[CORDA-2473] - Remove AMQP system property (#5112)

This commit is contained in:
Dimos Raptis 2019-05-14 13:22:23 +01:00 committed by Shams Asari
parent ab8d4a312a
commit a468bee0ed
4 changed files with 18 additions and 73 deletions

View File

@ -23,7 +23,6 @@ import net.corda.serialization.internal.amqp.SerializationFactoryCacheKey
import net.corda.serialization.internal.amqp.SerializerFactory
import java.time.Duration
import java.util.ServiceLoader
import java.net.URLClassLoader
/**
* This class is essentially just a wrapper for an RPCConnection<CordaRPCOps> and can be treated identically.
@ -300,14 +299,11 @@ class CordaRPCClient private constructor(
try {
val cache = Caffeine.newBuilder().maximumSize(128).build<SerializationFactoryCacheKey, SerializerFactory>().asMap()
// If the client has provided a classloader, the associated classpath is checked for available custom serializers and serialization whitelists.
if (classLoader != null) {
val customSerializers = createInstancesOfClassesImplementing(classLoader, SerializationCustomSerializer::class.java)
val serializationWhitelists = ServiceLoader.load(SerializationWhitelist::class.java, classLoader).toSet()
AMQPClientSerializationScheme.initialiseSerialization(classLoader, customSerializers, serializationWhitelists, cache)
} else {
AMQPClientSerializationScheme.initialiseSerialization(classLoader, serializerFactoriesForContexts = cache)
}
// If the client has explicitly provided a classloader use this one to scan for custom serializers, otherwise use the current one.
val serializationClassLoader = this.classLoader ?: this.javaClass.classLoader
val customSerializers = createInstancesOfClassesImplementing(serializationClassLoader, SerializationCustomSerializer::class.java)
val serializationWhitelists = ServiceLoader.load(SerializationWhitelist::class.java, serializationClassLoader).toSet()
AMQPClientSerializationScheme.initialiseSerialization(serializationClassLoader, customSerializers, serializationWhitelists, cache)
} catch (e: IllegalStateException) {
// Race e.g. two of these constructed in parallel, ignore.
}

View File

@ -27,10 +27,7 @@ Serializers must
* Inherit from ``net.corda.core.serialization.SerializationCustomSerializer``
* Provide a proxy class to transform the object to and from
* Implement the ``toProxy`` and ``fromProxy`` methods
* Be either included into the CorDapp Jar or made known to the running process via the ``amqp.custom.serialization.scanSpec``
system property. This system property may be necessary to be able to discover custom serializer in the classpath.
At a minimum the value of the property should include comma separated set of packages where custom serializers located.
Full syntax includes scanning specification as defined by: `<http://github.com/lukehutch/fast-classpath-scanner/wiki/2.-Constructor#scan-spec>`
* Be either included into the CorDapp Jar or made available in the system class path of the running process
Serializers inheriting from ``SerializationCustomSerializer`` have to implement two methods and two types.

View File

@ -2,7 +2,6 @@
package net.corda.serialization.internal.amqp
import io.github.classgraph.ClassGraph
import net.corda.core.DeleteForDJVM
import net.corda.core.KeepForDJVM
import net.corda.core.StubOutForDJVM
@ -10,7 +9,6 @@ import net.corda.core.cordapp.Cordapp
import net.corda.core.internal.*
import net.corda.core.serialization.*
import net.corda.core.utilities.ByteSequence
import net.corda.core.utilities.contextLogger
import net.corda.serialization.internal.CordaSerializationMagic
import net.corda.serialization.internal.DefaultWhitelist
import net.corda.serialization.internal.MutableClassWhitelist
@ -57,44 +55,8 @@ abstract class AbstractAMQPSerializationScheme(
maybeNotConcurrentSerializerFactoriesForContexts
}
// TODO: This method of initialisation for the Whitelist and plugin serializers will have to change
// when we have per-cordapp contexts and dynamic app reloading but for now it's the easiest way
companion object {
const val SCAN_SPEC_PROP_NAME = "amqp.custom.serialization.scanSpec"
private val logger = contextLogger()
private val serializationWhitelists: List<SerializationWhitelist> by lazy {
ServiceLoader.load(SerializationWhitelist::class.java, this::class.java.classLoader).toList() + DefaultWhitelist
}
private val customSerializers: List<SerializationCustomSerializer<*, *>> by lazy {
val scanSpec: String? = System.getProperty(SCAN_SPEC_PROP_NAME)
if (scanSpec == null) {
logger.debug("scanSpec not set, not scanning for Custom Serializers")
emptyList()
} else {
logger.debug("scanSpec = \"$scanSpec\", scanning for Custom Serializers")
scanClasspathForSerializers(scanSpec)
}
}
@StubOutForDJVM
private fun scanClasspathForSerializers(scanSpec: String): List<SerializationCustomSerializer<*, *>> =
this::class.java.classLoader.let { cl ->
ClassGraph()
.whitelistPackages(scanSpec)
.addClassLoader(cl)
.enableAllInfo()
.pooledScan()
.use {
val serializerClass = SerializationCustomSerializer::class.java
it.getClassesImplementing(serializerClass.name).loadClasses(serializerClass)
}
.filterNot { it.isAbstractClass }
.map { it.kotlin.objectOrNewInstance() }
}
private val serializationWhitelists: List<SerializationWhitelist> by lazy { listOf(DefaultWhitelist) }
@DeleteForDJVM
val List<Cordapp>.customSerializers
@ -140,26 +102,16 @@ abstract class AbstractAMQPSerializationScheme(
registerNonDeterministicSerializers(factory)
}
// If we're passed in an external list we trust that, otherwise revert to looking at the scan of the
// classpath to find custom serializers.
if (cordappCustomSerializers.isEmpty()) {
for (customSerializer in customSerializers) {
factory.registerExternal(CorDappCustomSerializer(customSerializer, factory))
}
} else {
// This step is registering custom serializers, which have been added after node initialisation (i.e. via attachments during transaction verification).
// Note: the order between the registration of customSerializers and cordappCustomSerializers must be preserved as-is. The reason is the following:
// Currently, the serialization infrastructure does not support multiple versions of a class (the first one that is registered dominates).
// As a result, when inside a context with attachments class loader, we prioritize serializers loaded on-demand from attachments to serializers that had been
// loaded during node initialisation, by scanning the cordapps folder.
context.customSerializers.forEach { customSerializer ->
factory.registerExternal(CorDappCustomSerializer(customSerializer, factory))
}
logger.debug("Custom Serializer list loaded - not scanning classpath")
cordappCustomSerializers.forEach { customSerializer ->
factory.registerExternal(CorDappCustomSerializer(customSerializer, factory))
}
// This step is registering custom serializers, which have been added after node initialisation (i.e. via attachments during transaction verification).
// Note: the order between the registration of customSerializers and cordappCustomSerializers must be preserved as-is. The reason is the following:
// Currently, the serialization infrastructure does not support multiple versions of a class (the first one that is registered dominates).
// As a result, when inside a context with attachments class loader, we prioritize serializers loaded on-demand from attachments to serializers that had been
// loaded during node initialisation, by scanning the cordapps folder.
context.customSerializers.forEach { customSerializer ->
factory.registerExternal(CorDappCustomSerializer(customSerializer, factory))
}
cordappCustomSerializers.forEach { customSerializer ->
factory.registerExternal(CorDappCustomSerializer(customSerializer, factory))
}
context.properties[ContextPropertyKeys.SERIALIZERS]?.apply {

View File

@ -802,7 +802,7 @@ class DriverDSLImpl(
)
}
private val propertiesInScope = setOf("java.io.tmpdir", AbstractAMQPSerializationScheme.SCAN_SPEC_PROP_NAME)
private val propertiesInScope = setOf("java.io.tmpdir")
private fun inheritFromParentProcess(): Iterable<Pair<String, String>> {
return propertiesInScope.flatMap { propName ->