From f3b372d31d862f76ab7c1696b99927641ed6218e Mon Sep 17 00:00:00 2001 From: Dominic Fox <40790090+distributedleetravis@users.noreply.github.com> Date: Wed, 7 Nov 2018 13:48:45 +0000 Subject: [PATCH] CORDA-2099 make serializer factory interface (#4137) * Separate SerializerFactory construction from concrete implementation * Fewer build methods * Method naming that doesn't fatally confuse determinisation * Extract SerializerFactory interface * Reset to master's version of compiler.xml * Un-ignore flickering test * Remove unnecessary build method * Whitespace * Unused import * Change build method * Formatting fixes * Fix test --- .../client/jackson/internal/CordaModule.kt | 7 +- .../amqp/AMQPClientSerializationScheme.kt | 7 +- constants.properties | 2 +- ...VerificationExceptionSerialisationTests.kt | 4 +- .../amqp/AMQPServerSerializationScheme.kt | 3 +- .../RpcServerObservableSerializerTests.kt | 6 +- .../testutils/AMQPTestSerialiationScheme.kt | 5 +- serialization-deterministic/build.gradle | 1 + .../internal/amqp/AMQPSerializerFactories.kt | 12 +- .../internal/model/DefaultCacheProvider.kt | 9 + .../internal/amqp/AMQPSerializerFactories.kt | 5 +- .../internal/amqp/SerializerFactory.kt | 232 ++++++------ .../internal/amqp/SerializerFactoryBuilder.kt | 53 +++ .../internal/model/DefaultCacheProvider.kt | 11 + .../amqp/JavaPrivatePropertyTests.java | 9 +- .../internal/ListsSerializationTest.kt | 4 +- .../internal/amqp/CorDappSerializerTests.kt | 32 +- .../amqp/DeserializeNeedingCarpentryTests.kt | 4 +- .../serialization/internal/amqp/EnumTests.kt | 29 +- .../internal/amqp/FingerPrinterTesting.kt | 9 +- .../internal/amqp/GenericsTests.kt | 57 ++- .../amqp/OptionalSerializationTests.kt | 5 +- .../internal/amqp/PrivatePropertyTests.kt | 19 +- .../internal/amqp/SerializationOutputTests.kt | 334 +++++++++++++----- .../amqp/SerializationPropertyOrdering.kt | 3 +- .../internal/amqp/SerializationSchemaTests.kt | 3 +- ...ticInitialisationOfSerializedObjectTest.kt | 15 +- .../internal/amqp/testutils/AMQPTestUtils.kt | 15 +- .../carpenter/CarpenterExceptionTests.kt | 7 +- .../carpenter/ClassCarpenterTestUtils.kt | 6 +- 30 files changed, 599 insertions(+), 309 deletions(-) create mode 100644 serialization-deterministic/src/main/kotlin/net/corda/serialization/internal/model/DefaultCacheProvider.kt create mode 100644 serialization/src/main/kotlin/net/corda/serialization/internal/amqp/SerializerFactoryBuilder.kt create mode 100644 serialization/src/main/kotlin/net/corda/serialization/internal/model/DefaultCacheProvider.kt diff --git a/client/jackson/src/main/kotlin/net/corda/client/jackson/internal/CordaModule.kt b/client/jackson/src/main/kotlin/net/corda/client/jackson/internal/CordaModule.kt index e56711a50d..6eef15668a 100644 --- a/client/jackson/src/main/kotlin/net/corda/client/jackson/internal/CordaModule.kt +++ b/client/jackson/src/main/kotlin/net/corda/client/jackson/internal/CordaModule.kt @@ -38,10 +38,7 @@ import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.parseAsHex import net.corda.core.utilities.toHexString import net.corda.serialization.internal.AllWhitelist -import net.corda.serialization.internal.amqp.SerializerFactory -import net.corda.serialization.internal.amqp.constructorForDeserialization -import net.corda.serialization.internal.amqp.hasCordaSerializable -import net.corda.serialization.internal.amqp.propertiesForSerialization +import net.corda.serialization.internal.amqp.* import java.math.BigDecimal import java.security.PublicKey import java.security.cert.CertPath @@ -88,7 +85,7 @@ class CordaModule : SimpleModule("corda-core") { */ private class CordaSerializableBeanSerializerModifier : BeanSerializerModifier() { // We need to pass in a SerializerFactory when scanning for properties, but don't actually do any serialisation so any will do. - private val serializerFactory = SerializerFactory(AllWhitelist, javaClass.classLoader) + private val serializerFactory = SerializerFactoryBuilder.build(AllWhitelist, javaClass.classLoader) override fun changeProperties(config: SerializationConfig, beanDesc: BeanDescription, diff --git a/client/rpc/src/main/kotlin/net/corda/client/rpc/internal/serialization/amqp/AMQPClientSerializationScheme.kt b/client/rpc/src/main/kotlin/net/corda/client/rpc/internal/serialization/amqp/AMQPClientSerializationScheme.kt index 3ef215f9e8..6e094e87ee 100644 --- a/client/rpc/src/main/kotlin/net/corda/client/rpc/internal/serialization/amqp/AMQPClientSerializationScheme.kt +++ b/client/rpc/src/main/kotlin/net/corda/client/rpc/internal/serialization/amqp/AMQPClientSerializationScheme.kt @@ -8,10 +8,7 @@ import net.corda.core.serialization.SerializationCustomSerializer import net.corda.core.serialization.internal.SerializationEnvironment import net.corda.core.serialization.internal.nodeSerializationEnv import net.corda.serialization.internal.* -import net.corda.serialization.internal.amqp.AbstractAMQPSerializationScheme -import net.corda.serialization.internal.amqp.AccessOrderLinkedHashMap -import net.corda.serialization.internal.amqp.SerializerFactory -import net.corda.serialization.internal.amqp.amqpMagic +import net.corda.serialization.internal.amqp.* import net.corda.serialization.internal.amqp.custom.RxNotificationSerializer /** @@ -52,7 +49,7 @@ class AMQPClientSerializationScheme( } override fun rpcClientSerializerFactory(context: SerializationContext): SerializerFactory { - return SerializerFactory(context.whitelist, context.deserializationClassLoader, context.lenientCarpenterEnabled).apply { + return SerializerFactoryBuilder.build(context.whitelist, context.deserializationClassLoader, context.lenientCarpenterEnabled).apply { register(RpcClientObservableDeSerializer) register(RpcClientCordaFutureSerializer(this)) register(RxNotificationSerializer(this)) diff --git a/constants.properties b/constants.properties index 9ed2417171..d0817917ec 100644 --- a/constants.properties +++ b/constants.properties @@ -1,4 +1,4 @@ -gradlePluginsVersion=4.0.33 +gradlePluginsVersion=4.0.34 kotlinVersion=1.2.71 # ***************************************************************# # When incrementing platformVersion make sure to update # diff --git a/core/src/test/kotlin/net/corda/core/contracts/TransactionVerificationExceptionSerialisationTests.kt b/core/src/test/kotlin/net/corda/core/contracts/TransactionVerificationExceptionSerialisationTests.kt index 59b2801bb1..6ee97c6031 100644 --- a/core/src/test/kotlin/net/corda/core/contracts/TransactionVerificationExceptionSerialisationTests.kt +++ b/core/src/test/kotlin/net/corda/core/contracts/TransactionVerificationExceptionSerialisationTests.kt @@ -6,7 +6,7 @@ import net.corda.serialization.internal.AMQP_RPC_CLIENT_CONTEXT import net.corda.serialization.internal.AllWhitelist import net.corda.serialization.internal.amqp.DeserializationInput import net.corda.serialization.internal.amqp.SerializationOutput -import net.corda.serialization.internal.amqp.SerializerFactory +import net.corda.serialization.internal.amqp.SerializerFactoryBuilder import net.corda.serialization.internal.amqp.custom.PublicKeySerializer import net.corda.testing.core.DUMMY_BANK_A_NAME import net.corda.testing.core.DUMMY_NOTARY_NAME @@ -15,7 +15,7 @@ import org.junit.Test import kotlin.test.assertEquals class TransactionVerificationExceptionSerialisationTests { - private fun defaultFactory() = SerializerFactory( + private fun defaultFactory() = SerializerFactoryBuilder.build( AllWhitelist, ClassLoader.getSystemClassLoader() ) diff --git a/node/src/main/kotlin/net/corda/node/serialization/amqp/AMQPServerSerializationScheme.kt b/node/src/main/kotlin/net/corda/node/serialization/amqp/AMQPServerSerializationScheme.kt index dfe6b6fafd..1cb164b0eb 100644 --- a/node/src/main/kotlin/net/corda/node/serialization/amqp/AMQPServerSerializationScheme.kt +++ b/node/src/main/kotlin/net/corda/node/serialization/amqp/AMQPServerSerializationScheme.kt @@ -8,6 +8,7 @@ import net.corda.serialization.internal.CordaSerializationMagic import net.corda.serialization.internal.amqp.AbstractAMQPSerializationScheme import net.corda.serialization.internal.amqp.AccessOrderLinkedHashMap import net.corda.serialization.internal.amqp.SerializerFactory +import net.corda.serialization.internal.amqp.SerializerFactoryBuilder import net.corda.serialization.internal.amqp.custom.RxNotificationSerializer /** @@ -28,7 +29,7 @@ class AMQPServerSerializationScheme( } override fun rpcServerSerializerFactory(context: SerializationContext): SerializerFactory { - return SerializerFactory(context.whitelist, context.deserializationClassLoader, context.lenientCarpenterEnabled).apply { + return SerializerFactoryBuilder.build(context.whitelist, context.deserializationClassLoader, context.lenientCarpenterEnabled).apply { register(RpcServerObservableSerializer()) register(RpcServerCordaFutureSerializer(this)) register(RxNotificationSerializer(this)) diff --git a/node/src/test/kotlin/net/corda/node/internal/serialization/RpcServerObservableSerializerTests.kt b/node/src/test/kotlin/net/corda/node/internal/serialization/RpcServerObservableSerializerTests.kt index 720d147eac..a12cf73042 100644 --- a/node/src/test/kotlin/net/corda/node/internal/serialization/RpcServerObservableSerializerTests.kt +++ b/node/src/test/kotlin/net/corda/node/internal/serialization/RpcServerObservableSerializerTests.kt @@ -10,7 +10,7 @@ import net.corda.node.serialization.amqp.RpcServerObservableSerializer import net.corda.node.services.messaging.ObservableSubscription import net.corda.serialization.internal.AllWhitelist import net.corda.serialization.internal.amqp.SerializationOutput -import net.corda.serialization.internal.amqp.SerializerFactory +import net.corda.serialization.internal.amqp.SerializerFactoryBuilder import org.apache.activemq.artemis.api.core.SimpleString import org.junit.Test import rx.Observable @@ -34,7 +34,7 @@ class RpcServerObservableSerializerTests { @Test fun canSerializerBeRegistered() { - val sf = SerializerFactory(AllWhitelist, javaClass.classLoader) + val sf = SerializerFactoryBuilder.build(AllWhitelist, javaClass.classLoader) try { sf.register(RpcServerObservableSerializer()) @@ -67,7 +67,7 @@ class RpcServerObservableSerializerTests { deduplicationIdentity = "thisIsATest", clientAddress = SimpleString(testClientAddress)) - val sf = SerializerFactory(AllWhitelist, javaClass.classLoader).apply { + val sf = SerializerFactoryBuilder.build(AllWhitelist, javaClass.classLoader).apply { register(RpcServerObservableSerializer()) } diff --git a/node/src/test/kotlin/net/corda/node/internal/serialization/testutils/AMQPTestSerialiationScheme.kt b/node/src/test/kotlin/net/corda/node/internal/serialization/testutils/AMQPTestSerialiationScheme.kt index d17755fa4c..7a803cb661 100644 --- a/node/src/test/kotlin/net/corda/node/internal/serialization/testutils/AMQPTestSerialiationScheme.kt +++ b/node/src/test/kotlin/net/corda/node/internal/serialization/testutils/AMQPTestSerialiationScheme.kt @@ -12,6 +12,7 @@ import net.corda.serialization.internal.amqp.AbstractAMQPSerializationScheme import net.corda.serialization.internal.amqp.SerializerFactory import net.corda.serialization.internal.AllWhitelist import net.corda.serialization.internal.amqp.AccessOrderLinkedHashMap +import net.corda.serialization.internal.amqp.SerializerFactoryBuilder import net.corda.client.rpc.internal.ObservableContext as ClientObservableContext /** @@ -28,13 +29,13 @@ class AMQPRoundTripRPCSerializationScheme( cordappCustomSerializers, serializerFactoriesForContexts ) { override fun rpcClientSerializerFactory(context: SerializationContext): SerializerFactory { - return SerializerFactory(AllWhitelist, javaClass.classLoader).apply { + return SerializerFactoryBuilder.build(AllWhitelist, javaClass.classLoader).apply { register(RpcClientObservableDeSerializer) } } override fun rpcServerSerializerFactory(context: SerializationContext): SerializerFactory { - return SerializerFactory(AllWhitelist, javaClass.classLoader).apply { + return SerializerFactoryBuilder.build(AllWhitelist, javaClass.classLoader).apply { register(RpcServerObservableSerializer()) } } diff --git a/serialization-deterministic/build.gradle b/serialization-deterministic/build.gradle index 74190fd20a..36242351b5 100644 --- a/serialization-deterministic/build.gradle +++ b/serialization-deterministic/build.gradle @@ -50,6 +50,7 @@ task patchSerialization(type: Zip, dependsOn: serializationJarTask) { exclude 'net/corda/serialization/internal/amqp/AMQPSerializerFactories*' exclude 'net/corda/serialization/internal/amqp/AMQPStreams*' exclude 'net/corda/serialization/internal/amqp/AMQPSerializationThreadContext*' + exclude 'net/corda/serialization/internal/model/DefaultCacheProvider*' } reproducibleFileOrder = true diff --git a/serialization-deterministic/src/main/kotlin/net/corda/serialization/internal/amqp/AMQPSerializerFactories.kt b/serialization-deterministic/src/main/kotlin/net/corda/serialization/internal/amqp/AMQPSerializerFactories.kt index e3f74f2db9..d0bb4b4798 100644 --- a/serialization-deterministic/src/main/kotlin/net/corda/serialization/internal/amqp/AMQPSerializerFactories.kt +++ b/serialization-deterministic/src/main/kotlin/net/corda/serialization/internal/amqp/AMQPSerializerFactories.kt @@ -15,15 +15,9 @@ fun createSerializerFactoryFactory(): SerializerFactoryFactory = DeterministicSe private class DeterministicSerializerFactoryFactory : SerializerFactoryFactory { override fun make(context: SerializationContext) = - SerializerFactory( - whitelist = context.whitelist, - classCarpenter = DummyClassCarpenter(context.whitelist, context.deserializationClassLoader), - serializersByType = mutableMapOf(), - serializersByDescriptor = mutableMapOf(), - customSerializers = ArrayList(), - customSerializersCache = mutableMapOf(), - transformsCache = mutableMapOf() - ) + SerializerFactoryBuilder.build( + whitelist = context.whitelist, + classCarpenter = DummyClassCarpenter(context.whitelist, context.deserializationClassLoader)) } private class DummyClassCarpenter( diff --git a/serialization-deterministic/src/main/kotlin/net/corda/serialization/internal/model/DefaultCacheProvider.kt b/serialization-deterministic/src/main/kotlin/net/corda/serialization/internal/model/DefaultCacheProvider.kt new file mode 100644 index 0000000000..022c045e87 --- /dev/null +++ b/serialization-deterministic/src/main/kotlin/net/corda/serialization/internal/model/DefaultCacheProvider.kt @@ -0,0 +1,9 @@ +package net.corda.serialization.internal.model + +/** + * We can't have [ConcurrentHashMap]s in the DJVM, so it must supply its own version of this object which returns + * plain old [MutableMap]s instead. + */ +object DefaultCacheProvider { + fun createCache(): MutableMap = mutableMapOf() +} \ No newline at end of file diff --git a/serialization/src/main/kotlin/net/corda/serialization/internal/amqp/AMQPSerializerFactories.kt b/serialization/src/main/kotlin/net/corda/serialization/internal/amqp/AMQPSerializerFactories.kt index aacde49dac..93e82dfe0a 100644 --- a/serialization/src/main/kotlin/net/corda/serialization/internal/amqp/AMQPSerializerFactories.kt +++ b/serialization/src/main/kotlin/net/corda/serialization/internal/amqp/AMQPSerializerFactories.kt @@ -3,11 +3,14 @@ package net.corda.serialization.internal.amqp import net.corda.core.serialization.SerializationContext +import net.corda.serialization.internal.carpenter.ClassCarpenterImpl fun createSerializerFactoryFactory(): SerializerFactoryFactory = SerializerFactoryFactoryImpl() open class SerializerFactoryFactoryImpl : SerializerFactoryFactory { override fun make(context: SerializationContext): SerializerFactory { - return SerializerFactory(context.whitelist, context.deserializationClassLoader, context.lenientCarpenterEnabled) + return SerializerFactoryBuilder.build(context.whitelist, + ClassCarpenterImpl(context.whitelist, context.deserializationClassLoader, context.lenientCarpenterEnabled) + ) } } diff --git a/serialization/src/main/kotlin/net/corda/serialization/internal/amqp/SerializerFactory.kt b/serialization/src/main/kotlin/net/corda/serialization/internal/amqp/SerializerFactory.kt index c8d4b14891..1cfa23f1eb 100644 --- a/serialization/src/main/kotlin/net/corda/serialization/internal/amqp/SerializerFactory.kt +++ b/serialization/src/main/kotlin/net/corda/serialization/internal/amqp/SerializerFactory.kt @@ -1,7 +1,6 @@ package net.corda.serialization.internal.amqp import com.google.common.primitives.Primitives -import net.corda.core.DeleteForDJVM import net.corda.core.KeepForDJVM import net.corda.core.StubOutForDJVM import net.corda.core.internal.kotlinObjectInstance @@ -12,12 +11,11 @@ import net.corda.core.utilities.debug import net.corda.core.utilities.loggerFor import net.corda.core.utilities.trace import net.corda.serialization.internal.carpenter.* +import net.corda.serialization.internal.model.DefaultCacheProvider import org.apache.qpid.proton.amqp.* import java.io.NotSerializableException import java.lang.reflect.* import java.util.* -import java.util.concurrent.ConcurrentHashMap -import java.util.concurrent.CopyOnWriteArrayList import javax.annotation.concurrent.ThreadSafe @KeepForDJVM @@ -49,54 +47,122 @@ data class CustomSerializersCacheKey(val clazz: Class<*>, val declaredType: Type // TODO: need to support super classes as well as interfaces with our current code base... what's involved? If we continue to ban, what is the impact? @KeepForDJVM @ThreadSafe -open class SerializerFactory( - val whitelist: ClassWhitelist, - val classCarpenter: ClassCarpenter, - private val evolutionSerializerProvider: EvolutionSerializerProvider = DefaultEvolutionSerializerProvider, - val fingerPrinterConstructor: (SerializerFactory) -> FingerPrinter = ::SerializerFingerPrinter, - private val serializersByType: MutableMap>, - val serializersByDescriptor: MutableMap>, - private val customSerializers: MutableList, - private val customSerializersCache: MutableMap?>, - val transformsCache: MutableMap>>, +interface SerializerFactory { + val whitelist: ClassWhitelist + val classCarpenter: ClassCarpenter + val fingerPrinterConstructor: (SerializerFactory) -> FingerPrinter + // Caches + val serializersByType: MutableMap> + val serializersByDescriptor: MutableMap> + val transformsCache: MutableMap>> + val fingerPrinter: FingerPrinter + val classloader: ClassLoader + /** + * Look up, and manufacture if necessary, a serializer for the given type. + * + * @param actualClass Will be null if there isn't an actual object instance available (e.g. for + * restricted type processing). + */ + @Throws(NotSerializableException::class) + fun get(actualClass: Class<*>?, declaredType: Type): AMQPSerializer + + /** + * Lookup and manufacture a serializer for the given AMQP type descriptor, assuming we also have the necessary types + * contained in the [Schema]. + */ + @Throws(NotSerializableException::class) + fun get(typeDescriptor: Any, schema: SerializationSchemas): AMQPSerializer + + /** + * Register a custom serializer for any type that cannot be serialized or deserialized by the default serializer + * that expects to find getters and a constructor with a parameter for each property. + */ + fun register(customSerializer: CustomSerializer) + + fun findCustomSerializer(clazz: Class<*>, declaredType: Type): AMQPSerializer? + fun registerExternal(customSerializer: CorDappCustomSerializer) + fun registerByDescriptor(name: Symbol, serializerCreator: () -> AMQPSerializer): AMQPSerializer + + object AnyType : WildcardType { + override fun getUpperBounds(): Array = arrayOf(Object::class.java) + + override fun getLowerBounds(): Array = emptyArray() + + override fun toString(): String = "?" + } + + companion object { + fun isPrimitive(type: Type): Boolean = primitiveTypeName(type) != null + + fun primitiveTypeName(type: Type): String? { + val clazz = type as? Class<*> ?: return null + return primitiveTypeNames[Primitives.unwrap(clazz)] + } + + fun primitiveType(type: String): Class<*>? { + return namesOfPrimitiveTypes[type] + } + + private val primitiveTypeNames: Map, String> = mapOf( + Character::class.java to "char", + Char::class.java to "char", + Boolean::class.java to "boolean", + Byte::class.java to "byte", + UnsignedByte::class.java to "ubyte", + Short::class.java to "short", + UnsignedShort::class.java to "ushort", + Int::class.java to "int", + UnsignedInteger::class.java to "uint", + Long::class.java to "long", + UnsignedLong::class.java to "ulong", + Float::class.java to "float", + Double::class.java to "double", + Decimal32::class.java to "decimal32", + Decimal64::class.java to "decimal62", + Decimal128::class.java to "decimal128", + Date::class.java to "timestamp", + UUID::class.java to "uuid", + ByteArray::class.java to "binary", + String::class.java to "string", + Symbol::class.java to "symbol") + + private val namesOfPrimitiveTypes: Map> = primitiveTypeNames.map { it.value to it.key }.toMap() + + fun nameForType(type: Type): String = when (type) { + is Class<*> -> { + primitiveTypeName(type) ?: if (type.isArray) { + "${nameForType(type.componentType)}${if (type.componentType.isPrimitive) "[p]" else "[]"}" + } else type.name + } + is ParameterizedType -> { + "${nameForType(type.rawType)}<${type.actualTypeArguments.joinToString { nameForType(it) }}>" + } + is GenericArrayType -> "${nameForType(type.genericComponentType)}[]" + is WildcardType -> "?" + is TypeVariable<*> -> "?" + else -> throw AMQPNotSerializableException(type, "Unable to render type $type to a string.") + } + } +} + +open class DefaultSerializerFactory( + override val whitelist: ClassWhitelist, + override val classCarpenter: ClassCarpenter, + private val evolutionSerializerProvider: EvolutionSerializerProvider, + override val fingerPrinterConstructor: (SerializerFactory) -> FingerPrinter, private val onlyCustomSerializers: Boolean = false -) { - @DeleteForDJVM - constructor(whitelist: ClassWhitelist, - classCarpenter: ClassCarpenter, - evolutionSerializerProvider: EvolutionSerializerProvider = DefaultEvolutionSerializerProvider, - fingerPrinterConstructor: (SerializerFactory) -> FingerPrinter = ::SerializerFingerPrinter, - onlyCustomSerializers: Boolean = false - ) : this( - whitelist, - classCarpenter, - evolutionSerializerProvider, - fingerPrinterConstructor, - ConcurrentHashMap(), - ConcurrentHashMap(), - CopyOnWriteArrayList(), - ConcurrentHashMap(), - ConcurrentHashMap(), - onlyCustomSerializers - ) +) : SerializerFactory { - @DeleteForDJVM - constructor(whitelist: ClassWhitelist, - carpenterClassLoader: ClassLoader, - lenientCarpenter: Boolean = false, - evolutionSerializerProvider: EvolutionSerializerProvider = DefaultEvolutionSerializerProvider, - fingerPrinterConstructor: (SerializerFactory) -> FingerPrinter = ::SerializerFingerPrinter, - onlyCustomSerializers: Boolean = false - ) : this( - whitelist, - ClassCarpenterImpl(whitelist, carpenterClassLoader, lenientCarpenter), - evolutionSerializerProvider, - fingerPrinterConstructor, - onlyCustomSerializers) + // Caches + override val serializersByType: MutableMap> = DefaultCacheProvider.createCache() + override val serializersByDescriptor: MutableMap> = DefaultCacheProvider.createCache() + private var customSerializers: List = emptyList() + private val customSerializersCache: MutableMap?> = DefaultCacheProvider.createCache() + override val transformsCache: MutableMap>> = DefaultCacheProvider.createCache() - val fingerPrinter by lazy { fingerPrinterConstructor(this) } + override val fingerPrinter by lazy { fingerPrinterConstructor(this) } - val classloader: ClassLoader get() = classCarpenter.classloader + override val classloader: ClassLoader get() = classCarpenter.classloader // Used to short circuit any computation for a given input, for performance. private data class MemoType(val actualClass: Class<*>?, val declaredType: Type) : Type @@ -108,7 +174,7 @@ open class SerializerFactory( * restricted type processing). */ @Throws(NotSerializableException::class) - fun get(actualClass: Class<*>?, declaredType: Type): AMQPSerializer { + override fun get(actualClass: Class<*>?, declaredType: Type): AMQPSerializer { // can be useful to enable but will be *extremely* chatty if you do logger.trace { "Get Serializer for $actualClass ${declaredType.typeName}" } @@ -169,7 +235,7 @@ open class SerializerFactory( * contained in the [Schema]. */ @Throws(NotSerializableException::class) - fun get(typeDescriptor: Any, schema: SerializationSchemas): AMQPSerializer { + override fun get(typeDescriptor: Any, schema: SerializationSchemas): AMQPSerializer { return serializersByDescriptor[typeDescriptor] ?: { logger.trace("get Serializer descriptor=${typeDescriptor}") processSchema(FactorySchemaAndDescriptor(schema, typeDescriptor)) @@ -182,7 +248,7 @@ open class SerializerFactory( * Register a custom serializer for any type that cannot be serialized or deserialized by the default serializer * that expects to find getters and a constructor with a parameter for each property. */ - open fun register(customSerializer: CustomSerializer) { + override fun register(customSerializer: CustomSerializer) { logger.trace("action=\"Registering custom serializer\", class=\"${customSerializer.type}\"") if (!serializersByDescriptor.containsKey(customSerializer.typeDescriptor)) { customSerializers += customSerializer @@ -193,7 +259,7 @@ open class SerializerFactory( } } - fun registerExternal(customSerializer: CorDappCustomSerializer) { + override fun registerExternal(customSerializer: CorDappCustomSerializer) { logger.trace("action=\"Registering external serializer\", class=\"${customSerializer.type}\"") if (!serializersByDescriptor.containsKey(customSerializer.typeDescriptor)) { customSerializers += customSerializer @@ -319,7 +385,7 @@ open class SerializerFactory( throw AMQPNotSerializableException( type, "Serializer does not support synthetic classes") - } else if (isPrimitive(clazz)) { + } else if (SerializerFactory.isPrimitive(clazz)) { AMQPPrimitiveSerializer(clazz) } else { findCustomSerializer(clazz, declaredType) ?: run { @@ -344,7 +410,7 @@ open class SerializerFactory( } } - internal fun findCustomSerializer(clazz: Class<*>, declaredType: Type): AMQPSerializer? { + override fun findCustomSerializer(clazz: Class<*>, declaredType: Type): AMQPSerializer? { return customSerializersCache.computeIfAbsent(CustomSerializersCacheKey(clazz, declaredType), ::doFindCustomSerializer) } @@ -383,69 +449,11 @@ open class SerializerFactory( return MapSerializer(declaredType, this) } - fun registerByDescriptor(name: Symbol, serializerCreator: () -> AMQPSerializer): AMQPSerializer = + override fun registerByDescriptor(name: Symbol, serializerCreator: () -> AMQPSerializer): AMQPSerializer = serializersByDescriptor.computeIfAbsent(name) { _ -> serializerCreator() } companion object { private val logger = contextLogger() - - fun isPrimitive(type: Type): Boolean = primitiveTypeName(type) != null - - fun primitiveTypeName(type: Type): String? { - val clazz = type as? Class<*> ?: return null - return primitiveTypeNames[Primitives.unwrap(clazz)] - } - - fun primitiveType(type: String): Class<*>? { - return namesOfPrimitiveTypes[type] - } - - private val primitiveTypeNames: Map, String> = mapOf( - Character::class.java to "char", - Char::class.java to "char", - Boolean::class.java to "boolean", - Byte::class.java to "byte", - UnsignedByte::class.java to "ubyte", - Short::class.java to "short", - UnsignedShort::class.java to "ushort", - Int::class.java to "int", - UnsignedInteger::class.java to "uint", - Long::class.java to "long", - UnsignedLong::class.java to "ulong", - Float::class.java to "float", - Double::class.java to "double", - Decimal32::class.java to "decimal32", - Decimal64::class.java to "decimal62", - Decimal128::class.java to "decimal128", - Date::class.java to "timestamp", - UUID::class.java to "uuid", - ByteArray::class.java to "binary", - String::class.java to "string", - Symbol::class.java to "symbol") - - private val namesOfPrimitiveTypes: Map> = primitiveTypeNames.map { it.value to it.key }.toMap() - - fun nameForType(type: Type): String = when (type) { - is Class<*> -> { - primitiveTypeName(type) ?: if (type.isArray) { - "${nameForType(type.componentType)}${if (type.componentType.isPrimitive) "[p]" else "[]"}" - } else type.name - } - is ParameterizedType -> { - "${nameForType(type.rawType)}<${type.actualTypeArguments.joinToString { nameForType(it) }}>" - } - is GenericArrayType -> "${nameForType(type.genericComponentType)}[]" - is WildcardType -> "?" - is TypeVariable<*> -> "?" - else -> throw AMQPNotSerializableException(type, "Unable to render type $type to a string.") - } } - object AnyType : WildcardType { - override fun getUpperBounds(): Array = arrayOf(Object::class.java) - - override fun getLowerBounds(): Array = emptyArray() - - override fun toString(): String = "?" - } } \ No newline at end of file diff --git a/serialization/src/main/kotlin/net/corda/serialization/internal/amqp/SerializerFactoryBuilder.kt b/serialization/src/main/kotlin/net/corda/serialization/internal/amqp/SerializerFactoryBuilder.kt new file mode 100644 index 0000000000..0d05d4e0de --- /dev/null +++ b/serialization/src/main/kotlin/net/corda/serialization/internal/amqp/SerializerFactoryBuilder.kt @@ -0,0 +1,53 @@ +package net.corda.serialization.internal.amqp + +import net.corda.core.DeleteForDJVM +import net.corda.core.KeepForDJVM +import net.corda.core.serialization.ClassWhitelist +import net.corda.serialization.internal.carpenter.ClassCarpenter +import net.corda.serialization.internal.carpenter.ClassCarpenterImpl + +@KeepForDJVM +object SerializerFactoryBuilder { + + @JvmStatic + @JvmOverloads + fun build( + whitelist: ClassWhitelist, + classCarpenter: ClassCarpenter, + evolutionSerializerProvider: EvolutionSerializerProvider = DefaultEvolutionSerializerProvider, + fingerPrinterProvider: (SerializerFactory) -> FingerPrinter = ::SerializerFingerPrinter, + onlyCustomSerializers: Boolean = false): SerializerFactory { + return makeFactory( + whitelist, + classCarpenter, + evolutionSerializerProvider, + fingerPrinterProvider, + onlyCustomSerializers) + } + + @JvmStatic + @JvmOverloads + @DeleteForDJVM + fun build( + whitelist: ClassWhitelist, + carpenterClassLoader: ClassLoader, + lenientCarpenterEnabled: Boolean = false, + evolutionSerializerProvider: EvolutionSerializerProvider = DefaultEvolutionSerializerProvider, + fingerPrinterProvider: (SerializerFactory) -> FingerPrinter = ::SerializerFingerPrinter, + onlyCustomSerializers: Boolean = false): SerializerFactory { + return makeFactory( + whitelist, + ClassCarpenterImpl(whitelist, carpenterClassLoader, lenientCarpenterEnabled), + evolutionSerializerProvider, + fingerPrinterProvider, + onlyCustomSerializers) + } + + private fun makeFactory(whitelist: ClassWhitelist, + classCarpenter: ClassCarpenter, + evolutionSerializerProvider: EvolutionSerializerProvider, + fingerPrinterProvider: (SerializerFactory) -> FingerPrinter, + onlyCustomSerializers: Boolean) = + DefaultSerializerFactory(whitelist, classCarpenter, evolutionSerializerProvider, fingerPrinterProvider, + onlyCustomSerializers) +} \ No newline at end of file diff --git a/serialization/src/main/kotlin/net/corda/serialization/internal/model/DefaultCacheProvider.kt b/serialization/src/main/kotlin/net/corda/serialization/internal/model/DefaultCacheProvider.kt new file mode 100644 index 0000000000..4995c1dbb2 --- /dev/null +++ b/serialization/src/main/kotlin/net/corda/serialization/internal/model/DefaultCacheProvider.kt @@ -0,0 +1,11 @@ +package net.corda.serialization.internal.model + +import java.util.concurrent.ConcurrentHashMap + +/** + * We can't have [ConcurrentHashMap]s in the DJVM, so it must supply its own version of this object which returns + * plain old [MutableMap]s instead. + */ +object DefaultCacheProvider { + fun createCache(): MutableMap = ConcurrentHashMap() +} \ No newline at end of file diff --git a/serialization/src/test/java/net/corda/serialization/internal/amqp/JavaPrivatePropertyTests.java b/serialization/src/test/java/net/corda/serialization/internal/amqp/JavaPrivatePropertyTests.java index e96763360d..a68e14b572 100644 --- a/serialization/src/test/java/net/corda/serialization/internal/amqp/JavaPrivatePropertyTests.java +++ b/serialization/src/test/java/net/corda/serialization/internal/amqp/JavaPrivatePropertyTests.java @@ -147,10 +147,7 @@ public class JavaPrivatePropertyTests { // // Now ensure we actually got a private property serializer // - Field f = SerializerFactory.class.getDeclaredField("serializersByDescriptor"); - f.setAccessible(true); - - Map> serializersByDescriptor = uncheckedCast(f.get(factory)); + Map> serializersByDescriptor = factory.getSerializersByDescriptor(); assertEquals(1, serializersByDescriptor.size()); ObjectSerializer cSerializer = ((ObjectSerializer)serializersByDescriptor.values().toArray()[0]); @@ -175,9 +172,7 @@ public class JavaPrivatePropertyTests { // // Now ensure we actually got a private property serializer // - Field f = SerializerFactory.class.getDeclaredField("serializersByDescriptor"); - f.setAccessible(true); - Map> serializersByDescriptor = uncheckedCast(f.get(factory)); + Map> serializersByDescriptor = factory.getSerializersByDescriptor(); assertEquals(1, serializersByDescriptor.size()); ObjectSerializer cSerializer = ((ObjectSerializer)serializersByDescriptor.values().toArray()[0]); diff --git a/serialization/src/test/kotlin/net/corda/serialization/internal/ListsSerializationTest.kt b/serialization/src/test/kotlin/net/corda/serialization/internal/ListsSerializationTest.kt index 60f71520fe..0164664800 100644 --- a/serialization/src/test/kotlin/net/corda/serialization/internal/ListsSerializationTest.kt +++ b/serialization/src/test/kotlin/net/corda/serialization/internal/ListsSerializationTest.kt @@ -7,7 +7,7 @@ import net.corda.node.serialization.kryo.kryoMagic import net.corda.node.services.statemachine.DataSessionMessage import net.corda.serialization.internal.amqp.DeserializationInput import net.corda.serialization.internal.amqp.Envelope -import net.corda.serialization.internal.amqp.SerializerFactory +import net.corda.serialization.internal.amqp.SerializerFactoryBuilder import net.corda.testing.core.SerializationEnvironmentRule import net.corda.testing.internal.amqpSpecific import net.corda.testing.internal.kryoSpecific @@ -28,7 +28,7 @@ class ListsSerializationTest { fun verifyEnvelope(serBytes: SerializedBytes, envVerBody: (Envelope) -> Unit) = amqpSpecific("AMQP specific envelope verification") { val context = SerializationFactory.defaultFactory.defaultContext - val envelope = DeserializationInput(SerializerFactory(context.whitelist, context.deserializationClassLoader)).getEnvelope(serBytes, context) + val envelope = DeserializationInput(SerializerFactoryBuilder.build(context.whitelist, context.deserializationClassLoader)).getEnvelope(serBytes, context) envVerBody(envelope) } } diff --git a/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/CorDappSerializerTests.kt b/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/CorDappSerializerTests.kt index 55aa7ca1a8..d38187f6b7 100644 --- a/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/CorDappSerializerTests.kt +++ b/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/CorDappSerializerTests.kt @@ -4,6 +4,7 @@ import net.corda.core.serialization.ClassWhitelist import net.corda.core.serialization.SerializationCustomSerializer import net.corda.serialization.internal.AllWhitelist import net.corda.serialization.internal.amqp.testutils.* +import net.corda.serialization.internal.carpenter.ClassCarpenterImpl import org.assertj.core.api.Assertions import org.junit.Test import java.io.NotSerializableException @@ -12,16 +13,16 @@ import kotlin.test.assertEquals class CorDappSerializerTests { data class NeedsProxy(val a: String) - private fun proxyFactory( - serializers: List> - ) = SerializerFactory( - AllWhitelist, - ClassLoader.getSystemClassLoader(), - onlyCustomSerializers = true - ).apply { + private fun proxyFactory(serializers: List>): SerializerFactory { + val factory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()), + DefaultEvolutionSerializerProvider) + serializers.forEach { - registerExternal(CorDappCustomSerializer(it, this)) + factory.registerExternal(CorDappCustomSerializer(it, factory)) } + + return factory } class NeedsProxyProxySerializer : SerializationCustomSerializer { @@ -101,7 +102,10 @@ class CorDappSerializerTests { override fun hasListed(type: Class<*>): Boolean = type.name in allowedClasses } - val factory = SerializerFactory(WL(), ClassLoader.getSystemClassLoader()) + val whitelist = WL() + val factory = SerializerFactoryBuilder.build(whitelist, + ClassCarpenterImpl(whitelist, ClassLoader.getSystemClassLoader()) + ) factory.registerExternal(CorDappCustomSerializer(NeedsProxyProxySerializer(), factory)) val tv1 = 100 @@ -123,7 +127,10 @@ class CorDappSerializerTests { override fun hasListed(type: Class<*>): Boolean = type.name in allowedClasses } - val factory = SerializerFactory(WL(), ClassLoader.getSystemClassLoader()) + val whitelist = WL() + val factory = SerializerFactoryBuilder.build(whitelist, + ClassCarpenterImpl(whitelist, ClassLoader.getSystemClassLoader()) + ) factory.registerExternal(CorDappCustomSerializer(NeedsProxyProxySerializer(), factory)) val tv1 = 100 @@ -148,7 +155,10 @@ class CorDappSerializerTests { override fun hasListed(type: Class<*>): Boolean = type.name in allowedClasses } - val factory = SerializerFactory(WL(), ClassLoader.getSystemClassLoader()) + val whitelist = WL() + val factory = SerializerFactoryBuilder.build(whitelist, + ClassCarpenterImpl(whitelist, ClassLoader.getSystemClassLoader()) + ) factory.registerExternal(CorDappCustomSerializer(NeedsProxyProxySerializer(), factory)) val tv1 = 100 diff --git a/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/DeserializeNeedingCarpentryTests.kt b/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/DeserializeNeedingCarpentryTests.kt index 1b6642bdd5..1d7fa23dd6 100644 --- a/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/DeserializeNeedingCarpentryTests.kt +++ b/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/DeserializeNeedingCarpentryTests.kt @@ -94,7 +94,9 @@ class DeserializeNeedingCarpentryTests : AmqpCarpenterBase(AllWhitelist) { // won't already exist and it will be carpented a second time showing that when A and B are the // same underlying class that we didn't create a second instance of the class with the // second deserialisation - val lfactory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val lfactory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) val deserialisedC = DeserializationInput(lfactory).deserialize( TestSerializationOutput(VERBOSE, lfactory).serialize(concreteC)) diff --git a/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/EnumTests.kt b/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/EnumTests.kt index 4221aeff61..badb31c2cd 100644 --- a/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/EnumTests.kt +++ b/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/EnumTests.kt @@ -9,6 +9,7 @@ import net.corda.serialization.internal.amqp.testutils.deserializeAndReturnEnvel import net.corda.serialization.internal.amqp.testutils.serializeAndReturnSchema import net.corda.serialization.internal.amqp.testutils.testDefaultFactoryNoEvolution import net.corda.serialization.internal.amqp.testutils.testName +import net.corda.serialization.internal.carpenter.ClassCarpenterImpl import org.assertj.core.api.Assertions import org.junit.Test import java.io.NotSerializableException @@ -205,7 +206,10 @@ class EnumTests { } } - val factory = SerializerFactory(WL(classTestName("C")), ClassLoader.getSystemClassLoader()) + val whitelist = WL(classTestName("C")) + val factory = SerializerFactoryBuilder.build(whitelist, + ClassCarpenterImpl(whitelist, ClassLoader.getSystemClassLoader()) + ) Assertions.assertThatThrownBy { TestSerializationOutput(VERBOSE, factory).serialize(C(Bras.UNDERWIRE)) @@ -223,7 +227,10 @@ class EnumTests { } } - val factory = SerializerFactory(WL(), ClassLoader.getSystemClassLoader()) + val whitelist = WL() + val factory = SerializerFactoryBuilder.build(whitelist, + ClassCarpenterImpl(whitelist, ClassLoader.getSystemClassLoader()) + ) // if it all works, this won't explode TestSerializationOutput(VERBOSE, factory).serialize(C(Bras.UNDERWIRE)) @@ -237,7 +244,10 @@ class EnumTests { override fun hasListed(type: Class<*>) = false } - val factory = SerializerFactory(WL(), ClassLoader.getSystemClassLoader()) + val whitelist = WL() + val factory = SerializerFactoryBuilder.build(whitelist, + ClassCarpenterImpl(whitelist, ClassLoader.getSystemClassLoader()) + ) // if it all works, this won't explode TestSerializationOutput(VERBOSE, factory).serialize(C(AnnotatedBras.UNDERWIRE)) @@ -252,14 +262,19 @@ class EnumTests { } // first serialise the class using a context in which Bras are whitelisted - val factory = SerializerFactory(WL(listOf(classTestName("C"), - "net.corda.serialization.internal.amqp.EnumTests\$Bras")), - ClassLoader.getSystemClassLoader()) + val whitelist = WL(listOf(classTestName("C"), + "net.corda.serialization.internal.amqp.EnumTests\$Bras")) + val factory = SerializerFactoryBuilder.build(whitelist, + ClassCarpenterImpl(whitelist, ClassLoader.getSystemClassLoader()) + ) val bytes = TestSerializationOutput(VERBOSE, factory).serialize(C(Bras.UNDERWIRE)) // then take that serialised object and attempt to deserialize it in a context that // disallows the Bras enum - val factory2 = SerializerFactory(WL(listOf(classTestName("C"))), ClassLoader.getSystemClassLoader()) + val whitelist1 = WL(listOf(classTestName("C"))) + val factory2 = SerializerFactoryBuilder.build(whitelist1, + ClassCarpenterImpl(whitelist1, ClassLoader.getSystemClassLoader()) + ) Assertions.assertThatThrownBy { DeserializationInput(factory2).deserialize(bytes) }.isInstanceOf(NotSerializableException::class.java) diff --git a/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/FingerPrinterTesting.kt b/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/FingerPrinterTesting.kt index 6d88f3ccf2..1e5f7c3d82 100644 --- a/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/FingerPrinterTesting.kt +++ b/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/FingerPrinterTesting.kt @@ -6,6 +6,7 @@ import kotlin.test.assertEquals import net.corda.serialization.internal.AllWhitelist import net.corda.serialization.internal.amqp.testutils.TestSerializationOutput import net.corda.serialization.internal.amqp.testutils.serializeAndReturnSchema +import net.corda.serialization.internal.carpenter.ClassCarpenterImpl class FingerPrinterTesting : FingerPrinter { private var index = 0 @@ -39,11 +40,9 @@ class FingerPrinterTestingTests { fun worksAsReplacement() { data class C(val a: Int, val b: Long) - val factory = SerializerFactory( - AllWhitelist, - ClassLoader.getSystemClassLoader(), - evolutionSerializerProvider = FailIfEvolutionAttempted, - fingerPrinterConstructor = { _ -> FingerPrinterTesting() }) + val factory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()), + fingerPrinterProvider = { _ -> FingerPrinterTesting() }) val blob = TestSerializationOutput(VERBOSE, factory).serializeAndReturnSchema(C(1, 2L)) diff --git a/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/GenericsTests.kt b/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/GenericsTests.kt index af68f8d669..544d467bd8 100644 --- a/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/GenericsTests.kt +++ b/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/GenericsTests.kt @@ -9,6 +9,7 @@ import net.corda.core.identity.CordaX500Name import net.corda.core.serialization.SerializedBytes import net.corda.serialization.internal.amqp.testutils.* import net.corda.serialization.internal.AllWhitelist +import net.corda.serialization.internal.carpenter.ClassCarpenterImpl import net.corda.testing.common.internal.ProjectStructure.projectRootDir import net.corda.testing.core.TestIdentity import org.junit.Test @@ -120,8 +121,12 @@ class GenericsTests { data class G(val a: Int) data class Wrapper(val a: Int, val b: SerializedBytes) - val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) - val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) + val factory2 = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) val ser = SerializationOutput(factory) val gBytes = ser.serialize(G(1)) @@ -145,8 +150,12 @@ class GenericsTests { data class Container(val b: T) data class Wrapper(val c: Container) - val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) - val factories = listOf(factory, SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())) + val factory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) + val factories = listOf(factory, SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + )) val ser = SerializationOutput(factory) ser.serialize(Wrapper(Container(InnerA(1)))).apply { @@ -178,8 +187,12 @@ class GenericsTests { data class Wrapper(val c: Container) val factorys = listOf( - SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()), - SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())) + SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ), + SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + )) val ser = SerializationOutput(factorys[0]) @@ -200,7 +213,9 @@ class GenericsTests { private fun forceWildcardSerialize( a: ForceWildcard<*>, - factory: SerializerFactory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())): SerializedBytes<*> { + factory: SerializerFactory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + )): SerializedBytes<*> { val bytes = SerializationOutput(factory).serializeAndReturnSchema(a) factory.serializersByDescriptor.printKeyToType() bytes.printSchema() @@ -210,21 +225,27 @@ class GenericsTests { @Suppress("UNCHECKED_CAST") private fun forceWildcardDeserializeString( bytes: SerializedBytes<*>, - factory: SerializerFactory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())) { + factory: SerializerFactory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + )) { DeserializationInput(factory).deserialize(bytes as SerializedBytes>) } @Suppress("UNCHECKED_CAST") private fun forceWildcardDeserializeDouble( bytes: SerializedBytes<*>, - factory: SerializerFactory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())) { + factory: SerializerFactory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + )) { DeserializationInput(factory).deserialize(bytes as SerializedBytes>) } @Suppress("UNCHECKED_CAST") private fun forceWildcardDeserialize( bytes: SerializedBytes<*>, - factory: SerializerFactory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())) { + factory: SerializerFactory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + )) { DeserializationInput(factory).deserialize(bytes as SerializedBytes>) } @@ -236,7 +257,9 @@ class GenericsTests { @Test fun forceWildcardSharedFactory() { - val f = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val f = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) forceWildcardDeserializeString(forceWildcardSerialize(ForceWildcard("hello"), f), f) forceWildcardDeserializeDouble(forceWildcardSerialize(ForceWildcard(3.0), f), f) } @@ -250,7 +273,9 @@ class GenericsTests { @Test fun forceWildcardDeserializeSharedFactory() { - val f = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val f = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) forceWildcardDeserialize(forceWildcardSerialize(ForceWildcard("hello"), f), f) forceWildcardDeserialize(forceWildcardSerialize(ForceWildcard(10), f), f) forceWildcardDeserialize(forceWildcardSerialize(ForceWildcard(20.0), f), f) @@ -288,7 +313,9 @@ class GenericsTests { // possibly altering how we serialise things val altClassLoader = cl() - val factory2 = SerializerFactory(AllWhitelist, altClassLoader) + val factory2 = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, altClassLoader) + ) factory2.register(net.corda.serialization.internal.amqp.custom.PublicKeySerializer) val ser2 = TestSerializationOutput(VERBOSE, factory2).serializeAndReturnSchema(state) @@ -297,7 +324,9 @@ class GenericsTests { factory3.register(net.corda.serialization.internal.amqp.custom.PublicKeySerializer) DeserializationInput(factory3).deserializeAndReturnEnvelope(ser1.obj) - val factory4 = SerializerFactory(AllWhitelist, cl()) + val factory4 = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, cl()) + ) factory4.register(net.corda.serialization.internal.amqp.custom.PublicKeySerializer) DeserializationInput(factory4).deserializeAndReturnEnvelope(ser2.obj) } diff --git a/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/OptionalSerializationTests.kt b/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/OptionalSerializationTests.kt index 10b154863f..cf12f740a8 100644 --- a/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/OptionalSerializationTests.kt +++ b/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/OptionalSerializationTests.kt @@ -5,6 +5,7 @@ import net.corda.serialization.internal.amqp.custom.OptionalSerializer import net.corda.serialization.internal.amqp.testutils.TestSerializationOutput import net.corda.serialization.internal.amqp.testutils.deserialize import net.corda.serialization.internal.amqp.testutils.testDefaultFactory +import net.corda.serialization.internal.carpenter.ClassCarpenterImpl import org.hamcrest.Matchers.`is` import org.hamcrest.Matchers.equalTo import org.junit.Assert @@ -17,7 +18,9 @@ class OptionalSerializationTests { fun setupEnclosedSerializationTest() { @Test fun `java optionals should serialize`() { - val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory.register(OptionalSerializer(factory)) val obj = Optional.ofNullable("YES") val bytes = TestSerializationOutput(true, factory).serialize(obj) diff --git a/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/PrivatePropertyTests.kt b/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/PrivatePropertyTests.kt index 5a62f66c4f..b4012b5c00 100644 --- a/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/PrivatePropertyTests.kt +++ b/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/PrivatePropertyTests.kt @@ -17,15 +17,6 @@ import java.util.* class PrivatePropertyTests { private val factory = testDefaultFactoryNoEvolution() - companion object { - val fields : Map = mapOf ( - "serializersByDesc" to SerializerFactory::class.java.getDeclaredField("serializersByDescriptor")).apply { - this.values.forEach { - it.isAccessible = true - } - } - } - @Test fun testWithOnePrivateProperty() { data class C(private val b: String) @@ -134,8 +125,7 @@ class PrivatePropertyTests { val schemaAndBlob = SerializationOutput(factory).serializeAndReturnSchema(c1) assertEquals(1, schemaAndBlob.schema.types.size) - @Suppress("UNCHECKED_CAST") - val serializersByDescriptor = fields["serializersByDesc"]?.get(factory) as ConcurrentHashMap> + val serializersByDescriptor = factory.serializersByDescriptor val schemaDescriptor = schemaAndBlob.schema.types.first().descriptor.name serializersByDescriptor.filterKeys { (it as Symbol) == schemaDescriptor }.values.apply { @@ -163,8 +153,7 @@ class PrivatePropertyTests { val schemaAndBlob = SerializationOutput(factory).serializeAndReturnSchema(c1) assertEquals(1, schemaAndBlob.schema.types.size) - @Suppress("UNCHECKED_CAST") - val serializersByDescriptor = fields["serializersByDesc"]?.get(factory) as ConcurrentHashMap> + val serializersByDescriptor = factory.serializersByDescriptor val schemaDescriptor = schemaAndBlob.schema.types.first().descriptor.name serializersByDescriptor.filterKeys { (it as Symbol) == schemaDescriptor }.values.apply { @@ -192,7 +181,7 @@ class PrivatePropertyTests { val output = SerializationOutput(factory).serializeAndReturnSchema(c1) println (output.schema) - val serializersByDescriptor = fields["serializersByDesc"]!!.get(factory) as ConcurrentHashMap> + val serializersByDescriptor = factory.serializersByDescriptor // Inner and Outer assertEquals(2, serializersByDescriptor.size) @@ -212,7 +201,7 @@ class PrivatePropertyTests { val output = SerializationOutput(factory).serializeAndReturnSchema(C("this is nice")) - val serializersByDescriptor = fields["serializersByDesc"]!!.get(factory) as ConcurrentHashMap> + val serializersByDescriptor = factory.serializersByDescriptor val schemaDescriptor = output.schema.types.first().descriptor.name serializersByDescriptor.filterKeys { (it as Symbol) == schemaDescriptor }.values.apply { diff --git a/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/SerializationOutputTests.kt b/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/SerializationOutputTests.kt index a0259ca36c..0ee30b0373 100644 --- a/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/SerializationOutputTests.kt +++ b/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/SerializationOutputTests.kt @@ -23,6 +23,7 @@ import net.corda.nodeapi.internal.crypto.ContentSignerBuilder import net.corda.serialization.internal.* import net.corda.serialization.internal.amqp.SerializerFactory.Companion.isPrimitive import net.corda.serialization.internal.amqp.testutils.* +import net.corda.serialization.internal.carpenter.ClassCarpenterImpl import net.corda.testing.contracts.DummyContract import net.corda.testing.core.BOB_NAME import net.corda.testing.core.SerializationEnvironmentRule @@ -207,9 +208,8 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi } private fun defaultFactory(): SerializerFactory { - return SerializerFactory( - AllWhitelist, - ClassLoader.getSystemClassLoader(), + return SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()), evolutionSerializerProvider = FailIfEvolutionAttempted ) } @@ -368,13 +368,17 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi @Test(expected = NotSerializableException::class) fun `test whitelist`() { val obj = Woo2(4) - serdes(obj, SerializerFactory(EmptyWhitelist, ClassLoader.getSystemClassLoader())) + serdes(obj, SerializerFactoryBuilder.build(EmptyWhitelist, + ClassCarpenterImpl(EmptyWhitelist, ClassLoader.getSystemClassLoader()) + )) } @Test fun `test annotation whitelisting`() { val obj = AnnotatedWoo(5) - serdes(obj, SerializerFactory(EmptyWhitelist, ClassLoader.getSystemClassLoader())) + serdes(obj, SerializerFactoryBuilder.build(EmptyWhitelist, + ClassCarpenterImpl(EmptyWhitelist, ClassLoader.getSystemClassLoader()) + )) } @Test(expected = NotSerializableException::class) @@ -471,7 +475,9 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi @Test fun `class constructor is invoked on deserialisation`() { compression == null || return // Manipulation of serialized bytes is invalid if they're compressed. - val ser = SerializationOutput(SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())) + val ser = SerializationOutput(SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + )) val des = DeserializationInput(ser.serializerFactory) val serialisedOne = ser.serialize(NonZeroByte(1), compression).bytes val serialisedTwo = ser.serialize(NonZeroByte(2), compression).bytes @@ -496,9 +502,13 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi @Test fun `test custom serializers on public key`() { - val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory.register(net.corda.serialization.internal.amqp.custom.PublicKeySerializer) - val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory2 = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory2.register(net.corda.serialization.internal.amqp.custom.PublicKeySerializer) val obj = MEGA_CORP_PUBKEY serdes(obj, factory, factory2) @@ -507,21 +517,29 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi @Test fun `test annotation is inherited`() { val obj = InheritAnnotation("blah") - serdes(obj, SerializerFactory(EmptyWhitelist, ClassLoader.getSystemClassLoader())) + serdes(obj, SerializerFactoryBuilder.build(EmptyWhitelist, + ClassCarpenterImpl(EmptyWhitelist, ClassLoader.getSystemClassLoader()) + )) } @Test fun `generics from java are supported`() { val obj = DummyOptional("YES") - serdes(obj, SerializerFactory(EmptyWhitelist, ClassLoader.getSystemClassLoader())) + serdes(obj, SerializerFactoryBuilder.build(EmptyWhitelist, + ClassCarpenterImpl(EmptyWhitelist, ClassLoader.getSystemClassLoader()) + )) } @Test fun `test throwables serialize`() { - val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory.register(net.corda.serialization.internal.amqp.custom.ThrowableSerializer(factory)) - val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory2 = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory2.register(net.corda.serialization.internal.amqp.custom.ThrowableSerializer(factory2)) val t = IllegalAccessException("message").fillInStackTrace() @@ -537,10 +555,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi @Test fun `test complex throwables serialize`() { - val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory.register(net.corda.serialization.internal.amqp.custom.ThrowableSerializer(factory)) - val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory2 = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory2.register(net.corda.serialization.internal.amqp.custom.ThrowableSerializer(factory2)) try { @@ -567,10 +589,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi @Test fun `test suppressed throwables serialize`() { - val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory.register(net.corda.serialization.internal.amqp.custom.ThrowableSerializer(factory)) - val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory2 = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory2.register(net.corda.serialization.internal.amqp.custom.ThrowableSerializer(factory2)) try { @@ -589,10 +615,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi @Test fun `test flow corda exception subclasses serialize`() { - val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory.register(net.corda.serialization.internal.amqp.custom.ThrowableSerializer(factory)) - val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory2 = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory2.register(net.corda.serialization.internal.amqp.custom.ThrowableSerializer(factory2)) val obj = FlowException("message").fillInStackTrace() @@ -601,10 +631,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi @Test fun `test RPC corda exception subclasses serialize`() { - val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory.register(net.corda.serialization.internal.amqp.custom.ThrowableSerializer(factory)) - val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory2 = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory2.register(net.corda.serialization.internal.amqp.custom.ThrowableSerializer(factory2)) val obj = RPCException("message").fillInStackTrace() @@ -666,10 +700,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi SerializerFactory::class.java) func.isAccessible = true - val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) func.invoke(scheme, testSerializationContext, factory) - val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory2 = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) func.invoke(scheme, testSerializationContext, factory2) val desState = serdes(state, factory, factory2, expectedEqual = false, expectDeserializedEqual = false) @@ -680,10 +718,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi @Test fun `test currencies serialize`() { - val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory.register(net.corda.serialization.internal.amqp.custom.CurrencySerializer) - val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory2 = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory2.register(net.corda.serialization.internal.amqp.custom.CurrencySerializer) val obj = Currency.getInstance("USD") @@ -692,10 +734,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi @Test fun `test big decimals serialize`() { - val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory.register(net.corda.serialization.internal.amqp.custom.BigDecimalSerializer) - val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory2 = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory2.register(net.corda.serialization.internal.amqp.custom.BigDecimalSerializer) val obj = BigDecimal("100000000000000000000000000000.00") @@ -704,10 +750,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi @Test fun `test instants serialize`() { - val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory.register(net.corda.serialization.internal.amqp.custom.InstantSerializer(factory)) - val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory2 = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory2.register(net.corda.serialization.internal.amqp.custom.InstantSerializer(factory2)) val obj = Instant.now() @@ -716,10 +766,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi @Test fun `test durations serialize`() { - val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory.register(net.corda.serialization.internal.amqp.custom.DurationSerializer(factory)) - val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory2 = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory2.register(net.corda.serialization.internal.amqp.custom.DurationSerializer(factory2)) val obj = Duration.of(1000000L, ChronoUnit.MILLIS) @@ -728,10 +782,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi @Test fun `test local date serialize`() { - val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory.register(net.corda.serialization.internal.amqp.custom.LocalDateSerializer(factory)) - val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory2 = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory2.register(net.corda.serialization.internal.amqp.custom.LocalDateSerializer(factory2)) val obj = LocalDate.now() @@ -740,10 +798,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi @Test fun `test local time serialize`() { - val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory.register(net.corda.serialization.internal.amqp.custom.LocalTimeSerializer(factory)) - val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory2 = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory2.register(net.corda.serialization.internal.amqp.custom.LocalTimeSerializer(factory2)) val obj = LocalTime.now() @@ -752,10 +814,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi @Test fun `test local date time serialize`() { - val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory.register(net.corda.serialization.internal.amqp.custom.LocalDateTimeSerializer(factory)) - val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory2 = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory2.register(net.corda.serialization.internal.amqp.custom.LocalDateTimeSerializer(factory2)) val obj = LocalDateTime.now() @@ -764,10 +830,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi @Test fun `test zoned date time serialize`() { - val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory.register(net.corda.serialization.internal.amqp.custom.ZonedDateTimeSerializer(factory)) - val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory2 = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory2.register(net.corda.serialization.internal.amqp.custom.ZonedDateTimeSerializer(factory2)) val obj = ZonedDateTime.now() @@ -776,10 +846,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi @Test fun `test offset time serialize`() { - val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory.register(net.corda.serialization.internal.amqp.custom.OffsetTimeSerializer(factory)) - val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory2 = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory2.register(net.corda.serialization.internal.amqp.custom.OffsetTimeSerializer(factory2)) val obj = OffsetTime.now() @@ -788,10 +862,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi @Test fun `test offset date time serialize`() { - val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory.register(net.corda.serialization.internal.amqp.custom.OffsetDateTimeSerializer(factory)) - val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory2 = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory2.register(net.corda.serialization.internal.amqp.custom.OffsetDateTimeSerializer(factory2)) val obj = OffsetDateTime.now() @@ -800,10 +878,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi @Test fun `test year serialize`() { - val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory.register(net.corda.serialization.internal.amqp.custom.YearSerializer(factory)) - val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory2 = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory2.register(net.corda.serialization.internal.amqp.custom.YearSerializer(factory2)) val obj = Year.now() @@ -812,10 +894,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi @Test fun `test year month serialize`() { - val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory.register(net.corda.serialization.internal.amqp.custom.YearMonthSerializer(factory)) - val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory2 = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory2.register(net.corda.serialization.internal.amqp.custom.YearMonthSerializer(factory2)) val obj = YearMonth.now() @@ -824,10 +910,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi @Test fun `test month day serialize`() { - val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory.register(net.corda.serialization.internal.amqp.custom.MonthDaySerializer(factory)) - val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory2 = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory2.register(net.corda.serialization.internal.amqp.custom.MonthDaySerializer(factory2)) val obj = MonthDay.now() @@ -836,10 +926,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi @Test fun `test period serialize`() { - val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory.register(net.corda.serialization.internal.amqp.custom.PeriodSerializer(factory)) - val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory2 = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory2.register(net.corda.serialization.internal.amqp.custom.PeriodSerializer(factory2)) val obj = Period.of(99, 98, 97) @@ -866,10 +960,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi @Test fun `test X509 certificate serialize`() { - val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory.register(net.corda.serialization.internal.amqp.custom.X509CertificateSerializer) - val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory2 = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory2.register(net.corda.serialization.internal.amqp.custom.X509CertificateSerializer) val obj = BOB_IDENTITY.certificate @@ -878,10 +976,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi @Test fun `test cert path serialize`() { - val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory.register(net.corda.serialization.internal.amqp.custom.CertPathSerializer(factory)) - val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory2 = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory2.register(net.corda.serialization.internal.amqp.custom.CertPathSerializer(factory2)) val obj = BOB_IDENTITY.certPath @@ -905,9 +1007,13 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi @Test fun `test StateRef serialize`() { - val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) - val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory2 = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) val obj = StateRef(SecureHash.randomSHA256(), 0) serdes(obj, factory, factory2) @@ -953,8 +1059,12 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi val b = ByteArray(2) val obj = Bob(listOf(a, b, a)) - val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) - val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) + val factory2 = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) val obj2 = serdes(obj, factory, factory2, false, false) assertNotSame(obj2.byteArrays[0], obj2.byteArrays[2]) @@ -967,8 +1077,12 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi val a = listOf("a", "b") val obj = Vic(a, a) - val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) - val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) + val factory2 = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) val objCopy = serdes(obj, factory, factory2) assertSame(objCopy.a, objCopy.b) } @@ -984,8 +1098,12 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi fun `test private constructor`() { val obj = Spike() - val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) - val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) + val factory2 = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) serdes(obj, factory, factory2) } @@ -993,10 +1111,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi @Test fun `test toString custom serializer`() { - val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory.register(net.corda.serialization.internal.amqp.custom.BigDecimalSerializer) - val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory2 = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory2.register(net.corda.serialization.internal.amqp.custom.BigDecimalSerializer) val obj = BigDecimals(BigDecimal.TEN, BigDecimal.TEN) @@ -1008,10 +1130,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi @Test fun `test BigInteger custom serializer`() { - val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory.register(net.corda.serialization.internal.amqp.custom.BigIntegerSerializer) - val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory2 = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory2.register(net.corda.serialization.internal.amqp.custom.BigIntegerSerializer) val obj = BigIntegers(BigInteger.TEN, BigInteger.TEN) @@ -1028,10 +1154,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi @Test fun `test X509CRL custom serializer`() { - val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory.register(net.corda.serialization.internal.amqp.custom.X509CRLSerializer) - val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory2 = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory2.register(net.corda.serialization.internal.amqp.custom.X509CRLSerializer) val obj = emptyCrl() @@ -1042,10 +1172,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi @Test fun `test byte arrays not reference counted`() { - val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory.register(net.corda.serialization.internal.amqp.custom.BigDecimalSerializer) - val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory2 = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory2.register(net.corda.serialization.internal.amqp.custom.BigDecimalSerializer) val bytes = ByteArray(1) @@ -1056,10 +1190,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi @Test fun `test StringBuffer serialize`() { - val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory.register(net.corda.serialization.internal.amqp.custom.StringBufferSerializer) - val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory2 = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory2.register(net.corda.serialization.internal.amqp.custom.StringBufferSerializer) val obj = StringBuffer("Bob") @@ -1069,10 +1207,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi @Test fun `test SimpleString serialize`() { - val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory.register(net.corda.serialization.internal.amqp.custom.SimpleStringSerializer) - val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory2 = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory2.register(net.corda.serialization.internal.amqp.custom.SimpleStringSerializer) val obj = SimpleString("Bob") @@ -1093,10 +1235,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi @Test fun `test InputStream serialize`() { - val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory.register(net.corda.serialization.internal.amqp.custom.InputStreamSerializer) - val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory2 = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory2.register(net.corda.serialization.internal.amqp.custom.InputStreamSerializer) val bytes = ByteArray(10) { it.toByte() } val obj = bytes.inputStream() @@ -1108,10 +1254,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi @Test fun `test EnumSet serialize`() { - val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory.register(net.corda.serialization.internal.amqp.custom.EnumSetSerializer(factory)) - val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory2 = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory2.register(net.corda.serialization.internal.amqp.custom.EnumSetSerializer(factory2)) val obj = EnumSet.of(Month.APRIL, Month.AUGUST) @@ -1120,10 +1270,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi @Test fun `test BitSet serialize`() { - val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory.register(net.corda.serialization.internal.amqp.custom.BitSetSerializer(factory)) - val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory2 = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory2.register(net.corda.serialization.internal.amqp.custom.BitSetSerializer(factory2)) val obj = BitSet.valueOf(kotlin.ByteArray(16) { it.toByte() }).get(0, 123) @@ -1140,10 +1294,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi @Test fun `test contract attachment serialize`() { - val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory.register(net.corda.serialization.internal.amqp.custom.ContractAttachmentSerializer(factory)) - val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory2 = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory2.register(net.corda.serialization.internal.amqp.custom.ContractAttachmentSerializer(factory2)) val obj = ContractAttachment(GeneratedAttachment("test".toByteArray()), DummyContract.PROGRAM_ID) @@ -1156,10 +1314,14 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi @Test fun `test contract attachment throws if missing attachment`() { - val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory.register(net.corda.serialization.internal.amqp.custom.ContractAttachmentSerializer(factory)) - val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val factory2 = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) factory2.register(net.corda.serialization.internal.amqp.custom.ContractAttachmentSerializer(factory2)) val obj = ContractAttachment(object : AbstractAttachment({ throw Exception() }) { @@ -1351,7 +1513,9 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi @Test fun `compression reduces number of bytes significantly`() { - val ser = SerializationOutput(SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())) + val ser = SerializationOutput(SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + )) val obj = ByteArray(20000) val uncompressedSize = ser.serialize(obj).bytes.size val compressedSize = ser.serialize(obj, CordaSerializationEncoding.SNAPPY).bytes.size diff --git a/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/SerializationPropertyOrdering.kt b/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/SerializationPropertyOrdering.kt index 0e1f8788f3..750a2f2c5c 100644 --- a/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/SerializationPropertyOrdering.kt +++ b/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/SerializationPropertyOrdering.kt @@ -102,14 +102,13 @@ class SerializationPropertyOrdering { // Test needs to look at a bunch of private variables, change the access semantics for them val fields : Map = mapOf ( - "serializersByDesc" to SerializerFactory::class.java.getDeclaredField("serializersByDescriptor"), "setter" to PropertyAccessorGetterSetter::class.java.getDeclaredField("setter")).apply { this.values.forEach { it.isAccessible = true } } - val serializersByDescriptor = fields["serializersByDesc"]!!.get(sf) as ConcurrentHashMap> + val serializersByDescriptor = sf.serializersByDescriptor val schemaDescriptor = output.schema.types.first().descriptor.name // make sure that each property accessor has a setter to ensure we're using getter / setter instantiation diff --git a/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/SerializationSchemaTests.kt b/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/SerializationSchemaTests.kt index a5f4925f24..7a56cbb953 100644 --- a/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/SerializationSchemaTests.kt +++ b/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/SerializationSchemaTests.kt @@ -6,6 +6,7 @@ import net.corda.serialization.internal.BuiltInExceptionsWhitelist import net.corda.serialization.internal.CordaSerializationMagic import net.corda.serialization.internal.GlobalTransientClassWhiteList import net.corda.serialization.internal.SerializationContextImpl +import net.corda.serialization.internal.carpenter.ClassCarpenterImpl import org.junit.Test import kotlin.test.assertEquals @@ -22,7 +23,7 @@ val TESTING_CONTEXT = SerializationContextImpl(amqpMagic, class TestSerializerFactory( wl: ClassWhitelist, cl: ClassLoader -) : SerializerFactory(wl, cl) { +) : DefaultSerializerFactory(wl, ClassCarpenterImpl(wl, cl, false), DefaultEvolutionSerializerProvider, ::SerializerFingerPrinter) { var registerCount = 0 override fun register(customSerializer: CustomSerializer) { diff --git a/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/StaticInitialisationOfSerializedObjectTest.kt b/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/StaticInitialisationOfSerializedObjectTest.kt index 800f5e87c7..f8450faf49 100644 --- a/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/StaticInitialisationOfSerializedObjectTest.kt +++ b/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/StaticInitialisationOfSerializedObjectTest.kt @@ -48,7 +48,9 @@ class StaticInitialisationOfSerializedObjectTest { fun kotlinObjectWithCompanionObject() { data class D(val c: C) - val sf = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) + val sf = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) + ) val typeMap = sf::class.java.getDeclaredField("serializersByType") typeMap.isAccessible = true @@ -87,7 +89,10 @@ class StaticInitialisationOfSerializedObjectTest { ".StaticInitialisationOfSerializedObjectTest\$deserializeTest\$D" } - val sf2 = SerializerFactory(WL(), ClassLoader.getSystemClassLoader()) + val whitelist = WL() + val sf2 = SerializerFactoryBuilder.build(whitelist, + ClassCarpenterImpl(whitelist, ClassLoader.getSystemClassLoader()) + ) val bytes = url.readBytes() assertThatThrownBy { @@ -97,8 +102,8 @@ class StaticInitialisationOfSerializedObjectTest { // Version of a serializer factory that will allow the class carpenter living on the // factory to have a different whitelist applied to it than the factory - class TestSerializerFactory(wl1: ClassWhitelist, wl2: ClassWhitelist) : - SerializerFactory(wl1, ClassCarpenterImpl(wl2, ClassLoader.getSystemClassLoader())) + private fun testSerializerFactory(wl1: ClassWhitelist, wl2: ClassWhitelist) = + SerializerFactoryBuilder.build(wl1, ClassCarpenterImpl(wl2, ClassLoader.getSystemClassLoader())) // This time have the serialization factory and the carpenter use different whitelists @Test @@ -126,7 +131,7 @@ class StaticInitialisationOfSerializedObjectTest { override fun hasListed(type: Class<*>) = true } - val sf2 = TestSerializerFactory(WL1(), WL2()) + val sf2 = testSerializerFactory(WL1(), WL2()) val bytes = url.readBytes() // Deserializing should throw because C is not on the whitelist NOT because diff --git a/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/testutils/AMQPTestUtils.kt b/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/testutils/AMQPTestUtils.kt index ea81448da7..b248d11c2d 100644 --- a/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/testutils/AMQPTestUtils.kt +++ b/serialization/src/test/kotlin/net/corda/serialization/internal/amqp/testutils/AMQPTestUtils.kt @@ -10,6 +10,7 @@ import net.corda.core.utilities.OpaqueBytes import net.corda.serialization.internal.AllWhitelist import net.corda.serialization.internal.EmptyWhitelist import net.corda.serialization.internal.amqp.* +import net.corda.serialization.internal.carpenter.ClassCarpenterImpl import net.corda.testing.common.internal.ProjectStructure import org.apache.qpid.proton.codec.Data import org.junit.Test @@ -17,16 +18,20 @@ import java.io.File.separatorChar import java.io.NotSerializableException import java.nio.file.StandardCopyOption.REPLACE_EXISTING -fun testDefaultFactory() = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) +fun testDefaultFactory() = SerializerFactoryBuilder.build(AllWhitelist, + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()) +) fun testDefaultFactoryNoEvolution(): SerializerFactory { - return SerializerFactory( + return SerializerFactoryBuilder.build( AllWhitelist, - ClassLoader.getSystemClassLoader(), - evolutionSerializerProvider = FailIfEvolutionAttempted) + ClassCarpenterImpl(AllWhitelist, ClassLoader.getSystemClassLoader()), + FailIfEvolutionAttempted) } -fun testDefaultFactoryWithWhitelist() = SerializerFactory(EmptyWhitelist, ClassLoader.getSystemClassLoader()) +fun testDefaultFactoryWithWhitelist() = SerializerFactoryBuilder.build(EmptyWhitelist, + ClassCarpenterImpl(EmptyWhitelist, ClassLoader.getSystemClassLoader()) +) class TestSerializationOutput( private val verbose: Boolean, diff --git a/serialization/src/test/kotlin/net/corda/serialization/internal/carpenter/CarpenterExceptionTests.kt b/serialization/src/test/kotlin/net/corda/serialization/internal/carpenter/CarpenterExceptionTests.kt index 8aeaa99ac7..fd1e737e5a 100644 --- a/serialization/src/test/kotlin/net/corda/serialization/internal/carpenter/CarpenterExceptionTests.kt +++ b/serialization/src/test/kotlin/net/corda/serialization/internal/carpenter/CarpenterExceptionTests.kt @@ -5,7 +5,6 @@ import net.corda.serialization.internal.AllWhitelist import net.corda.serialization.internal.amqp.* import net.corda.serialization.internal.amqp.testutils.TestSerializationOutput import net.corda.serialization.internal.amqp.testutils.deserialize -import net.corda.serialization.internal.amqp.testutils.serialize import net.corda.serialization.internal.amqp.testutils.testDefaultFactory import org.assertj.core.api.Assertions import org.junit.Test @@ -33,8 +32,8 @@ interface TestInterface { // Create a custom serialization factory where we need to be able to both specify a carpenter // but also have the class loader used by the carpenter be substantially different from the // one used by the factory so as to ensure we can control their behaviour independently. -class TestFactory(classCarpenter: ClassCarpenter) - : SerializerFactory(classCarpenter.whitelist, classCarpenter) +private fun testFactory(classCarpenter: ClassCarpenter) + = SerializerFactoryBuilder.build(classCarpenter.whitelist, classCarpenter) class CarpenterExceptionTests { companion object { @@ -90,7 +89,7 @@ class CarpenterExceptionTests { // we set the class loader of the ClassCarpenter to reject one of them, resulting in a CarpentryError // which we then want the code to wrap in a NotSerializeableException val cc = ClassCarpenterImpl(AllWhitelist, TestClassLoader(listOf(C2::class.jvmName))) - val factory = TestFactory(cc) + val factory = testFactory(cc) Assertions.assertThatThrownBy { DeserializationInput(factory).deserialize(ser) diff --git a/serialization/src/test/kotlin/net/corda/serialization/internal/carpenter/ClassCarpenterTestUtils.kt b/serialization/src/test/kotlin/net/corda/serialization/internal/carpenter/ClassCarpenterTestUtils.kt index 5c3701dc49..0068399ed6 100644 --- a/serialization/src/test/kotlin/net/corda/serialization/internal/carpenter/ClassCarpenterTestUtils.kt +++ b/serialization/src/test/kotlin/net/corda/serialization/internal/carpenter/ClassCarpenterTestUtils.kt @@ -41,12 +41,12 @@ fun Schema.mangleNames(names: List): Schema { * Custom implementation of a [SerializerFactory] where we need to give it a class carpenter * rather than have it create its own */ -class SerializerFactoryExternalCarpenter(classCarpenter: ClassCarpenter) - : SerializerFactory(classCarpenter.whitelist, classCarpenter) +private fun serializerFactoryExternalCarpenter(classCarpenter: ClassCarpenter) + = SerializerFactoryBuilder.build(classCarpenter.whitelist, classCarpenter) open class AmqpCarpenterBase(whitelist: ClassWhitelist) { var cc = ClassCarpenterImpl(whitelist = whitelist) - var factory = SerializerFactoryExternalCarpenter(cc) + var factory = serializerFactoryExternalCarpenter(cc) fun serialise(obj: T): SerializedBytes = SerializationOutput(factory).serialize(obj) @Suppress("NOTHING_TO_INLINE")