CORDA-553 - Remove CordaCustomSerializer annotation

It isn't actually needed as we can scan the jar for classes implementing
the interface.
This commit is contained in:
Katelyn Baker
2017-12-04 17:56:27 +00:00
parent c4d5d3817c
commit 8878fa99a0
16 changed files with 28 additions and 53 deletions

View File

@ -37,7 +37,7 @@ interface Cordapp {
val schedulableFlows: List<Class<out FlowLogic<*>>> val schedulableFlows: List<Class<out FlowLogic<*>>>
val services: List<Class<out SerializeAsToken>> val services: List<Class<out SerializeAsToken>>
val serializationWhitelists: List<SerializationWhitelist> val serializationWhitelists: List<SerializationWhitelist>
val serializationCustomSerializers: List<Class<out SerializationCustomSerializer<*, *>>> val serializationCustomSerializers: List<SerializationCustomSerializer<*, *>>
val customSchemas: Set<MappedSchema> val customSchemas: Set<MappedSchema>
val jarPath: URL val jarPath: URL
val cordappClasses: List<String> val cordappClasses: List<String>

View File

@ -17,7 +17,7 @@ data class CordappImpl(
override val schedulableFlows: List<Class<out FlowLogic<*>>>, override val schedulableFlows: List<Class<out FlowLogic<*>>>,
override val services: List<Class<out SerializeAsToken>>, override val services: List<Class<out SerializeAsToken>>,
override val serializationWhitelists: List<SerializationWhitelist>, override val serializationWhitelists: List<SerializationWhitelist>,
override val serializationCustomSerializers: List<Class<out SerializationCustomSerializer<*, *>>>, override val serializationCustomSerializers: List<SerializationCustomSerializer<*, *>>,
override val customSchemas: Set<MappedSchema>, override val customSchemas: Set<MappedSchema>,
override val jarPath: URL) : Cordapp { override val jarPath: URL) : Cordapp {
override val name: String = File(jarPath.toURI()).name.removeSuffix(".jar") override val name: String = File(jarPath.toURI()).name.removeSuffix(".jar")

View File

@ -1,10 +0,0 @@
package net.corda.core.serialization
/**
* This annotation marks a class as being a serializer provided by a CorDapp to proxy some third party
* class Corda couldn't otherwise serialize. It should be applied to classes that implement the
* [SerializationCustomSerializer] interface
*/
@Target(AnnotationTarget.CLASS)
annotation class CordaCustomSerializer

View File

@ -1,27 +1,18 @@
package net.corda.core.serialization package net.corda.core.serialization
import java.lang.reflect.Type
/** /**
* Allows CorDapps to provide custom serializers for third party libraries where those libraries cannot * Allows CorDapps to provide custom serializers for third party libraries where those libraries cannot
* be recompiled with the -parmater flag rendering their classes natively serializable by Corda. In this case * be recompiled with the -parameters flag rendering their classes natively serializable by Corda. In this case
* a proxy serializer can be written that extends this type whose purpose is to move between those an * a proxy serializer can be written that extends this type whose purpose is to move between those an
* unserializable types and an intermediate representation * unserializable types and an intermediate representation.
* *
* NOTE: The proxy object must be specified as a seperate class. However, this can be defined within the * NOTE: The proxy object must should be specified as a seperate class. However, this can be defined within the
* scope of the serializer. Also, that class must be annotated with the [CordaCustomSerializerProxy] * scope of the custom serializer.
* annotation
*
* For instances of this class to be discoverable they must be annotated with the [CordaCustomSerializer]
* annotation.
*
* Failing to apply either annotation will result in the class not being loaded by Corda and thus serialization
* failing
*/ */
interface SerializationCustomSerializer<OBJ, PROXY> { interface SerializationCustomSerializer<OBJ, PROXY> {
/** /**
* Should facilitate the conversion of the third party object into the serializable * Should facilitate the conversion of the third party object into the serializable
* local class specified by [ptype] * local class specified by [PROXY]
*/ */
fun toProxy(obj: OBJ) : PROXY fun toProxy(obj: OBJ) : PROXY

View File

@ -3,7 +3,7 @@ Pluggable Serializers for CorDapps
.. contents:: .. contents::
To be serializable by Corda Java classes must be compiled with the -parameters switch to enable matching of it's properties To be serializable by Corda Java classes must be compiled with the -parameters switch to enable matching of its properties
to constructor parameters. This is important because Corda's internal AMQP serialization scheme will only construct to constructor parameters. This is important because Corda's internal AMQP serialization scheme will only construct
objects using their constructors. However, when recompilation isn't possible, or classes are built in such a way that objects using their constructors. However, when recompilation isn't possible, or classes are built in such a way that
they cannot be easily modified for simple serialization, CorDapps can provide custom proxy serializers that Corda they cannot be easily modified for simple serialization, CorDapps can provide custom proxy serializers that Corda
@ -18,11 +18,10 @@ Writing a Custom Serializer
--------------------------- ---------------------------
Serializers must Serializers must
* Inherit from net.corda.core.serialization.SerializationCustomSerializer * Inherit from net.corda.core.serialization.SerializationCustomSerializer
* Be annotated with the @CordaCustomSerializer annotation
* Provide a proxy class to transform the object to and from * Provide a proxy class to transform the object to and from
* Implmenet the ``toProxy`` and ``fromProxy`` methods * Implement the ``toProxy`` and ``fromProxy`` methods
Serializers inheriting from SerializationCustomSerializer have to implement two methods and two types Serializers inheriting from SerializationCustomSerializer have to implement two methods and two types.
Example Example
------- -------
@ -47,13 +46,12 @@ Consider this example class
} }
Without a custom serializer we cannot serialize this class as there is no public constructor that facilitates the Without a custom serializer we cannot serialize this class as there is no public constructor that facilitates the
initialisation of all of it's properties. initialisation of all of its properties.
To be serializable by Corda this would require a custom serializer as follows To be serializable by Corda this would require a custom serializer as follows:
.. sourcecode:: kotlin .. sourcecode:: kotlin
@CordaCustomSerializer
class ExampleSerializer : SerializationCustomSerializer<Example, ExampleSerializer.Proxy> { class ExampleSerializer : SerializationCustomSerializer<Example, ExampleSerializer.Proxy> {
data class Proxy(val a: Int, val b: Int) data class Proxy(val a: Int, val b: Int)

View File

@ -18,11 +18,11 @@ AMQP Serialization is now enabled for both peer to peer communication and writin
brings a stable format Corda can support internally throughout it's lifetime that meets the needs of Corda and our brings a stable format Corda can support internally throughout it's lifetime that meets the needs of Corda and our
users. users.
* **CorDapp Custom Serializers** * **Custom Serializers**
To allow interop with third party libraries that cannot be recompiled we add functionality that allows custom serialises To allow interop with third party libraries that cannot be recompiled we add functionality that allows custom serializers
to be written for those classes provided. If needed, a proxy object can be created as an interim step that allows Corda's internal to be written for those classes. If needed, a proxy object can be created as an interim step that allows Corda's internal
serialisers to operate on those types. serializers to operate on those types.
A good example of this is the SIMM valuation demo which has a number of such serializers defined in the plugin/customserializers package A good example of this is the SIMM valuation demo which has a number of such serializers defined in the plugin/customserializers package

View File

@ -70,7 +70,7 @@ abstract class AbstractAMQPSerializationScheme(val cordappLoader: List<Cordapp>)
cordappLoader.forEach { ca -> cordappLoader.forEach { ca ->
ca.serializationCustomSerializers.forEach { ca.serializationCustomSerializers.forEach {
factory.registerExternal(CorDappCustomSerializer(it.newInstance(), factory)) factory.registerExternal(CorDappCustomSerializer(it, factory))
} }
} }
} }

View File

@ -1,7 +1,6 @@
package net.corda.nodeapi.internal.serialization.amqp package net.corda.nodeapi.internal.serialization.amqp
import org.junit.Test import org.junit.Test
import net.corda.core.serialization.CordaCustomSerializer
import net.corda.core.serialization.ClassWhitelist import net.corda.core.serialization.ClassWhitelist
import net.corda.core.serialization.SerializationCustomSerializer import net.corda.core.serialization.SerializationCustomSerializer
import org.assertj.core.api.Assertions import org.assertj.core.api.Assertions
@ -11,7 +10,6 @@ import kotlin.test.assertEquals
class CorDappSerializerTests { class CorDappSerializerTests {
data class NeedsProxy (val a: String) data class NeedsProxy (val a: String)
@CordaCustomSerializer
class NeedsProxyProxySerializer : SerializationCustomSerializer<NeedsProxy, NeedsProxyProxySerializer.Proxy> { class NeedsProxyProxySerializer : SerializationCustomSerializer<NeedsProxy, NeedsProxyProxySerializer.Proxy> {
data class Proxy(val proxy_a_: String) data class Proxy(val proxy_a_: String)

View File

@ -248,8 +248,9 @@ class CordappLoader private constructor(private val cordappJarPaths: List<Restri
} + DefaultWhitelist // Always add the DefaultWhitelist to the whitelist for an app. } + DefaultWhitelist // Always add the DefaultWhitelist to the whitelist for an app.
} }
private fun findSerialzers(scanResult: RestrictedScanResult) : List<Class<out SerializationCustomSerializer<*, *>>> { private fun findSerialzers(scanResult: RestrictedScanResult) : List<SerializationCustomSerializer<*, *>> {
return scanResult.getClassesWithAnnotation(SerializationCustomSerializer::class, CordaCustomSerializer::class) // return scanResult.getClassesWithAnnotation(SerializationCustomSerializer::class, CordaCustomSerializer::class)
return scanResult.getClassesImplementing(SerializationCustomSerializer::class)
} }
private fun findCustomSchemas(scanResult: RestrictedScanResult): Set<MappedSchema> { private fun findCustomSchemas(scanResult: RestrictedScanResult): Set<MappedSchema> {
@ -308,6 +309,14 @@ class CordappLoader private constructor(private val cordappJarPaths: List<Restri
.map { it.kotlin.objectOrNewInstance() } .map { it.kotlin.objectOrNewInstance() }
} }
fun <T : Any> getClassesImplementing(type: KClass<T>): List<T> {
return scanResult.getNamesOfClassesImplementing(type.java)
.filter { it.startsWith(qualifiedNamePrefix) }
.mapNotNull { loadClass(it, type) }
.filterNot { Modifier.isAbstract(it.modifiers) }
.map { it.kotlin.objectOrNewInstance() }
}
fun <T : Any> getClassesWithAnnotation(type: KClass<T>, annotation: KClass<out Annotation>): List<Class<out T>> { fun <T : Any> getClassesWithAnnotation(type: KClass<T>, annotation: KClass<out Annotation>): List<Class<out T>> {
return scanResult.getNamesOfClassesWithAnnotation(annotation.java) return scanResult.getNamesOfClassesWithAnnotation(annotation.java)
.filter { it.startsWith(qualifiedNamePrefix) } .filter { it.startsWith(qualifiedNamePrefix) }

View File

@ -2,10 +2,8 @@ package net.corda.vega.plugin.customserializers
import com.opengamma.strata.market.param.CurrencyParameterSensitivities import com.opengamma.strata.market.param.CurrencyParameterSensitivities
import com.opengamma.strata.market.param.CurrencyParameterSensitivity import com.opengamma.strata.market.param.CurrencyParameterSensitivity
import net.corda.core.serialization.CordaCustomSerializer
import net.corda.core.serialization.SerializationCustomSerializer import net.corda.core.serialization.SerializationCustomSerializer
@CordaCustomSerializer
@Suppress("UNUSED") @Suppress("UNUSED")
class CurrencyParameterSensitivitiesSerializer : class CurrencyParameterSensitivitiesSerializer :
SerializationCustomSerializer<CurrencyParameterSensitivities, CurrencyParameterSensitivitiesSerializer.Proxy> { SerializationCustomSerializer<CurrencyParameterSensitivities, CurrencyParameterSensitivitiesSerializer.Proxy> {

View File

@ -5,10 +5,8 @@ import com.opengamma.strata.market.param.ParameterMetadata
import com.opengamma.strata.data.MarketDataName import com.opengamma.strata.data.MarketDataName
import com.opengamma.strata.collect.array.DoubleArray import com.opengamma.strata.collect.array.DoubleArray
import com.opengamma.strata.basics.currency.Currency import com.opengamma.strata.basics.currency.Currency
import net.corda.core.serialization.CordaCustomSerializer
import net.corda.core.serialization.SerializationCustomSerializer import net.corda.core.serialization.SerializationCustomSerializer
@CordaCustomSerializer
@Suppress("UNUSED") @Suppress("UNUSED")
class CurrencyParameterSensitivitySerializer : class CurrencyParameterSensitivitySerializer :
SerializationCustomSerializer<CurrencyParameterSensitivity, CurrencyParameterSensitivitySerializer.Proxy> { SerializationCustomSerializer<CurrencyParameterSensitivity, CurrencyParameterSensitivitySerializer.Proxy> {

View File

@ -1,10 +1,8 @@
package net.corda.vega.plugin.customserializers package net.corda.vega.plugin.customserializers
import com.opengamma.strata.basics.currency.Currency import com.opengamma.strata.basics.currency.Currency
import net.corda.core.serialization.CordaCustomSerializer
import net.corda.core.serialization.SerializationCustomSerializer import net.corda.core.serialization.SerializationCustomSerializer
@CordaCustomSerializer
@Suppress("UNUSED") @Suppress("UNUSED")
class CurrencySerializer : SerializationCustomSerializer<Currency, CurrencySerializer.Proxy> { class CurrencySerializer : SerializationCustomSerializer<Currency, CurrencySerializer.Proxy> {
data class Proxy(val currency: String) data class Proxy(val currency: String)

View File

@ -1,10 +1,8 @@
package net.corda.vega.plugin.customserializers package net.corda.vega.plugin.customserializers
import net.corda.core.serialization.CordaCustomSerializer
import net.corda.core.serialization.SerializationCustomSerializer import net.corda.core.serialization.SerializationCustomSerializer
import com.opengamma.strata.collect.array.DoubleArray import com.opengamma.strata.collect.array.DoubleArray
@CordaCustomSerializer
@Suppress("UNUSED") @Suppress("UNUSED")
class DoubleArraySerializer : SerializationCustomSerializer<DoubleArray, DoubleArraySerializer.Proxy> { class DoubleArraySerializer : SerializationCustomSerializer<DoubleArray, DoubleArraySerializer.Proxy> {
data class Proxy(val amount: kotlin.DoubleArray) data class Proxy(val amount: kotlin.DoubleArray)

View File

@ -4,7 +4,6 @@ import com.opengamma.strata.basics.currency.MultiCurrencyAmount
import com.opengamma.strata.basics.currency.Currency import com.opengamma.strata.basics.currency.Currency
import net.corda.core.serialization.* import net.corda.core.serialization.*
@CordaCustomSerializer
@Suppress("UNUSED") @Suppress("UNUSED")
class MultiCurrencyAmountSerializer : class MultiCurrencyAmountSerializer :
SerializationCustomSerializer<MultiCurrencyAmount, MultiCurrencyAmountSerializer.Proxy> { SerializationCustomSerializer<MultiCurrencyAmount, MultiCurrencyAmountSerializer.Proxy> {

View File

@ -5,7 +5,6 @@ import com.opengamma.strata.market.param.TenorDateParameterMetadata
import net.corda.core.serialization.* import net.corda.core.serialization.*
import java.time.LocalDate import java.time.LocalDate
@CordaCustomSerializer
@Suppress("UNUSED") @Suppress("UNUSED")
class TenorDateParameterMetadataSerializer : class TenorDateParameterMetadataSerializer :
SerializationCustomSerializer<TenorDateParameterMetadata, TenorDateParameterMetadataSerializer.Proxy> { SerializationCustomSerializer<TenorDateParameterMetadata, TenorDateParameterMetadataSerializer.Proxy> {

View File

@ -4,7 +4,6 @@ import com.opengamma.strata.basics.date.Tenor
import net.corda.core.serialization.* import net.corda.core.serialization.*
import java.time.Period import java.time.Period
@CordaCustomSerializer
@Suppress("UNUSED") @Suppress("UNUSED")
class TenorSerializer : SerializationCustomSerializer<Tenor, TenorSerializer.Proxy> { class TenorSerializer : SerializationCustomSerializer<Tenor, TenorSerializer.Proxy> {
data class Proxy(val years: Int, val months: Int, val days: Int, val name: String) data class Proxy(val years: Int, val months: Int, val days: Int, val name: String)