mirror of
https://github.com/corda/corda.git
synced 2025-02-23 18:40:33 +00:00
CORDA-786 - Use reflection to infer proxy and proxied types in CorDapp custom serializers
This removes any need for the user implement and override types from the super class * CORDA-786 - Docs update * CORDA-786 - Remove unneeded second annotation on the proxy objects * Fix merge conflicts
This commit is contained in:
parent
d25b7f560c
commit
fcec60e232
@ -38,7 +38,6 @@ interface Cordapp {
|
||||
val schedulableFlows: List<Class<out FlowLogic<*>>>
|
||||
val services: List<Class<out SerializeAsToken>>
|
||||
val serializationWhitelists: List<SerializationWhitelist>
|
||||
val serializationCustomSerializerProxies: List<Class<*>>
|
||||
val serializationCustomSerializers: List<Class<out SerializationCustomSerializer<*, *>>>
|
||||
val customSchemas: Set<MappedSchema>
|
||||
val jarPath: URL
|
||||
|
@ -17,7 +17,6 @@ data class CordappImpl(
|
||||
override val schedulableFlows: List<Class<out FlowLogic<*>>>,
|
||||
override val services: List<Class<out SerializeAsToken>>,
|
||||
override val serializationWhitelists: List<SerializationWhitelist>,
|
||||
override val serializationCustomSerializerProxies: List<Class<*>>,
|
||||
override val serializationCustomSerializers: List<Class<out SerializationCustomSerializer<*, *>>>,
|
||||
override val customSchemas: Set<MappedSchema>,
|
||||
override val jarPath: URL) : Cordapp {
|
||||
|
@ -8,11 +8,3 @@ package net.corda.core.serialization
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
annotation class CordaCustomSerializer
|
||||
|
||||
/**
|
||||
* This annotation marks a class as being a proxy for some third party class and used by some
|
||||
* implementation of [SerializationCustomSerializer]. Such classes must be annotated to allow
|
||||
* them to be discovered in a CorDapp jar and loaded
|
||||
*/
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
annotation class CordaCustomSerializerProxy
|
||||
|
||||
|
@ -17,9 +17,6 @@ import java.lang.reflect.Type
|
||||
*
|
||||
* Failing to apply either annotation will result in the class not being loaded by Corda and thus serialization
|
||||
* failing
|
||||
*
|
||||
* @property type the type of the object that this class is proxying
|
||||
* @property ptype the type of the proxy object used as an intermediate representation of [type]
|
||||
*/
|
||||
interface SerializationCustomSerializer<OBJ, PROXY> {
|
||||
/**
|
||||
@ -33,14 +30,4 @@ interface SerializationCustomSerializer<OBJ, PROXY> {
|
||||
* unserializable type
|
||||
*/
|
||||
fun fromProxy(proxy: PROXY) : OBJ
|
||||
|
||||
/**
|
||||
* Should be set to the type of the object being proxied
|
||||
*/
|
||||
val type: Type
|
||||
|
||||
/**
|
||||
* Should be set to the proxy objects type
|
||||
*/
|
||||
val ptype: Type
|
||||
}
|
@ -1,16 +1,18 @@
|
||||
Pluggable Serializers for CorDapps
|
||||
==================================
|
||||
To be serializable by Corda Java classes must be compiled with the -parameter switch to enable matching of it's properties
|
||||
to constructor parameters. This is important because Corda's internal AMQP serialization scheme will only constuct
|
||||
|
||||
.. contents::
|
||||
|
||||
To be serializable by Corda Java classes must be compiled with the -parameters switch to enable matching of it's properties
|
||||
to constructor parameters. This is important because Corda's internal AMQP serialization scheme will only construct
|
||||
objects using their constructors. However, when recompilation isn't possible, or classes are built in such a way that
|
||||
they cannot be easily modified for simple serailization, CorDapps can provide custom proxy serializers that Corda
|
||||
can use to move from types it cannot serializer to an interim representation that it can with the transformation to and
|
||||
can use to move from types it cannot serialize to an interim representation that it can with the transformation to and
|
||||
from this proxy object being handled by the supplied serializer.
|
||||
|
||||
Serializer Location
|
||||
-------------------
|
||||
Custom serializers should be placed in the plugins directory of a CorDapp or a sub directory thereof. These
|
||||
classes will be scanned and loaded by the CorDapp loading process.
|
||||
Custom serializer classes should follow the rules for including classes found in :doc:`cordapp-build-systems`
|
||||
|
||||
Writing a Custom Serializer
|
||||
---------------------------
|
||||
@ -26,7 +28,9 @@ Example
|
||||
-------
|
||||
Consider this example class
|
||||
|
||||
|
||||
.. sourcecode:: java
|
||||
|
||||
public final class Example {
|
||||
private final Int a
|
||||
private final Int b
|
||||
@ -42,33 +46,31 @@ Consider this example class
|
||||
public int getB() { return b; }
|
||||
}
|
||||
|
||||
Without a custom serializer we cannot serialise this class as there is no public constructor that facilitates the
|
||||
initialisation of al of its's properties.
|
||||
Without a custom serializer we cannot serialize this class as there is no public constructor that facilitates the
|
||||
initialisation of all of its's properties.
|
||||
|
||||
To be serializable by Corda this would require a custom serializer as follows
|
||||
|
||||
.. sourcecode:: kotlin
|
||||
|
||||
@CordaCustomSerializer
|
||||
class ExampleSerializer : SerializationCustomSerializer {
|
||||
class ExampleSerializer : SerializationCustomSerializer<Example, ExampleSerializer.Proxy> {
|
||||
@CordaCustomSerializerProxy
|
||||
data class Proxy(val a: Int, val b: Int)
|
||||
|
||||
override fun toProxy(obj: Any): Any = Proxy((obj as Example).a, obj.b)
|
||||
override fun toProxy(obj: Example) = Proxy(obj.a, obj.b)
|
||||
|
||||
override fun fromProxy(proxy: Any): Any {
|
||||
override fun fromProxy(proxy: Proxy) : Example {
|
||||
val constructorArg = IntArray(2);
|
||||
constructorArg[0] = (proxy as Proxy).a
|
||||
constructorArg[0] = proxy.a
|
||||
constructorArg[1] = proxy.b
|
||||
return Example.create(constructorArg)
|
||||
}
|
||||
|
||||
override val type: Type get() = Example::class.java
|
||||
override val ptype: Type get() = Proxy::class.java
|
||||
}
|
||||
|
||||
Whitelisting
|
||||
------------
|
||||
By writing a custom serializer for a class it has the effect of adding that class to the whitelist, meaning such
|
||||
classes don't need explicitly adding to the CorDapp's whitelist
|
||||
classes don't need explicitly adding to the CorDapp's whitelist.
|
||||
|
||||
|
||||
|
@ -5,24 +5,70 @@ import net.corda.core.serialization.SerializationCustomSerializer
|
||||
import net.corda.nodeapi.internal.serialization.amqp.SerializerFactory.Companion.nameForType
|
||||
import org.apache.qpid.proton.amqp.Symbol
|
||||
import org.apache.qpid.proton.codec.Data
|
||||
import java.io.NotSerializableException
|
||||
import java.lang.reflect.Type
|
||||
import kotlin.reflect.jvm.javaType
|
||||
import kotlin.reflect.jvm.jvmErasure
|
||||
|
||||
/**
|
||||
* Index into the types list of the parent type of the serializer object, should be the
|
||||
* type that this object proxies for
|
||||
*/
|
||||
const val CORDAPP_TYPE = 0
|
||||
|
||||
/**
|
||||
* Index into the types list of the parent type of the serializer object, should be the
|
||||
* type of the proxy object that we're using to represent the object we're proxying for
|
||||
*/
|
||||
const val PROXY_TYPE = 1
|
||||
|
||||
/**
|
||||
* Wrapper class for user provided serializers
|
||||
*
|
||||
* Through the CorDapp JAR scanner we will have a list of custom serializer types that implement
|
||||
* the toProxy and fromProxy methods. This class takes an instance of one of those objects and
|
||||
* embeds it within a serialization context associated with a serializer factory by creating
|
||||
* and instance of this class and registering that with a [SerializerFactory]
|
||||
*
|
||||
* Proxy serializers should transform an unserializable class into a representation that we can serialize
|
||||
*
|
||||
* @property serializer in instance of a user written serialization proxy, normally scanned and loaded
|
||||
* automatically
|
||||
* @property type the Java [Type] of the class which this serializes, inferred via reflection of the
|
||||
* [serializer]'s super type
|
||||
* @property proxyType the Java [Type] of the class into which instances of [type] are proxied for use byt
|
||||
* the underlying serialisation engine
|
||||
*
|
||||
* @param factory a [SerializerFactory] belonging to the context this serializer is being instantiated
|
||||
* for
|
||||
*/
|
||||
class CorDappCustomSerializer(
|
||||
private val serialiser: SerializationCustomSerializer<*, *>,
|
||||
factory: SerializerFactory)
|
||||
: AMQPSerializer<Any>, SerializerFor {
|
||||
private val serializer: SerializationCustomSerializer<*, *>,
|
||||
factory: SerializerFactory) : AMQPSerializer<Any>, SerializerFor {
|
||||
override val revealSubclassesInSchema: Boolean get() = false
|
||||
override val type: Type get() = serialiser.type
|
||||
private val types = serializer::class.supertypes.filter { it.jvmErasure == SerializationCustomSerializer::class }
|
||||
.flatMap { it.arguments }
|
||||
.map { it.type!!.javaType }
|
||||
|
||||
init {
|
||||
if (types.size != 2) {
|
||||
throw NotSerializableException("Unable to determine serializer parent types")
|
||||
}
|
||||
}
|
||||
|
||||
override val type = types[CORDAPP_TYPE]
|
||||
val proxyType = types[PROXY_TYPE]
|
||||
|
||||
override val typeDescriptor = Symbol.valueOf("$DESCRIPTOR_DOMAIN:${nameForType(type)}")
|
||||
val descriptor: Descriptor = Descriptor(typeDescriptor)
|
||||
|
||||
private val proxySerializer: ObjectSerializer by lazy { ObjectSerializer(serialiser.ptype, factory) }
|
||||
private val proxySerializer: ObjectSerializer by lazy { ObjectSerializer(proxyType, factory) }
|
||||
|
||||
override fun writeClassInfo(output: SerializationOutput) {}
|
||||
|
||||
override fun writeObject(obj: Any, data: Data, type: Type, output: SerializationOutput) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val proxy = (serialiser as SerializationCustomSerializer<Any?,Any?>).toProxy(obj)
|
||||
val proxy = uncheckedCast<SerializationCustomSerializer<*, *>,
|
||||
SerializationCustomSerializer<Any?,Any?>> (serializer).toProxy(obj)
|
||||
|
||||
data.withDescribed(descriptor) {
|
||||
data.withList {
|
||||
@ -33,11 +79,10 @@ class CorDappCustomSerializer(
|
||||
}
|
||||
}
|
||||
|
||||
override fun readObject(obj: Any, schema: Schema, input: DeserializationInput) =
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
(serialiser as SerializationCustomSerializer<Any?,Any?>).fromProxy(
|
||||
uncheckedCast(proxySerializer.readObject(obj, schema, input)))!!
|
||||
override fun readObject(obj: Any, schemas: SerializationSchemas, input: DeserializationInput) =
|
||||
uncheckedCast<SerializationCustomSerializer<*, *>, SerializationCustomSerializer<Any?,Any?>> (
|
||||
serializer).fromProxy(uncheckedCast(proxySerializer.readObject(obj, schemas, input)))!!
|
||||
|
||||
override fun isSerializerFor(clazz: Class<*>): Boolean = clazz == type
|
||||
override fun isSerializerFor(clazz: Class<*>) = clazz == type
|
||||
}
|
||||
|
||||
|
@ -204,8 +204,8 @@ open class SerializerFactory(val whitelist: ClassWhitelist, cl: ClassLoader) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterate over an AMQP schema, for each type ascertain weather it's on ClassPath of [classloader] amd
|
||||
* if not use the [ClassCarpenter] to generate a class to use in it's place
|
||||
* Iterate over an AMQP schema, for each type ascertain whether it's on ClassPath of [classloader] and,
|
||||
* if not, use the [ClassCarpenter] to generate a class to use in it's place.
|
||||
*/
|
||||
private fun processSchema(schemaAndDescriptor: FactorySchemaAndDescriptor, sentinel: Boolean = false) {
|
||||
val metaSchema = CarpenterMetaSchema.newInstance()
|
||||
|
@ -2,27 +2,21 @@ package net.corda.nodeapi.internal.serialization.amqp
|
||||
|
||||
import org.junit.Test
|
||||
import net.corda.core.serialization.CordaCustomSerializer
|
||||
import net.corda.core.serialization.CordaCustomSerializerProxy
|
||||
import net.corda.core.serialization.ClassWhitelist
|
||||
import net.corda.core.serialization.SerializationCustomSerializer
|
||||
import org.assertj.core.api.Assertions
|
||||
import java.io.NotSerializableException
|
||||
import java.lang.reflect.Type
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class CorDappSerializerTests {
|
||||
data class NeedsProxy (val a: String)
|
||||
|
||||
@CordaCustomSerializer
|
||||
class NeedsProxyProxySerializer : SerializationCustomSerializer {
|
||||
@CordaCustomSerializerProxy
|
||||
class NeedsProxyProxySerializer : SerializationCustomSerializer<NeedsProxy, NeedsProxyProxySerializer.Proxy> {
|
||||
data class Proxy(val proxy_a_: String)
|
||||
|
||||
override val type: Type get() = NeedsProxy::class.java
|
||||
override val ptype: Type get() = Proxy::class.java
|
||||
|
||||
override fun fromProxy(proxy: Any) : Any = NeedsProxy((proxy as Proxy).proxy_a_)
|
||||
override fun toProxy(obj: Any) : Any = Proxy((obj as NeedsProxy).a)
|
||||
override fun fromProxy(proxy: Proxy) = NeedsProxy(proxy.proxy_a_)
|
||||
override fun toProxy(obj: NeedsProxy) = Proxy(obj.a)
|
||||
}
|
||||
|
||||
// Standard proxy serializer used internally, here for comparison purposes
|
||||
@ -34,12 +28,10 @@ class CorDappSerializerTests {
|
||||
data class Proxy(val proxy_a_: String)
|
||||
|
||||
override fun toProxy(obj: NeedsProxy): Proxy {
|
||||
println ("InternalProxySerializer - toProxy")
|
||||
return Proxy(obj.a)
|
||||
}
|
||||
|
||||
override fun fromProxy(proxy: Proxy): NeedsProxy {
|
||||
println ("InternalProxySerializer - fromProxy")
|
||||
return NeedsProxy(proxy.proxy_a_)
|
||||
}
|
||||
}
|
||||
|
@ -181,7 +181,6 @@ class CordappLoader private constructor(private val cordappJarPaths: List<Restri
|
||||
schedulableFlows = listOf(),
|
||||
services = listOf(),
|
||||
serializationWhitelists = listOf(),
|
||||
serializationCustomSerializerProxies = listOf(),
|
||||
serializationCustomSerializers = listOf(),
|
||||
customSchemas = setOf(),
|
||||
jarPath = ContractUpgradeFlow.javaClass.protectionDomain.codeSource.location // Core JAR location
|
||||
@ -198,7 +197,6 @@ class CordappLoader private constructor(private val cordappJarPaths: List<Restri
|
||||
findSchedulableFlows(scanResult),
|
||||
findServices(scanResult),
|
||||
findPlugins(it),
|
||||
findSerialiserProxies(scanResult),
|
||||
findSerialzers(scanResult),
|
||||
findCustomSchemas(scanResult),
|
||||
it.url)
|
||||
@ -250,10 +248,6 @@ class CordappLoader private constructor(private val cordappJarPaths: List<Restri
|
||||
} + DefaultWhitelist // Always add the DefaultWhitelist to the whitelist for an app.
|
||||
}
|
||||
|
||||
private fun findSerialiserProxies(scanResult: RestrictedScanResult) : List<Class<*>> {
|
||||
return scanResult.getClassesWithAnnotation(Class::class, CordaCustomSerializerProxy::class)
|
||||
}
|
||||
|
||||
private fun findSerialzers(scanResult: RestrictedScanResult) : List<Class<out SerializationCustomSerializer<*, *>>> {
|
||||
return scanResult.getClassesWithAnnotation(SerializationCustomSerializer::class, CordaCustomSerializer::class)
|
||||
}
|
||||
|
@ -3,20 +3,14 @@ package net.corda.vega.plugin.customserializers
|
||||
import com.opengamma.strata.market.param.CurrencyParameterSensitivities
|
||||
import com.opengamma.strata.market.param.CurrencyParameterSensitivity
|
||||
import net.corda.core.serialization.CordaCustomSerializer
|
||||
import net.corda.core.serialization.CordaCustomSerializerProxy
|
||||
import net.corda.core.serialization.SerializationCustomSerializer
|
||||
import java.lang.reflect.Type
|
||||
|
||||
@CordaCustomSerializer
|
||||
@Suppress("UNUSED")
|
||||
class CurrencyParameterSensitivitiesSerializer :
|
||||
SerializationCustomSerializer<CurrencyParameterSensitivities, CurrencyParameterSensitivitiesSerializer.Proxy> {
|
||||
@CordaCustomSerializerProxy
|
||||
data class Proxy(val sensitivities: List<CurrencyParameterSensitivity>)
|
||||
|
||||
override val type: Type get() = CurrencyParameterSensitivities::class.java
|
||||
override val ptype: Type get() = Proxy::class.java
|
||||
|
||||
override fun fromProxy(proxy: Proxy) = CurrencyParameterSensitivities.of(proxy.sensitivities)
|
||||
override fun toProxy(obj: CurrencyParameterSensitivities) = Proxy(obj.sensitivities)
|
||||
}
|
@ -6,22 +6,16 @@ import com.opengamma.strata.data.MarketDataName
|
||||
import com.opengamma.strata.collect.array.DoubleArray
|
||||
import com.opengamma.strata.basics.currency.Currency
|
||||
import net.corda.core.serialization.CordaCustomSerializer
|
||||
import net.corda.core.serialization.CordaCustomSerializerProxy
|
||||
import net.corda.core.serialization.SerializationCustomSerializer
|
||||
import java.lang.reflect.Type
|
||||
|
||||
@CordaCustomSerializer
|
||||
@Suppress("UNUSED")
|
||||
class CurrencyParameterSensitivitySerializer :
|
||||
SerializationCustomSerializer<CurrencyParameterSensitivity, CurrencyParameterSensitivitySerializer.Proxy> {
|
||||
@CordaCustomSerializerProxy
|
||||
data class Proxy(val currency: Currency, val marketDataName: MarketDataName<*>,
|
||||
val parameterMetadata: List<ParameterMetadata>,
|
||||
val sensitivity: DoubleArray)
|
||||
|
||||
override val type: Type get() = CurrencyParameterSensitivity::class.java
|
||||
override val ptype: Type get() = Proxy::class.java
|
||||
|
||||
override fun fromProxy(proxy: CurrencyParameterSensitivitySerializer.Proxy) =
|
||||
CurrencyParameterSensitivity.of(
|
||||
proxy.marketDataName,
|
||||
|
@ -2,19 +2,13 @@ package net.corda.vega.plugin.customserializers
|
||||
|
||||
import com.opengamma.strata.basics.currency.Currency
|
||||
import net.corda.core.serialization.CordaCustomSerializer
|
||||
import net.corda.core.serialization.CordaCustomSerializerProxy
|
||||
import net.corda.core.serialization.SerializationCustomSerializer
|
||||
import java.lang.reflect.Type
|
||||
|
||||
@CordaCustomSerializer
|
||||
@Suppress("UNUSED")
|
||||
class CurrencySerializer : SerializationCustomSerializer<Currency, CurrencySerializer.Proxy> {
|
||||
@CordaCustomSerializerProxy
|
||||
data class Proxy(val currency: String)
|
||||
|
||||
override val type: Type get() = Currency::class.java
|
||||
override val ptype: Type get() = Proxy::class.java
|
||||
|
||||
override fun fromProxy(proxy: Proxy) = Currency.parse(proxy.currency)
|
||||
override fun toProxy(obj: Currency) = Proxy(obj.toString())
|
||||
}
|
||||
|
@ -1,20 +1,14 @@
|
||||
package net.corda.vega.plugin.customserializers
|
||||
|
||||
import net.corda.core.serialization.CordaCustomSerializer
|
||||
import net.corda.core.serialization.CordaCustomSerializerProxy
|
||||
import net.corda.core.serialization.SerializationCustomSerializer
|
||||
import com.opengamma.strata.collect.array.DoubleArray
|
||||
import java.lang.reflect.Type
|
||||
|
||||
@CordaCustomSerializer
|
||||
@Suppress("UNUSED")
|
||||
class DoubleArraySerializer : SerializationCustomSerializer<DoubleArray, DoubleArraySerializer.Proxy> {
|
||||
@CordaCustomSerializerProxy
|
||||
data class Proxy(val amount: kotlin.DoubleArray)
|
||||
|
||||
override val type: Type get() = DoubleArray::class.java
|
||||
override val ptype: Type get() = Proxy::class.java
|
||||
|
||||
override fun fromProxy(proxy: Proxy) = DoubleArray.copyOf(proxy.amount)
|
||||
override fun toProxy(obj: DoubleArray) = Proxy(obj.toArray())
|
||||
}
|
||||
|
@ -3,20 +3,15 @@ package net.corda.vega.plugin.customserializers
|
||||
import com.opengamma.strata.basics.currency.MultiCurrencyAmount
|
||||
import com.opengamma.strata.basics.currency.Currency
|
||||
import net.corda.core.serialization.*
|
||||
import java.lang.reflect.Type
|
||||
|
||||
@CordaCustomSerializer
|
||||
@Suppress("UNUSED")
|
||||
class MultiCurrencyAmountSerializer :
|
||||
SerializationCustomSerializer<MultiCurrencyAmount, MultiCurrencyAmountSerializer.Proxy> {
|
||||
@CordaCustomSerializerProxy
|
||||
data class Proxy(val curencies : Map<Currency, Double>)
|
||||
|
||||
override fun toProxy(obj: MultiCurrencyAmount) = Proxy(obj.toMap())
|
||||
override fun fromProxy(proxy: Proxy) = MultiCurrencyAmount.of(proxy.curencies)
|
||||
|
||||
override val type: Type get() = MultiCurrencyAmount::class.java
|
||||
override val ptype: Type get() = Proxy::class.java
|
||||
}
|
||||
|
||||
|
||||
|
@ -3,20 +3,14 @@ package net.corda.vega.plugin.customserializers
|
||||
import com.opengamma.strata.basics.date.Tenor
|
||||
import com.opengamma.strata.market.param.TenorDateParameterMetadata
|
||||
import net.corda.core.serialization.*
|
||||
import java.lang.reflect.Type
|
||||
import java.time.LocalDate
|
||||
|
||||
@CordaCustomSerializer
|
||||
@Suppress("UNUSED")
|
||||
class TenorDateParameterMetadataSerializer :
|
||||
SerializationCustomSerializer<TenorDateParameterMetadata, TenorDateParameterMetadataSerializer.Proxy> {
|
||||
@CordaCustomSerializerProxy
|
||||
data class Proxy(val tenor: Tenor, val date: LocalDate, val identifier: Tenor, val label: String)
|
||||
|
||||
override val type: Type get() = TenorDateParameterMetadata::class.java
|
||||
override val ptype: Type get() = Proxy::class.java
|
||||
|
||||
|
||||
override fun toProxy(obj: TenorDateParameterMetadata) = Proxy(obj.tenor, obj.date, obj.identifier, obj.label)
|
||||
override fun fromProxy(proxy: Proxy) = TenorDateParameterMetadata.of(proxy.date, proxy.tenor, proxy.label)
|
||||
}
|
||||
|
@ -2,18 +2,13 @@ package net.corda.vega.plugin.customserializers
|
||||
|
||||
import com.opengamma.strata.basics.date.Tenor
|
||||
import net.corda.core.serialization.*
|
||||
import java.lang.reflect.Type
|
||||
import java.time.Period
|
||||
|
||||
@CordaCustomSerializer
|
||||
@Suppress("UNUSED")
|
||||
class TenorSerializer : SerializationCustomSerializer<Tenor, TenorSerializer.Proxy> {
|
||||
@CordaCustomSerializerProxy
|
||||
data class Proxy(val years: Int, val months: Int, val days: Int, val name: String)
|
||||
|
||||
override val type: Type get() = Tenor::class.java
|
||||
override val ptype: Type get() = Proxy::class.java
|
||||
|
||||
override fun toProxy(obj: Tenor) = Proxy(obj.period.years, obj.period.months, obj.period.days, obj.toString())
|
||||
override fun fromProxy(proxy: Proxy) = Tenor.of (Period.of(proxy.years, proxy.months, proxy.days))
|
||||
}
|
||||
|
@ -104,6 +104,7 @@ private fun createTestSerializationEnv(label: String) = object : SerializationEn
|
||||
},
|
||||
AMQP_P2P_CONTEXT,
|
||||
KRYO_RPC_SERVER_CONTEXT,
|
||||
KRYO_RPC_CLIENT_CONTEXT,
|
||||
AMQP_STORAGE_CONTEXT,
|
||||
KRYO_CHECKPOINT_CONTEXT) {
|
||||
override fun toString() = "testSerializationEnv($label)"
|
||||
|
@ -22,7 +22,6 @@ class MockCordappProvider(cordappLoader: CordappLoader, attachmentStorage: Attac
|
||||
schedulableFlows = emptyList(),
|
||||
services = emptyList(),
|
||||
serializationWhitelists = emptyList(),
|
||||
serializationCustomSerializerProxies = emptyList(),
|
||||
serializationCustomSerializers = emptyList(),
|
||||
customSchemas = emptySet(),
|
||||
jarPath = Paths.get(".").toUri().toURL())
|
||||
|
Loading…
x
Reference in New Issue
Block a user