mirror of
https://github.com/corda/corda.git
synced 2025-06-19 15:43:52 +00:00
CORDA-1603: Class carpenter able to synthesis Cash.State objects (#3400)
This requires the class carpenter to be able to run in a "lenient" mode where it permits synthesised classes to implement interfaces with unimplemented methods.
This commit is contained in:
@ -50,7 +50,7 @@ class AMQPClientSerializationScheme(
|
|||||||
target == SerializationContext.UseCase.RPCClient || target == SerializationContext.UseCase.P2P)
|
target == SerializationContext.UseCase.RPCClient || target == SerializationContext.UseCase.P2P)
|
||||||
|
|
||||||
override fun rpcClientSerializerFactory(context: SerializationContext): SerializerFactory {
|
override fun rpcClientSerializerFactory(context: SerializationContext): SerializerFactory {
|
||||||
return SerializerFactory(context.whitelist, ClassLoader.getSystemClassLoader()).apply {
|
return SerializerFactory(context.whitelist, ClassLoader.getSystemClassLoader(), context.lenientCarpenterEnabled).apply {
|
||||||
register(RpcClientObservableSerializer)
|
register(RpcClientObservableSerializer)
|
||||||
register(RpcClientCordaFutureSerializer(this))
|
register(RpcClientCordaFutureSerializer(this))
|
||||||
register(RxNotificationSerializer(this))
|
register(RxNotificationSerializer(this))
|
||||||
|
@ -142,6 +142,14 @@ interface SerializationContext {
|
|||||||
* otherwise they appear as new copies of the object.
|
* otherwise they appear as new copies of the object.
|
||||||
*/
|
*/
|
||||||
val objectReferencesEnabled: Boolean
|
val objectReferencesEnabled: Boolean
|
||||||
|
/**
|
||||||
|
* If true the carpenter will happily synthesis classes that implement interfaces containing methods that are not
|
||||||
|
* getters for any AMQP fields. Invoking these methods will throw an [AbstractMethodError]. If false then an exception
|
||||||
|
* will be thrown during deserialization instead.
|
||||||
|
*
|
||||||
|
* The default is false.
|
||||||
|
*/
|
||||||
|
val lenientCarpenterEnabled: Boolean
|
||||||
/**
|
/**
|
||||||
* The use case we are serializing or deserializing for. See [UseCase].
|
* The use case we are serializing or deserializing for. See [UseCase].
|
||||||
*/
|
*/
|
||||||
@ -157,6 +165,12 @@ interface SerializationContext {
|
|||||||
*/
|
*/
|
||||||
fun withoutReferences(): SerializationContext
|
fun withoutReferences(): SerializationContext
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a new context based on this one but with a lenient carpenter.
|
||||||
|
* @see lenientCarpenterEnabled
|
||||||
|
*/
|
||||||
|
fun withLenientCarpenter(): SerializationContext
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to return a new context based on this context with the deserialization class loader changed.
|
* Helper method to return a new context based on this context with the deserialization class loader changed.
|
||||||
*/
|
*/
|
||||||
|
@ -7,6 +7,10 @@ release, see :doc:`upgrade-notes`.
|
|||||||
Unreleased
|
Unreleased
|
||||||
----------
|
----------
|
||||||
|
|
||||||
|
* The class carpenter has a "lenient" mode where it will, during deserialisation, happily synthesis classes that implement
|
||||||
|
interfaces that will have unimplemented methods. This is useful, for example, for object viewers. This can be turned on
|
||||||
|
with ``SerializationContext.withLenientCarpenter``.
|
||||||
|
|
||||||
* Introduced a grace period before the initial node registration fails if the node cannot connect to the Doorman.
|
* Introduced a grace period before the initial node registration fails if the node cannot connect to the Doorman.
|
||||||
It retries 10 times with a 1 minute interval in between each try. At the moment this is not configurable.
|
It retries 10 times with a 1 minute interval in between each try. At the moment this is not configurable.
|
||||||
|
|
||||||
|
@ -557,6 +557,11 @@ without the supporting classes being present on the classpath. This can be usef
|
|||||||
be able to use reflection over the deserialized data, for scripting languages that run on the JVM, and also for
|
be able to use reflection over the deserialized data, for scripting languages that run on the JVM, and also for
|
||||||
ensuring classes not on the classpath can be deserialized without loading potentially malicious code.
|
ensuring classes not on the classpath can be deserialized without loading potentially malicious code.
|
||||||
|
|
||||||
|
If the original class implements some interfaces then the carpenter will make sure that all of the interface methods are
|
||||||
|
backed by feilds. If that's not the case then an exception will be thrown during deserialization. This check can
|
||||||
|
be turned off with ``SerializationContext.withLenientCarpenter``. This can be useful if only the field getters are needed,
|
||||||
|
say in an object viewer.
|
||||||
|
|
||||||
Possible future enhancements include:
|
Possible future enhancements include:
|
||||||
|
|
||||||
#. Java singleton support. We will add support for identifying classes which are singletons and identifying the
|
#. Java singleton support. We will add support for identifying classes which are singletons and identifying the
|
||||||
|
@ -26,15 +26,13 @@ class AMQPServerSerializationScheme(
|
|||||||
throw UnsupportedOperationException()
|
throw UnsupportedOperationException()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun rpcServerSerializerFactory(context: SerializationContext) =
|
override fun rpcServerSerializerFactory(context: SerializationContext): SerializerFactory {
|
||||||
SerializerFactory(
|
return SerializerFactory(context.whitelist, context.deserializationClassLoader, context.lenientCarpenterEnabled).apply {
|
||||||
context.whitelist,
|
|
||||||
context.deserializationClassLoader
|
|
||||||
).apply {
|
|
||||||
register(RpcServerObservableSerializer())
|
register(RpcServerObservableSerializer())
|
||||||
register(RpcServerCordaFutureSerializer(this))
|
register(RpcServerCordaFutureSerializer(this))
|
||||||
register(RxNotificationSerializer(this))
|
register(RxNotificationSerializer(this))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun canDeserializeVersion(magic: CordaSerializationMagic, target: SerializationContext.UseCase): Boolean {
|
override fun canDeserializeVersion(magic: CordaSerializationMagic, target: SerializationContext.UseCase): Boolean {
|
||||||
return canDeserializeVersion(magic) &&
|
return canDeserializeVersion(magic) &&
|
||||||
|
@ -30,7 +30,8 @@ data class SerializationContextImpl @JvmOverloads constructor(override val prefe
|
|||||||
override val objectReferencesEnabled: Boolean,
|
override val objectReferencesEnabled: Boolean,
|
||||||
override val useCase: SerializationContext.UseCase,
|
override val useCase: SerializationContext.UseCase,
|
||||||
override val encoding: SerializationEncoding?,
|
override val encoding: SerializationEncoding?,
|
||||||
override val encodingWhitelist: EncodingWhitelist = NullEncodingWhitelist) : SerializationContext {
|
override val encodingWhitelist: EncodingWhitelist = NullEncodingWhitelist,
|
||||||
|
override val lenientCarpenterEnabled: Boolean = false) : SerializationContext {
|
||||||
private val builder = AttachmentsClassLoaderBuilder(properties, deserializationClassLoader)
|
private val builder = AttachmentsClassLoaderBuilder(properties, deserializationClassLoader)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -52,6 +53,8 @@ data class SerializationContextImpl @JvmOverloads constructor(override val prefe
|
|||||||
return copy(objectReferencesEnabled = false)
|
return copy(objectReferencesEnabled = false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun withLenientCarpenter(): SerializationContext = copy(lenientCarpenterEnabled = true)
|
||||||
|
|
||||||
override fun withClassLoader(classLoader: ClassLoader): SerializationContext {
|
override fun withClassLoader(classLoader: ClassLoader): SerializationContext {
|
||||||
return copy(deserializationClassLoader = classLoader)
|
return copy(deserializationClassLoader = classLoader)
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import net.corda.core.serialization.SerializationContext
|
|||||||
fun createSerializerFactoryFactory(): SerializerFactoryFactory = SerializerFactoryFactoryImpl()
|
fun createSerializerFactoryFactory(): SerializerFactoryFactory = SerializerFactoryFactoryImpl()
|
||||||
|
|
||||||
open class SerializerFactoryFactoryImpl : SerializerFactoryFactory {
|
open class SerializerFactoryFactoryImpl : SerializerFactoryFactory {
|
||||||
override fun make(context: SerializationContext) =
|
override fun make(context: SerializationContext): SerializerFactory {
|
||||||
SerializerFactory(context.whitelist, context.deserializationClassLoader)
|
return SerializerFactory(context.whitelist, context.deserializationClassLoader, context.lenientCarpenterEnabled)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,8 @@ import net.corda.serialization.internal.amqp.SerializerFactory.Companion.nameFor
|
|||||||
import org.apache.qpid.proton.amqp.Symbol
|
import org.apache.qpid.proton.amqp.Symbol
|
||||||
import org.apache.qpid.proton.codec.Data
|
import org.apache.qpid.proton.codec.Data
|
||||||
import java.io.NotSerializableException
|
import java.io.NotSerializableException
|
||||||
|
import java.lang.reflect.Constructor
|
||||||
|
import java.lang.reflect.InvocationTargetException
|
||||||
import java.lang.reflect.Type
|
import java.lang.reflect.Type
|
||||||
import kotlin.reflect.jvm.javaConstructor
|
import kotlin.reflect.jvm.javaConstructor
|
||||||
|
|
||||||
@ -29,8 +31,7 @@ open class ObjectSerializer(val clazz: Type, factory: SerializerFactory) : AMQPS
|
|||||||
|
|
||||||
private val typeName = nameForType(clazz)
|
private val typeName = nameForType(clazz)
|
||||||
|
|
||||||
override val typeDescriptor = Symbol.valueOf(
|
override val typeDescriptor: Symbol = Symbol.valueOf("$DESCRIPTOR_DOMAIN:${factory.fingerPrinter.fingerprint(type)}")
|
||||||
"$DESCRIPTOR_DOMAIN:${factory.fingerPrinter.fingerprint(type)}")!!
|
|
||||||
|
|
||||||
// We restrict to only those annotated or whitelisted
|
// We restrict to only those annotated or whitelisted
|
||||||
private val interfaces = interfacesForSerialization(clazz, factory)
|
private val interfaces = interfacesForSerialization(clazz, factory)
|
||||||
@ -119,7 +120,7 @@ open class ObjectSerializer(val clazz: Type, factory: SerializerFactory) : AMQPS
|
|||||||
context: SerializationContext): Any = ifThrowsAppend({ clazz.typeName }) {
|
context: SerializationContext): Any = ifThrowsAppend({ clazz.typeName }) {
|
||||||
logger.trace { "Calling setter based construction for ${clazz.typeName}" }
|
logger.trace { "Calling setter based construction for ${clazz.typeName}" }
|
||||||
|
|
||||||
val instance: Any = javaConstructor?.newInstance() ?: throw NotSerializableException(
|
val instance: Any = javaConstructor?.newInstanceUnwrapped() ?: throw NotSerializableException(
|
||||||
"Failed to instantiate instance of object $clazz")
|
"Failed to instantiate instance of object $clazz")
|
||||||
|
|
||||||
// read the properties out of the serialised form, since we're invoking the setters the order we
|
// read the properties out of the serialised form, since we're invoking the setters the order we
|
||||||
@ -153,7 +154,15 @@ open class ObjectSerializer(val clazz: Type, factory: SerializerFactory) : AMQPS
|
|||||||
+ "serialized properties.")
|
+ "serialized properties.")
|
||||||
}
|
}
|
||||||
|
|
||||||
return javaConstructor?.newInstance(*properties.toTypedArray())
|
return javaConstructor?.newInstanceUnwrapped(*properties.toTypedArray())
|
||||||
?: throw NotSerializableException("Attempt to deserialize an interface: $clazz. Serialized form is invalid.")
|
?: throw NotSerializableException("Attempt to deserialize an interface: $clazz. Serialized form is invalid.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun <T> Constructor<T>.newInstanceUnwrapped(vararg args: Any?): T {
|
||||||
|
try {
|
||||||
|
return newInstance(*args)
|
||||||
|
} catch (e: InvocationTargetException) {
|
||||||
|
throw e.cause!!
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -8,6 +8,7 @@ import net.corda.core.StubOutForDJVM
|
|||||||
import net.corda.core.internal.kotlinObjectInstance
|
import net.corda.core.internal.kotlinObjectInstance
|
||||||
import net.corda.core.internal.uncheckedCast
|
import net.corda.core.internal.uncheckedCast
|
||||||
import net.corda.core.serialization.ClassWhitelist
|
import net.corda.core.serialization.ClassWhitelist
|
||||||
|
import net.corda.core.utilities.contextLogger
|
||||||
import net.corda.core.utilities.debug
|
import net.corda.core.utilities.debug
|
||||||
import net.corda.core.utilities.loggerFor
|
import net.corda.core.utilities.loggerFor
|
||||||
import net.corda.core.utilities.trace
|
import net.corda.core.utilities.trace
|
||||||
@ -53,40 +54,43 @@ open class SerializerFactory(
|
|||||||
private val serializersByType: MutableMap<Type, AMQPSerializer<Any>>,
|
private val serializersByType: MutableMap<Type, AMQPSerializer<Any>>,
|
||||||
val serializersByDescriptor: MutableMap<Any, AMQPSerializer<Any>>,
|
val serializersByDescriptor: MutableMap<Any, AMQPSerializer<Any>>,
|
||||||
private val customSerializers: MutableList<SerializerFor>,
|
private val customSerializers: MutableList<SerializerFor>,
|
||||||
val transformsCache: MutableMap<String, EnumMap<TransformTypes, MutableList<Transform>>>) {
|
val transformsCache: MutableMap<String, EnumMap<TransformTypes, MutableList<Transform>>>
|
||||||
|
) {
|
||||||
@DeleteForDJVM
|
@DeleteForDJVM
|
||||||
constructor(whitelist: ClassWhitelist,
|
constructor(whitelist: ClassWhitelist,
|
||||||
classCarpenter: ClassCarpenter,
|
classCarpenter: ClassCarpenter,
|
||||||
evolutionSerializerGetter: EvolutionSerializerGetterBase = EvolutionSerializerGetter(),
|
evolutionSerializerGetter: EvolutionSerializerGetterBase = EvolutionSerializerGetter(),
|
||||||
fingerPrinter: FingerPrinter = SerializerFingerPrinter()
|
fingerPrinter: FingerPrinter = SerializerFingerPrinter()
|
||||||
) : this(whitelist, classCarpenter, evolutionSerializerGetter, fingerPrinter,
|
) : this(
|
||||||
serializersByType = ConcurrentHashMap(),
|
whitelist,
|
||||||
serializersByDescriptor = ConcurrentHashMap(),
|
classCarpenter,
|
||||||
customSerializers = CopyOnWriteArrayList(),
|
evolutionSerializerGetter,
|
||||||
transformsCache = ConcurrentHashMap())
|
fingerPrinter,
|
||||||
|
ConcurrentHashMap(),
|
||||||
|
ConcurrentHashMap(),
|
||||||
|
CopyOnWriteArrayList(),
|
||||||
|
ConcurrentHashMap()
|
||||||
|
)
|
||||||
|
|
||||||
@DeleteForDJVM
|
@DeleteForDJVM
|
||||||
constructor(whitelist: ClassWhitelist,
|
constructor(whitelist: ClassWhitelist,
|
||||||
classLoader: ClassLoader,
|
classLoader: ClassLoader,
|
||||||
|
lenientCarpenter: Boolean = false,
|
||||||
evolutionSerializerGetter: EvolutionSerializerGetterBase = EvolutionSerializerGetter(),
|
evolutionSerializerGetter: EvolutionSerializerGetterBase = EvolutionSerializerGetter(),
|
||||||
fingerPrinter: FingerPrinter = SerializerFingerPrinter()
|
fingerPrinter: FingerPrinter = SerializerFingerPrinter()
|
||||||
) : this(whitelist, ClassCarpenterImpl(classLoader, whitelist), evolutionSerializerGetter, fingerPrinter,
|
) : this(whitelist, ClassCarpenterImpl(classLoader, whitelist, lenientCarpenter), evolutionSerializerGetter, fingerPrinter)
|
||||||
serializersByType = ConcurrentHashMap(),
|
|
||||||
serializersByDescriptor = ConcurrentHashMap(),
|
|
||||||
customSerializers = CopyOnWriteArrayList(),
|
|
||||||
transformsCache = ConcurrentHashMap())
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
fingerPrinter.setOwner(this)
|
fingerPrinter.setOwner(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
val classloader: ClassLoader
|
val classloader: ClassLoader get() = classCarpenter.classloader
|
||||||
get() = classCarpenter.classloader
|
|
||||||
|
|
||||||
private fun getEvolutionSerializer(typeNotation: TypeNotation, newSerializer: AMQPSerializer<Any>,
|
private fun getEvolutionSerializer(typeNotation: TypeNotation,
|
||||||
schemas: SerializationSchemas) = evolutionSerializerGetter.getEvolutionSerializer(this, typeNotation, newSerializer, schemas)
|
newSerializer: AMQPSerializer<Any>,
|
||||||
|
schemas: SerializationSchemas): AMQPSerializer<Any> {
|
||||||
private val logger = loggerFor<SerializerFactory>()
|
return evolutionSerializerGetter.getEvolutionSerializer(this, typeNotation, newSerializer, schemas)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Look up, and manufacture if necessary, a serializer for the given type.
|
* Look up, and manufacture if necessary, a serializer for the given type.
|
||||||
@ -380,6 +384,8 @@ open class SerializerFactory(
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
private val logger = contextLogger()
|
||||||
|
|
||||||
fun isPrimitive(type: Type): Boolean = primitiveTypeName(type) != null
|
fun isPrimitive(type: Type): Boolean = primitiveTypeName(type) != null
|
||||||
|
|
||||||
fun primitiveTypeName(type: Type): String? {
|
fun primitiveTypeName(type: Type): String? {
|
||||||
@ -469,4 +475,3 @@ open class SerializerFactory(
|
|||||||
override fun toString(): String = "?"
|
override fun toString(): String = "?"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ fun CompositeType.carpenterSchema(classloader: ClassLoader,
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
providesList.add(classloader.loadClass(it))
|
providesList.add(classloader.loadClass(it.stripGenerics()))
|
||||||
} catch (e: ClassNotFoundException) {
|
} catch (e: ClassNotFoundException) {
|
||||||
carpenterSchemas.addDepPair(this, name, it)
|
carpenterSchemas.addDepPair(this, name, it)
|
||||||
isCreatable = false
|
isCreatable = false
|
||||||
|
@ -6,6 +6,8 @@ import net.corda.core.DeleteForDJVM
|
|||||||
import net.corda.core.KeepForDJVM
|
import net.corda.core.KeepForDJVM
|
||||||
import net.corda.core.serialization.ClassWhitelist
|
import net.corda.core.serialization.ClassWhitelist
|
||||||
import net.corda.core.serialization.CordaSerializable
|
import net.corda.core.serialization.CordaSerializable
|
||||||
|
import net.corda.core.utilities.contextLogger
|
||||||
|
import net.corda.core.utilities.debug
|
||||||
import org.objectweb.asm.ClassWriter
|
import org.objectweb.asm.ClassWriter
|
||||||
import org.objectweb.asm.MethodVisitor
|
import org.objectweb.asm.MethodVisitor
|
||||||
import org.objectweb.asm.Opcodes.*
|
import org.objectweb.asm.Opcodes.*
|
||||||
@ -102,8 +104,9 @@ interface ClassCarpenter {
|
|||||||
* Equals/hashCode methods are not yet supported.
|
* Equals/hashCode methods are not yet supported.
|
||||||
*/
|
*/
|
||||||
@DeleteForDJVM
|
@DeleteForDJVM
|
||||||
class ClassCarpenterImpl(cl: ClassLoader, override val whitelist: ClassWhitelist) : ClassCarpenter {
|
class ClassCarpenterImpl(cl: ClassLoader = Thread.currentThread().contextClassLoader,
|
||||||
constructor(whitelist: ClassWhitelist) : this(Thread.currentThread().contextClassLoader, whitelist)
|
override val whitelist: ClassWhitelist,
|
||||||
|
private val lenient: Boolean = false) : ClassCarpenter {
|
||||||
|
|
||||||
// TODO: Generics.
|
// TODO: Generics.
|
||||||
// TODO: Sandbox the generated code when a security manager is in use.
|
// TODO: Sandbox the generated code when a security manager is in use.
|
||||||
@ -439,25 +442,36 @@ class ClassCarpenterImpl(cl: ClassLoader, override val whitelist: ClassWhitelist
|
|||||||
// actually called, which is a bit too dynamic for my tastes.
|
// actually called, which is a bit too dynamic for my tastes.
|
||||||
val allFields = schema.fieldsIncludingSuperclasses()
|
val allFields = schema.fieldsIncludingSuperclasses()
|
||||||
for (itf in schema.interfaces) {
|
for (itf in schema.interfaces) {
|
||||||
itf.methods.forEach {
|
methodLoop@
|
||||||
val fieldNameFromItf = when {
|
for (method in itf.methods) {
|
||||||
it.name.startsWith("get") -> it.name.substring(3).decapitalize()
|
val fieldNameFromItf = if (method.name.startsWith("get")) {
|
||||||
else -> throw InterfaceMismatchNonGetterException(itf, it)
|
method.name.substring(3).decapitalize()
|
||||||
|
} else if (lenient) {
|
||||||
|
logger.debug { "Ignoring interface $method which is not a getter" }
|
||||||
|
continue@methodLoop
|
||||||
|
} else {
|
||||||
|
throw InterfaceMismatchNonGetterException(itf, method)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're trying to carpent a class that prior to serialisation / deserialization
|
// If we're trying to carpent a class that prior to serialisation / deserialization
|
||||||
// was made by a carpenter then we can ignore this (it will implement a plain get
|
// was made by a carpenter then we can ignore this (it will implement a plain get
|
||||||
// method from SimpleFieldAccess).
|
// method from SimpleFieldAccess).
|
||||||
if (fieldNameFromItf.isEmpty() && SimpleFieldAccess::class.java in schema.interfaces) return@forEach
|
if (fieldNameFromItf.isEmpty() && SimpleFieldAccess::class.java in schema.interfaces) continue@methodLoop
|
||||||
|
|
||||||
if ((schema is ClassSchema) and (fieldNameFromItf !in allFields)) {
|
if ((schema is ClassSchema) and (fieldNameFromItf !in allFields)) {
|
||||||
|
if (lenient) {
|
||||||
|
logger.debug { "Ignoring interface $method which is not backed by an AMQP field" }
|
||||||
|
} else {
|
||||||
throw InterfaceMismatchMissingAMQPFieldException(itf, fieldNameFromItf)
|
throw InterfaceMismatchMissingAMQPFieldException(itf, fieldNameFromItf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
private val logger = contextLogger()
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@Suppress("UNUSED")
|
@Suppress("UNUSED")
|
||||||
fun getField(obj: Any, name: String): Any? = obj.javaClass.getMethod("get" + name.capitalize()).invoke(obj)
|
fun getField(obj: Any, name: String): Any? = obj.javaClass.getMethod("get" + name.capitalize()).invoke(obj)
|
||||||
|
@ -8,6 +8,9 @@ import org.junit.Test;
|
|||||||
|
|
||||||
import java.io.NotSerializableException;
|
import java.io.NotSerializableException;
|
||||||
|
|
||||||
|
import static net.corda.serialization.internal.amqp.testutils.AMQPTestUtilsKt.testDefaultFactory;
|
||||||
|
import static org.assertj.core.api.Assertions.*;
|
||||||
|
|
||||||
@Ignore("Current behaviour allows for the serialization of objects with private members, this will be disallowed at some point in the future")
|
@Ignore("Current behaviour allows for the serialization of objects with private members, this will be disallowed at some point in the future")
|
||||||
public class ErrorMessageTests {
|
public class ErrorMessageTests {
|
||||||
private String errMsg(String property, String testname) {
|
private String errMsg(String property, String testname) {
|
||||||
@ -32,19 +35,10 @@ public class ErrorMessageTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testJavaConstructorAnnotations() {
|
public void testJavaConstructorAnnotations() {
|
||||||
EvolutionSerializerGetterBase evolutionSerialiserGetter = new EvolutionSerializerGetter();
|
SerializationOutput ser = new SerializationOutput(testDefaultFactory());
|
||||||
FingerPrinter fingerPrinter = new SerializerFingerPrinter();
|
|
||||||
SerializerFactory factory1 = new SerializerFactory(
|
|
||||||
AllWhitelist.INSTANCE,
|
|
||||||
ClassLoader.getSystemClassLoader(),
|
|
||||||
evolutionSerialiserGetter,
|
|
||||||
fingerPrinter);
|
|
||||||
|
|
||||||
SerializationOutput ser = new SerializationOutput(factory1);
|
assertThatThrownBy(() -> ser.serialize(new C(1), TestSerializationContext.testSerializationContext))
|
||||||
|
|
||||||
Assertions.assertThatThrownBy(() -> ser.serialize(new C(1), TestSerializationContext.testSerializationContext))
|
|
||||||
.isInstanceOf(NotSerializableException.class)
|
.isInstanceOf(NotSerializableException.class)
|
||||||
.hasMessage(errMsg("a", getClass().getName()));
|
.hasMessage(errMsg("a", getClass().getName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package net.corda.serialization.internal.amqp;
|
package net.corda.serialization.internal.amqp;
|
||||||
|
|
||||||
import net.corda.core.serialization.SerializationCustomSerializer;
|
import net.corda.core.serialization.SerializationCustomSerializer;
|
||||||
import net.corda.serialization.internal.AllWhitelist;
|
|
||||||
import net.corda.serialization.internal.amqp.testutils.TestSerializationContext;
|
import net.corda.serialization.internal.amqp.testutils.TestSerializationContext;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
@ -9,6 +8,8 @@ import java.io.NotSerializableException;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static net.corda.serialization.internal.amqp.testutils.AMQPTestUtilsKt.testDefaultFactory;
|
||||||
|
|
||||||
public class JavaCustomSerializerTests {
|
public class JavaCustomSerializerTests {
|
||||||
/**
|
/**
|
||||||
* The class lacks a public constructor that takes parameters it can associate
|
* The class lacks a public constructor that takes parameters it can associate
|
||||||
@ -87,10 +88,8 @@ public class JavaCustomSerializerTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void serializeExample() throws NotSerializableException, NoSuchFieldException, IllegalAccessException {
|
public void serializeExample() throws NotSerializableException {
|
||||||
SerializerFactory factory = new SerializerFactory(AllWhitelist.INSTANCE, ClassLoader.getSystemClassLoader(),
|
SerializerFactory factory = testDefaultFactory();
|
||||||
new EvolutionSerializerGetter(),
|
|
||||||
new SerializerFingerPrinter());
|
|
||||||
SerializationOutput ser = new SerializationOutput(factory);
|
SerializationOutput ser = new SerializationOutput(factory);
|
||||||
|
|
||||||
List<Integer> l = new ArrayList<Integer>(2);
|
List<Integer> l = new ArrayList<Integer>(2);
|
||||||
@ -102,7 +101,5 @@ public class JavaCustomSerializerTests {
|
|||||||
factory.registerExternal(ccs);
|
factory.registerExternal(ccs);
|
||||||
|
|
||||||
ser.serialize(e, TestSerializationContext.testSerializationContext);
|
ser.serialize(e, TestSerializationContext.testSerializationContext);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
package net.corda.serialization.internal.amqp;
|
package net.corda.serialization.internal.amqp;
|
||||||
|
|
||||||
import net.corda.core.serialization.SerializedBytes;
|
import net.corda.core.serialization.SerializedBytes;
|
||||||
import net.corda.serialization.internal.AllWhitelist;
|
|
||||||
import net.corda.serialization.internal.amqp.testutils.TestSerializationContext;
|
import net.corda.serialization.internal.amqp.testutils.TestSerializationContext;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import java.io.NotSerializableException;
|
import java.io.NotSerializableException;
|
||||||
|
|
||||||
|
import static net.corda.serialization.internal.amqp.testutils.AMQPTestUtilsKt.testDefaultFactory;
|
||||||
import static org.jgroups.util.Util.assertEquals;
|
import static org.jgroups.util.Util.assertEquals;
|
||||||
|
|
||||||
public class JavaGenericsTest {
|
public class JavaGenericsTest {
|
||||||
@ -27,11 +27,7 @@ public class JavaGenericsTest {
|
|||||||
public void basicGeneric() throws NotSerializableException {
|
public void basicGeneric() throws NotSerializableException {
|
||||||
A a1 = new A(1);
|
A a1 = new A(1);
|
||||||
|
|
||||||
SerializerFactory factory = new SerializerFactory(
|
SerializerFactory factory = testDefaultFactory();
|
||||||
AllWhitelist.INSTANCE,
|
|
||||||
ClassLoader.getSystemClassLoader(),
|
|
||||||
new EvolutionSerializerGetter(),
|
|
||||||
new SerializerFingerPrinter());
|
|
||||||
|
|
||||||
SerializationOutput ser = new SerializationOutput(factory);
|
SerializationOutput ser = new SerializationOutput(factory);
|
||||||
SerializedBytes<?> bytes = ser.serialize(a1, TestSerializationContext.testSerializationContext);
|
SerializedBytes<?> bytes = ser.serialize(a1, TestSerializationContext.testSerializationContext);
|
||||||
@ -43,11 +39,7 @@ public class JavaGenericsTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private SerializedBytes<?> forceWildcardSerialize(A<?> a) throws NotSerializableException {
|
private SerializedBytes<?> forceWildcardSerialize(A<?> a) throws NotSerializableException {
|
||||||
SerializerFactory factory = new SerializerFactory(
|
SerializerFactory factory = testDefaultFactory();
|
||||||
AllWhitelist.INSTANCE,
|
|
||||||
ClassLoader.getSystemClassLoader(),
|
|
||||||
new EvolutionSerializerGetter(),
|
|
||||||
new SerializerFingerPrinter());
|
|
||||||
|
|
||||||
return (new SerializationOutput(factory)).serialize(a, TestSerializationContext.testSerializationContext);
|
return (new SerializationOutput(factory)).serialize(a, TestSerializationContext.testSerializationContext);
|
||||||
}
|
}
|
||||||
@ -59,11 +51,7 @@ public class JavaGenericsTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private A<?> forceWildcardDeserialize(SerializedBytes<?> bytes) throws NotSerializableException {
|
private A<?> forceWildcardDeserialize(SerializedBytes<?> bytes) throws NotSerializableException {
|
||||||
SerializerFactory factory = new SerializerFactory(
|
SerializerFactory factory = testDefaultFactory();
|
||||||
AllWhitelist.INSTANCE,
|
|
||||||
ClassLoader.getSystemClassLoader(),
|
|
||||||
new EvolutionSerializerGetter(),
|
|
||||||
new SerializerFingerPrinter());
|
|
||||||
|
|
||||||
DeserializationInput des = new DeserializationInput(factory);
|
DeserializationInput des = new DeserializationInput(factory);
|
||||||
return des.deserialize(bytes, A.class, TestSerializationContext.testSerializationContext);
|
return des.deserialize(bytes, A.class, TestSerializationContext.testSerializationContext);
|
||||||
@ -85,11 +73,7 @@ public class JavaGenericsTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void forceWildcardSharedFactory() throws NotSerializableException {
|
public void forceWildcardSharedFactory() throws NotSerializableException {
|
||||||
SerializerFactory factory = new SerializerFactory(
|
SerializerFactory factory = testDefaultFactory();
|
||||||
AllWhitelist.INSTANCE,
|
|
||||||
ClassLoader.getSystemClassLoader(),
|
|
||||||
new EvolutionSerializerGetter(),
|
|
||||||
new SerializerFingerPrinter());
|
|
||||||
|
|
||||||
SerializedBytes<?> bytes = forceWildcardSerializeFactory(new A(new Inner(29)), factory);
|
SerializedBytes<?> bytes = forceWildcardSerializeFactory(new A(new Inner(29)), factory);
|
||||||
Inner i = (Inner)forceWildcardDeserializeFactory(bytes, factory).getT();
|
Inner i = (Inner)forceWildcardDeserializeFactory(bytes, factory).getT();
|
||||||
|
@ -4,28 +4,25 @@ import com.google.common.collect.ImmutableList;
|
|||||||
import net.corda.core.contracts.ContractState;
|
import net.corda.core.contracts.ContractState;
|
||||||
import net.corda.core.identity.AbstractParty;
|
import net.corda.core.identity.AbstractParty;
|
||||||
import net.corda.core.serialization.SerializedBytes;
|
import net.corda.core.serialization.SerializedBytes;
|
||||||
import net.corda.serialization.internal.AllWhitelist;
|
|
||||||
import net.corda.serialization.internal.amqp.testutils.TestSerializationContext;
|
import net.corda.serialization.internal.amqp.testutils.TestSerializationContext;
|
||||||
import org.assertj.core.api.Assertions;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.io.NotSerializableException;
|
import java.io.NotSerializableException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static net.corda.serialization.internal.amqp.testutils.AMQPTestUtilsKt.testDefaultFactory;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||||
|
|
||||||
class OuterClass1 {
|
class OuterClass1 {
|
||||||
protected SerializationOutput ser;
|
protected SerializationOutput ser;
|
||||||
DeserializationInput desExisting;
|
DeserializationInput desExisting;
|
||||||
DeserializationInput desRegen;
|
DeserializationInput desRegen;
|
||||||
|
|
||||||
OuterClass1() {
|
OuterClass1() {
|
||||||
SerializerFactory factory1 = new SerializerFactory(AllWhitelist.INSTANCE, ClassLoader.getSystemClassLoader(),
|
SerializerFactory factory1 = testDefaultFactory();
|
||||||
new EvolutionSerializerGetter(),
|
|
||||||
new SerializerFingerPrinter());
|
|
||||||
|
|
||||||
SerializerFactory factory2 = new SerializerFactory(AllWhitelist.INSTANCE, ClassLoader.getSystemClassLoader(),
|
SerializerFactory factory2 = testDefaultFactory();
|
||||||
new EvolutionSerializerGetter(),
|
|
||||||
new SerializerFingerPrinter());
|
|
||||||
|
|
||||||
this.ser = new SerializationOutput(factory1);
|
this.ser = new SerializationOutput(factory1);
|
||||||
this.desExisting = new DeserializationInput(factory1);
|
this.desExisting = new DeserializationInput(factory1);
|
||||||
@ -59,13 +56,9 @@ class OuterClass2 {
|
|||||||
DeserializationInput desRegen;
|
DeserializationInput desRegen;
|
||||||
|
|
||||||
OuterClass2() {
|
OuterClass2() {
|
||||||
SerializerFactory factory1 = new SerializerFactory(AllWhitelist.INSTANCE, ClassLoader.getSystemClassLoader(),
|
SerializerFactory factory1 = testDefaultFactory();
|
||||||
new EvolutionSerializerGetter(),
|
|
||||||
new SerializerFingerPrinter());
|
|
||||||
|
|
||||||
SerializerFactory factory2 = new SerializerFactory(AllWhitelist.INSTANCE, ClassLoader.getSystemClassLoader(),
|
SerializerFactory factory2 = testDefaultFactory();
|
||||||
new EvolutionSerializerGetter(),
|
|
||||||
new SerializerFingerPrinter());
|
|
||||||
|
|
||||||
this.ser = new SerializationOutput(factory1);
|
this.ser = new SerializationOutput(factory1);
|
||||||
this.desExisting = new DeserializationInput(factory1);
|
this.desExisting = new DeserializationInput(factory1);
|
||||||
@ -104,9 +97,7 @@ abstract class AbstractClass2 {
|
|||||||
protected SerializationOutput ser;
|
protected SerializationOutput ser;
|
||||||
|
|
||||||
AbstractClass2() {
|
AbstractClass2() {
|
||||||
SerializerFactory factory = new SerializerFactory(AllWhitelist.INSTANCE, ClassLoader.getSystemClassLoader(),
|
SerializerFactory factory = testDefaultFactory();
|
||||||
new EvolutionSerializerGetter(),
|
|
||||||
new SerializerFingerPrinter());
|
|
||||||
|
|
||||||
this.ser = new SerializationOutput(factory);
|
this.ser = new SerializationOutput(factory);
|
||||||
}
|
}
|
||||||
@ -134,9 +125,7 @@ abstract class AbstractClass3 {
|
|||||||
|
|
||||||
class Inherator5 extends AbstractClass3 {
|
class Inherator5 extends AbstractClass3 {
|
||||||
public void run() throws NotSerializableException {
|
public void run() throws NotSerializableException {
|
||||||
SerializerFactory factory = new SerializerFactory(AllWhitelist.INSTANCE, ClassLoader.getSystemClassLoader(),
|
SerializerFactory factory = testDefaultFactory();
|
||||||
new EvolutionSerializerGetter(),
|
|
||||||
new SerializerFingerPrinter());
|
|
||||||
|
|
||||||
SerializationOutput ser = new SerializationOutput(factory);
|
SerializationOutput ser = new SerializationOutput(factory);
|
||||||
ser.serialize(new DummyState(), TestSerializationContext.testSerializationContext);
|
ser.serialize(new DummyState(), TestSerializationContext.testSerializationContext);
|
||||||
@ -154,9 +143,7 @@ class Inherator6 extends AbstractClass3 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void run() throws NotSerializableException {
|
public void run() throws NotSerializableException {
|
||||||
SerializerFactory factory = new SerializerFactory(AllWhitelist.INSTANCE, ClassLoader.getSystemClassLoader(),
|
SerializerFactory factory = testDefaultFactory();
|
||||||
new EvolutionSerializerGetter(),
|
|
||||||
new SerializerFingerPrinter());
|
|
||||||
|
|
||||||
SerializationOutput ser = new SerializationOutput(factory);
|
SerializationOutput ser = new SerializationOutput(factory);
|
||||||
ser.serialize(new Wrapper(new DummyState()), TestSerializationContext.testSerializationContext);
|
ser.serialize(new Wrapper(new DummyState()), TestSerializationContext.testSerializationContext);
|
||||||
@ -166,57 +153,57 @@ class Inherator6 extends AbstractClass3 {
|
|||||||
public class JavaNestedClassesTests {
|
public class JavaNestedClassesTests {
|
||||||
@Test
|
@Test
|
||||||
public void publicNested() {
|
public void publicNested() {
|
||||||
Assertions.assertThatThrownBy(() -> new OuterClass1().run()).isInstanceOf(
|
assertThatThrownBy(() -> new OuterClass1().run()).isInstanceOf(
|
||||||
NotSerializableException.class).hasMessageContaining(
|
NotSerializableException.class).hasMessageContaining(
|
||||||
"has synthetic fields and is likely a nested inner class");
|
"has synthetic fields and is likely a nested inner class");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void privateNested() {
|
public void privateNested() {
|
||||||
Assertions.assertThatThrownBy(() -> new OuterClass2().run()).isInstanceOf(
|
assertThatThrownBy(() -> new OuterClass2().run()).isInstanceOf(
|
||||||
NotSerializableException.class).hasMessageContaining(
|
NotSerializableException.class).hasMessageContaining(
|
||||||
"has synthetic fields and is likely a nested inner class");
|
"has synthetic fields and is likely a nested inner class");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void publicNestedInherited() {
|
public void publicNestedInherited() {
|
||||||
Assertions.assertThatThrownBy(() -> new Inherator1().run()).isInstanceOf(
|
assertThatThrownBy(() -> new Inherator1().run()).isInstanceOf(
|
||||||
NotSerializableException.class).hasMessageContaining(
|
NotSerializableException.class).hasMessageContaining(
|
||||||
"has synthetic fields and is likely a nested inner class");
|
"has synthetic fields and is likely a nested inner class");
|
||||||
|
|
||||||
Assertions.assertThatThrownBy(() -> new Inherator1().iRun()).isInstanceOf(
|
assertThatThrownBy(() -> new Inherator1().iRun()).isInstanceOf(
|
||||||
NotSerializableException.class).hasMessageContaining(
|
NotSerializableException.class).hasMessageContaining(
|
||||||
"has synthetic fields and is likely a nested inner class");
|
"has synthetic fields and is likely a nested inner class");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void protectedNestedInherited() {
|
public void protectedNestedInherited() {
|
||||||
Assertions.assertThatThrownBy(() -> new Inherator2().run()).isInstanceOf(
|
assertThatThrownBy(() -> new Inherator2().run()).isInstanceOf(
|
||||||
NotSerializableException.class).hasMessageContaining(
|
NotSerializableException.class).hasMessageContaining(
|
||||||
"has synthetic fields and is likely a nested inner class");
|
"has synthetic fields and is likely a nested inner class");
|
||||||
|
|
||||||
Assertions.assertThatThrownBy(() -> new Inherator2().iRun()).isInstanceOf(
|
assertThatThrownBy(() -> new Inherator2().iRun()).isInstanceOf(
|
||||||
NotSerializableException.class).hasMessageContaining(
|
NotSerializableException.class).hasMessageContaining(
|
||||||
"has synthetic fields and is likely a nested inner class");
|
"has synthetic fields and is likely a nested inner class");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void abstractNested() {
|
public void abstractNested() {
|
||||||
Assertions.assertThatThrownBy(() -> new Inherator4().run()).isInstanceOf(
|
assertThatThrownBy(() -> new Inherator4().run()).isInstanceOf(
|
||||||
NotSerializableException.class).hasMessageContaining(
|
NotSerializableException.class).hasMessageContaining(
|
||||||
"has synthetic fields and is likely a nested inner class");
|
"has synthetic fields and is likely a nested inner class");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void abstractNestedFactoryOnNested() {
|
public void abstractNestedFactoryOnNested() {
|
||||||
Assertions.assertThatThrownBy(() -> new Inherator5().run()).isInstanceOf(
|
assertThatThrownBy(() -> new Inherator5().run()).isInstanceOf(
|
||||||
NotSerializableException.class).hasMessageContaining(
|
NotSerializableException.class).hasMessageContaining(
|
||||||
"has synthetic fields and is likely a nested inner class");
|
"has synthetic fields and is likely a nested inner class");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void abstractNestedFactoryOnNestedInWrapper() {
|
public void abstractNestedFactoryOnNestedInWrapper() {
|
||||||
Assertions.assertThatThrownBy(() -> new Inherator6().run()).isInstanceOf(
|
assertThatThrownBy(() -> new Inherator6().run()).isInstanceOf(
|
||||||
NotSerializableException.class).hasMessageContaining(
|
NotSerializableException.class).hasMessageContaining(
|
||||||
"has synthetic fields and is likely a nested inner class");
|
"has synthetic fields and is likely a nested inner class");
|
||||||
}
|
}
|
||||||
|
@ -3,15 +3,16 @@ package net.corda.serialization.internal.amqp;
|
|||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import net.corda.core.contracts.ContractState;
|
import net.corda.core.contracts.ContractState;
|
||||||
import net.corda.core.identity.AbstractParty;
|
import net.corda.core.identity.AbstractParty;
|
||||||
import net.corda.serialization.internal.AllWhitelist;
|
|
||||||
import net.corda.serialization.internal.amqp.testutils.TestSerializationContext;
|
import net.corda.serialization.internal.amqp.testutils.TestSerializationContext;
|
||||||
import org.assertj.core.api.Assertions;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.io.NotSerializableException;
|
import java.io.NotSerializableException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static net.corda.serialization.internal.amqp.testutils.AMQPTestUtilsKt.testDefaultFactory;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||||
|
|
||||||
abstract class JavaNestedInheritenceTestsBase {
|
abstract class JavaNestedInheritenceTestsBase {
|
||||||
class DummyState implements ContractState {
|
class DummyState implements ContractState {
|
||||||
@Override @NotNull public List<AbstractParty> getParticipants() {
|
@Override @NotNull public List<AbstractParty> getParticipants() {
|
||||||
@ -33,38 +34,32 @@ class TemplateWrapper<T> {
|
|||||||
public class JavaNestedInheritenceTests extends JavaNestedInheritenceTestsBase {
|
public class JavaNestedInheritenceTests extends JavaNestedInheritenceTestsBase {
|
||||||
@Test
|
@Test
|
||||||
public void serializeIt() {
|
public void serializeIt() {
|
||||||
SerializerFactory factory = new SerializerFactory(AllWhitelist.INSTANCE, ClassLoader.getSystemClassLoader(),
|
SerializerFactory factory = testDefaultFactory();
|
||||||
new EvolutionSerializerGetter(),
|
|
||||||
new SerializerFingerPrinter());
|
|
||||||
|
|
||||||
SerializationOutput ser = new SerializationOutput(factory);
|
SerializationOutput ser = new SerializationOutput(factory);
|
||||||
|
|
||||||
Assertions.assertThatThrownBy(() -> ser.serialize(new DummyState(), TestSerializationContext.testSerializationContext)).isInstanceOf(
|
assertThatThrownBy(() -> ser.serialize(new DummyState(), TestSerializationContext.testSerializationContext)).isInstanceOf(
|
||||||
NotSerializableException.class).hasMessageContaining(
|
NotSerializableException.class).hasMessageContaining(
|
||||||
"has synthetic fields and is likely a nested inner class");
|
"has synthetic fields and is likely a nested inner class");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void serializeIt2() {
|
public void serializeIt2() {
|
||||||
SerializerFactory factory = new SerializerFactory(AllWhitelist.INSTANCE, ClassLoader.getSystemClassLoader(),
|
SerializerFactory factory = testDefaultFactory();
|
||||||
new EvolutionSerializerGetter(),
|
|
||||||
new SerializerFingerPrinter());
|
|
||||||
|
|
||||||
SerializationOutput ser = new SerializationOutput(factory);
|
SerializationOutput ser = new SerializationOutput(factory);
|
||||||
Assertions.assertThatThrownBy(() -> ser.serialize(new Wrapper (new DummyState()), TestSerializationContext.testSerializationContext)).isInstanceOf(
|
assertThatThrownBy(() -> ser.serialize(new Wrapper (new DummyState()), TestSerializationContext.testSerializationContext)).isInstanceOf(
|
||||||
NotSerializableException.class).hasMessageContaining(
|
NotSerializableException.class).hasMessageContaining(
|
||||||
"has synthetic fields and is likely a nested inner class");
|
"has synthetic fields and is likely a nested inner class");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void serializeIt3() throws NotSerializableException {
|
public void serializeIt3() {
|
||||||
SerializerFactory factory1 = new SerializerFactory(AllWhitelist.INSTANCE, ClassLoader.getSystemClassLoader(),
|
SerializerFactory factory1 = testDefaultFactory();
|
||||||
new EvolutionSerializerGetter(),
|
|
||||||
new SerializerFingerPrinter());
|
|
||||||
|
|
||||||
SerializationOutput ser = new SerializationOutput(factory1);
|
SerializationOutput ser = new SerializationOutput(factory1);
|
||||||
|
|
||||||
Assertions.assertThatThrownBy(() -> ser.serialize(new TemplateWrapper<ContractState> (new DummyState()), TestSerializationContext.testSerializationContext)).isInstanceOf(
|
assertThatThrownBy(() -> ser.serialize(new TemplateWrapper<ContractState> (new DummyState()), TestSerializationContext.testSerializationContext)).isInstanceOf(
|
||||||
NotSerializableException.class).hasMessageContaining(
|
NotSerializableException.class).hasMessageContaining(
|
||||||
"has synthetic fields and is likely a nested inner class");
|
"has synthetic fields and is likely a nested inner class");
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
package net.corda.serialization.internal.amqp;
|
package net.corda.serialization.internal.amqp;
|
||||||
|
|
||||||
import net.corda.serialization.internal.AllWhitelist;
|
|
||||||
import net.corda.serialization.internal.amqp.testutils.TestSerializationContext;
|
import net.corda.serialization.internal.amqp.testutils.TestSerializationContext;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import static org.junit.Assert.*;
|
|
||||||
|
|
||||||
import java.io.NotSerializableException;
|
import java.io.NotSerializableException;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static net.corda.serialization.internal.amqp.testutils.AMQPTestUtilsKt.testDefaultFactory;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
public class JavaPrivatePropertyTests {
|
public class JavaPrivatePropertyTests {
|
||||||
static class C {
|
static class C {
|
||||||
private String a;
|
private String a;
|
||||||
@ -76,10 +77,8 @@ public class JavaPrivatePropertyTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void singlePrivateBooleanWithConstructor() throws NotSerializableException, NoSuchFieldException, IllegalAccessException {
|
public void singlePrivateBooleanWithConstructor() throws NotSerializableException {
|
||||||
SerializerFactory factory = new SerializerFactory(AllWhitelist.INSTANCE, ClassLoader.getSystemClassLoader(),
|
SerializerFactory factory = testDefaultFactory();
|
||||||
new EvolutionSerializerGetter(),
|
|
||||||
new SerializerFingerPrinter());
|
|
||||||
SerializationOutput ser = new SerializationOutput(factory);
|
SerializationOutput ser = new SerializationOutput(factory);
|
||||||
DeserializationInput des = new DeserializationInput(factory);
|
DeserializationInput des = new DeserializationInput(factory);
|
||||||
|
|
||||||
@ -89,10 +88,8 @@ public class JavaPrivatePropertyTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void singlePrivateBooleanWithNoConstructor() throws NotSerializableException, NoSuchFieldException, IllegalAccessException {
|
public void singlePrivateBooleanWithNoConstructor() throws NotSerializableException {
|
||||||
SerializerFactory factory = new SerializerFactory(AllWhitelist.INSTANCE, ClassLoader.getSystemClassLoader(),
|
SerializerFactory factory = testDefaultFactory();
|
||||||
new EvolutionSerializerGetter(),
|
|
||||||
new SerializerFingerPrinter());
|
|
||||||
|
|
||||||
SerializationOutput ser = new SerializationOutput(factory);
|
SerializationOutput ser = new SerializationOutput(factory);
|
||||||
DeserializationInput des = new DeserializationInput(factory);
|
DeserializationInput des = new DeserializationInput(factory);
|
||||||
@ -104,10 +101,8 @@ public class JavaPrivatePropertyTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCapitilsationOfIs() throws NotSerializableException, NoSuchFieldException, IllegalAccessException {
|
public void testCapitilsationOfIs() throws NotSerializableException {
|
||||||
SerializerFactory factory = new SerializerFactory(AllWhitelist.INSTANCE, ClassLoader.getSystemClassLoader(),
|
SerializerFactory factory = testDefaultFactory();
|
||||||
new EvolutionSerializerGetter(),
|
|
||||||
new SerializerFingerPrinter());
|
|
||||||
SerializationOutput ser = new SerializationOutput(factory);
|
SerializationOutput ser = new SerializationOutput(factory);
|
||||||
DeserializationInput des = new DeserializationInput(factory);
|
DeserializationInput des = new DeserializationInput(factory);
|
||||||
|
|
||||||
@ -120,10 +115,8 @@ public class JavaPrivatePropertyTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void singlePrivateIntWithBoolean() throws NotSerializableException, NoSuchFieldException, IllegalAccessException {
|
public void singlePrivateIntWithBoolean() throws NotSerializableException {
|
||||||
SerializerFactory factory = new SerializerFactory(AllWhitelist.INSTANCE, ClassLoader.getSystemClassLoader(),
|
SerializerFactory factory = testDefaultFactory();
|
||||||
new EvolutionSerializerGetter(),
|
|
||||||
new SerializerFingerPrinter());
|
|
||||||
SerializationOutput ser = new SerializationOutput(factory);
|
SerializationOutput ser = new SerializationOutput(factory);
|
||||||
DeserializationInput des = new DeserializationInput(factory);
|
DeserializationInput des = new DeserializationInput(factory);
|
||||||
|
|
||||||
@ -136,9 +129,7 @@ public class JavaPrivatePropertyTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void singlePrivateWithConstructor() throws NotSerializableException, NoSuchFieldException, IllegalAccessException {
|
public void singlePrivateWithConstructor() throws NotSerializableException, NoSuchFieldException, IllegalAccessException {
|
||||||
SerializerFactory factory = new SerializerFactory(AllWhitelist.INSTANCE, ClassLoader.getSystemClassLoader(),
|
SerializerFactory factory = testDefaultFactory();
|
||||||
new EvolutionSerializerGetter(),
|
|
||||||
new SerializerFingerPrinter());
|
|
||||||
|
|
||||||
SerializationOutput ser = new SerializationOutput(factory);
|
SerializationOutput ser = new SerializationOutput(factory);
|
||||||
DeserializationInput des = new DeserializationInput(factory);
|
DeserializationInput des = new DeserializationInput(factory);
|
||||||
@ -166,10 +157,7 @@ public class JavaPrivatePropertyTests {
|
|||||||
@Test
|
@Test
|
||||||
public void singlePrivateWithConstructorAndGetter()
|
public void singlePrivateWithConstructorAndGetter()
|
||||||
throws NotSerializableException, NoSuchFieldException, IllegalAccessException {
|
throws NotSerializableException, NoSuchFieldException, IllegalAccessException {
|
||||||
SerializerFactory factory = new SerializerFactory(AllWhitelist.INSTANCE,
|
SerializerFactory factory = testDefaultFactory();
|
||||||
ClassLoader.getSystemClassLoader(),
|
|
||||||
new EvolutionSerializerGetter(),
|
|
||||||
new SerializerFingerPrinter());
|
|
||||||
|
|
||||||
SerializationOutput ser = new SerializationOutput(factory);
|
SerializationOutput ser = new SerializationOutput(factory);
|
||||||
DeserializationInput des = new DeserializationInput(factory);
|
DeserializationInput des = new DeserializationInput(factory);
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
package net.corda.serialization.internal.amqp;
|
package net.corda.serialization.internal.amqp;
|
||||||
|
|
||||||
|
import net.corda.core.serialization.SerializedBytes;
|
||||||
import net.corda.serialization.internal.amqp.testutils.TestSerializationContext;
|
import net.corda.serialization.internal.amqp.testutils.TestSerializationContext;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import net.corda.serialization.internal.AllWhitelist;
|
|
||||||
import net.corda.core.serialization.SerializedBytes;
|
|
||||||
|
|
||||||
import java.io.NotSerializableException;
|
import java.io.NotSerializableException;
|
||||||
|
|
||||||
|
import static net.corda.serialization.internal.amqp.testutils.AMQPTestUtilsKt.testDefaultFactory;
|
||||||
|
|
||||||
public class JavaSerialiseEnumTests {
|
public class JavaSerialiseEnumTests {
|
||||||
|
|
||||||
public enum Bras {
|
public enum Bras {
|
||||||
@ -30,10 +30,7 @@ public class JavaSerialiseEnumTests {
|
|||||||
public void testJavaConstructorAnnotations() throws NotSerializableException {
|
public void testJavaConstructorAnnotations() throws NotSerializableException {
|
||||||
Bra bra = new Bra(Bras.UNDERWIRE);
|
Bra bra = new Bra(Bras.UNDERWIRE);
|
||||||
|
|
||||||
SerializerFactory factory1 = new SerializerFactory(AllWhitelist.INSTANCE, ClassLoader.getSystemClassLoader(),
|
SerializationOutput ser = new SerializationOutput(testDefaultFactory());
|
||||||
new EvolutionSerializerGetter(),
|
ser.serialize(bra, TestSerializationContext.testSerializationContext);
|
||||||
new SerializerFingerPrinter());
|
|
||||||
SerializationOutput ser = new SerializationOutput(factory1);
|
|
||||||
SerializedBytes<Object> bytes = ser.serialize(bra, TestSerializationContext.testSerializationContext);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package net.corda.serialization.internal.amqp;
|
package net.corda.serialization.internal.amqp;
|
||||||
|
|
||||||
import net.corda.core.serialization.ConstructorForDeserialization;
|
import net.corda.core.serialization.ConstructorForDeserialization;
|
||||||
import net.corda.serialization.internal.AllWhitelist;
|
|
||||||
import net.corda.core.serialization.SerializedBytes;
|
import net.corda.core.serialization.SerializedBytes;
|
||||||
import net.corda.serialization.internal.amqp.testutils.TestSerializationContext;
|
import net.corda.serialization.internal.amqp.testutils.TestSerializationContext;
|
||||||
import org.apache.qpid.proton.codec.DecoderImpl;
|
import org.apache.qpid.proton.codec.DecoderImpl;
|
||||||
@ -13,6 +12,7 @@ import java.io.NotSerializableException;
|
|||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import static net.corda.serialization.internal.amqp.testutils.AMQPTestUtilsKt.testDefaultFactory;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
public class JavaSerializationOutputTests {
|
public class JavaSerializationOutputTests {
|
||||||
@ -176,14 +176,8 @@ public class JavaSerializationOutputTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Object serdes(Object obj) throws NotSerializableException {
|
private Object serdes(Object obj) throws NotSerializableException {
|
||||||
EvolutionSerializerGetterBase evolutionSerialiserGetter = new EvolutionSerializerGetter();
|
SerializerFactory factory1 = testDefaultFactory();
|
||||||
FingerPrinter fingerPrinter = new SerializerFingerPrinter();
|
SerializerFactory factory2 = testDefaultFactory();
|
||||||
SerializerFactory factory1 = new SerializerFactory(AllWhitelist.INSTANCE, ClassLoader.getSystemClassLoader(),
|
|
||||||
evolutionSerialiserGetter,
|
|
||||||
fingerPrinter);
|
|
||||||
SerializerFactory factory2 = new SerializerFactory(AllWhitelist.INSTANCE, ClassLoader.getSystemClassLoader(),
|
|
||||||
evolutionSerialiserGetter,
|
|
||||||
fingerPrinter);
|
|
||||||
SerializationOutput ser = new SerializationOutput(factory1);
|
SerializationOutput ser = new SerializationOutput(factory1);
|
||||||
SerializedBytes<Object> bytes = ser.serialize(obj, TestSerializationContext.testSerializationContext);
|
SerializedBytes<Object> bytes = ser.serialize(obj, TestSerializationContext.testSerializationContext);
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@ package net.corda.serialization.internal.amqp;
|
|||||||
|
|
||||||
import net.corda.core.serialization.CordaSerializable;
|
import net.corda.core.serialization.CordaSerializable;
|
||||||
import net.corda.core.serialization.SerializedBytes;
|
import net.corda.core.serialization.SerializedBytes;
|
||||||
import net.corda.serialization.internal.AllWhitelist;
|
|
||||||
import net.corda.serialization.internal.amqp.testutils.TestSerializationContext;
|
import net.corda.serialization.internal.amqp.testutils.TestSerializationContext;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@ -10,6 +9,8 @@ import org.junit.Test;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static net.corda.serialization.internal.amqp.testutils.AMQPTestUtilsKt.testDefaultFactory;
|
||||||
|
|
||||||
public class ListsSerializationJavaTest {
|
public class ListsSerializationJavaTest {
|
||||||
|
|
||||||
@CordaSerializable
|
@CordaSerializable
|
||||||
@ -126,12 +127,7 @@ public class ListsSerializationJavaTest {
|
|||||||
|
|
||||||
// Have to have own version as Kotlin inline functions cannot be easily called from Java
|
// Have to have own version as Kotlin inline functions cannot be easily called from Java
|
||||||
private static <T> void assertEqualAfterRoundTripSerialization(T container, Class<T> clazz) throws Exception {
|
private static <T> void assertEqualAfterRoundTripSerialization(T container, Class<T> clazz) throws Exception {
|
||||||
EvolutionSerializerGetterBase evolutionSerializerGetter = new EvolutionSerializerGetter();
|
SerializerFactory factory1 = testDefaultFactory();
|
||||||
FingerPrinter fingerPrinter = new SerializerFingerPrinter();
|
|
||||||
SerializerFactory factory1 = new SerializerFactory(
|
|
||||||
AllWhitelist.INSTANCE, ClassLoader.getSystemClassLoader(),
|
|
||||||
evolutionSerializerGetter,
|
|
||||||
fingerPrinter);
|
|
||||||
SerializationOutput ser = new SerializationOutput(factory1);
|
SerializationOutput ser = new SerializationOutput(factory1);
|
||||||
SerializedBytes<Object> bytes = ser.serialize(container, TestSerializationContext.testSerializationContext);
|
SerializedBytes<Object> bytes = ser.serialize(container, TestSerializationContext.testSerializationContext);
|
||||||
DeserializationInput des = new DeserializationInput(factory1);
|
DeserializationInput des = new DeserializationInput(factory1);
|
||||||
|
@ -1,16 +1,17 @@
|
|||||||
package net.corda.serialization.internal.amqp;
|
package net.corda.serialization.internal.amqp;
|
||||||
|
|
||||||
import net.corda.core.serialization.SerializedBytes;
|
import net.corda.core.serialization.SerializedBytes;
|
||||||
import net.corda.serialization.internal.AllWhitelist;
|
|
||||||
import net.corda.serialization.internal.amqp.testutils.TestSerializationContext;
|
import net.corda.serialization.internal.amqp.testutils.TestSerializationContext;
|
||||||
import org.assertj.core.api.Assertions;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import static org.junit.Assert.*;
|
|
||||||
|
|
||||||
import java.io.NotSerializableException;
|
import java.io.NotSerializableException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static net.corda.serialization.internal.amqp.testutils.AMQPTestUtilsKt.testDefaultFactory;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
public class SetterConstructorTests {
|
public class SetterConstructorTests {
|
||||||
|
|
||||||
static class C {
|
static class C {
|
||||||
@ -119,13 +120,7 @@ public class SetterConstructorTests {
|
|||||||
// despite having no constructor we should still be able to serialise an instance of C
|
// despite having no constructor we should still be able to serialise an instance of C
|
||||||
@Test
|
@Test
|
||||||
public void serialiseC() throws NotSerializableException {
|
public void serialiseC() throws NotSerializableException {
|
||||||
EvolutionSerializerGetterBase evolutionSerialiserGetter = new EvolutionSerializerGetter();
|
SerializerFactory factory1 = testDefaultFactory();
|
||||||
FingerPrinter fingerPrinter = new SerializerFingerPrinter();
|
|
||||||
SerializerFactory factory1 = new SerializerFactory(
|
|
||||||
AllWhitelist.INSTANCE,
|
|
||||||
ClassLoader.getSystemClassLoader(),
|
|
||||||
evolutionSerialiserGetter,
|
|
||||||
fingerPrinter);
|
|
||||||
|
|
||||||
SerializationOutput ser = new SerializationOutput(factory1);
|
SerializationOutput ser = new SerializationOutput(factory1);
|
||||||
|
|
||||||
@ -195,13 +190,7 @@ public class SetterConstructorTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void deserialiseC() throws NotSerializableException {
|
public void deserialiseC() throws NotSerializableException {
|
||||||
EvolutionSerializerGetterBase evolutionSerialiserGetter = new EvolutionSerializerGetter();
|
SerializerFactory factory1 = testDefaultFactory();
|
||||||
FingerPrinter fingerPrinter = new SerializerFingerPrinter();
|
|
||||||
SerializerFactory factory1 = new SerializerFactory(
|
|
||||||
AllWhitelist.INSTANCE,
|
|
||||||
ClassLoader.getSystemClassLoader(),
|
|
||||||
evolutionSerialiserGetter,
|
|
||||||
fingerPrinter);
|
|
||||||
|
|
||||||
C cPre1 = new C();
|
C cPre1 = new C();
|
||||||
|
|
||||||
@ -268,13 +257,7 @@ public class SetterConstructorTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void serialiseOuterAndInner() throws NotSerializableException {
|
public void serialiseOuterAndInner() throws NotSerializableException {
|
||||||
EvolutionSerializerGetterBase evolutionSerialiserGetter = new EvolutionSerializerGetter();
|
SerializerFactory factory1 = testDefaultFactory();
|
||||||
FingerPrinter fingerPrinter = new SerializerFingerPrinter();
|
|
||||||
SerializerFactory factory1 = new SerializerFactory(
|
|
||||||
AllWhitelist.INSTANCE,
|
|
||||||
ClassLoader.getSystemClassLoader(),
|
|
||||||
evolutionSerialiserGetter,
|
|
||||||
fingerPrinter);
|
|
||||||
|
|
||||||
Inner1 i1 = new Inner1("Hello");
|
Inner1 i1 = new Inner1("Hello");
|
||||||
Inner2 i2 = new Inner2();
|
Inner2 i2 = new Inner2();
|
||||||
@ -298,38 +281,26 @@ public class SetterConstructorTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void typeMistmatch() {
|
public void typeMistmatch() {
|
||||||
EvolutionSerializerGetterBase evolutionSerialiserGetter = new EvolutionSerializerGetter();
|
SerializerFactory factory1 = testDefaultFactory();
|
||||||
FingerPrinter fingerPrinter = new SerializerFingerPrinter();
|
|
||||||
SerializerFactory factory1 = new SerializerFactory(
|
|
||||||
AllWhitelist.INSTANCE,
|
|
||||||
ClassLoader.getSystemClassLoader(),
|
|
||||||
evolutionSerialiserGetter,
|
|
||||||
fingerPrinter);
|
|
||||||
|
|
||||||
TypeMismatch tm = new TypeMismatch();
|
TypeMismatch tm = new TypeMismatch();
|
||||||
tm.setA(10);
|
tm.setA(10);
|
||||||
assertEquals("10", tm.getA());
|
assertEquals("10", tm.getA());
|
||||||
|
|
||||||
Assertions.assertThatThrownBy(() -> new SerializationOutput(factory1).serialize(tm,
|
assertThatThrownBy(() -> new SerializationOutput(factory1).serialize(tm,
|
||||||
TestSerializationContext.testSerializationContext)).isInstanceOf (
|
TestSerializationContext.testSerializationContext)).isInstanceOf (
|
||||||
NotSerializableException.class);
|
NotSerializableException.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void typeMistmatch2() {
|
public void typeMistmatch2() {
|
||||||
EvolutionSerializerGetterBase evolutionSerialiserGetter = new EvolutionSerializerGetter();
|
SerializerFactory factory1 = testDefaultFactory();
|
||||||
FingerPrinter fingerPrinter = new SerializerFingerPrinter();
|
|
||||||
SerializerFactory factory1 = new SerializerFactory(
|
|
||||||
AllWhitelist.INSTANCE,
|
|
||||||
ClassLoader.getSystemClassLoader(),
|
|
||||||
evolutionSerialiserGetter,
|
|
||||||
fingerPrinter);
|
|
||||||
|
|
||||||
TypeMismatch2 tm = new TypeMismatch2();
|
TypeMismatch2 tm = new TypeMismatch2();
|
||||||
tm.setA("10");
|
tm.setA("10");
|
||||||
assertEquals((Integer)10, tm.getA());
|
assertEquals((Integer)10, tm.getA());
|
||||||
|
|
||||||
Assertions.assertThatThrownBy(() -> new SerializationOutput(factory1).serialize(tm,
|
assertThatThrownBy(() -> new SerializationOutput(factory1).serialize(tm,
|
||||||
TestSerializationContext.testSerializationContext)).isInstanceOf(
|
TestSerializationContext.testSerializationContext)).isInstanceOf(
|
||||||
NotSerializableException.class);
|
NotSerializableException.class);
|
||||||
}
|
}
|
||||||
@ -346,13 +317,7 @@ public class SetterConstructorTests {
|
|||||||
|
|
||||||
cil.setL(l);
|
cil.setL(l);
|
||||||
|
|
||||||
EvolutionSerializerGetterBase evolutionSerialiserGetter = new EvolutionSerializerGetter();
|
SerializerFactory factory1 = testDefaultFactory();
|
||||||
FingerPrinter fingerPrinter = new SerializerFingerPrinter();
|
|
||||||
SerializerFactory factory1 = new SerializerFactory(
|
|
||||||
AllWhitelist.INSTANCE,
|
|
||||||
ClassLoader.getSystemClassLoader(),
|
|
||||||
evolutionSerialiserGetter,
|
|
||||||
fingerPrinter);
|
|
||||||
|
|
||||||
// if we've got super / sub types on the setter vs the underlying type the wrong way around this will
|
// if we've got super / sub types on the setter vs the underlying type the wrong way around this will
|
||||||
// explode. See CORDA-1229 (https://r3-cev.atlassian.net/browse/CORDA-1229)
|
// explode. See CORDA-1229 (https://r3-cev.atlassian.net/browse/CORDA-1229)
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
package net.corda.serialization.internal.amqp
|
package net.corda.serialization.internal.amqp
|
||||||
|
|
||||||
import net.corda.serialization.internal.AllWhitelist
|
import net.corda.serialization.internal.AllWhitelist
|
||||||
|
import net.corda.serialization.internal.amqp.testutils.*
|
||||||
import net.corda.serialization.internal.carpenter.*
|
import net.corda.serialization.internal.carpenter.*
|
||||||
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.testDefaultFactoryNoEvolution
|
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import kotlin.test.*
|
import kotlin.test.*
|
||||||
|
|
||||||
|
@ -1,15 +1,13 @@
|
|||||||
package net.corda.serialization.internal.amqp
|
package net.corda.serialization.internal.amqp
|
||||||
|
|
||||||
import net.corda.core.serialization.CordaSerializable
|
import net.corda.core.serialization.CordaSerializable
|
||||||
import net.corda.serialization.internal.carpenter.*
|
|
||||||
import net.corda.serialization.internal.AllWhitelist
|
import net.corda.serialization.internal.AllWhitelist
|
||||||
import net.corda.serialization.internal.amqp.testutils.TestSerializationOutput
|
import net.corda.serialization.internal.amqp.testutils.*
|
||||||
import net.corda.serialization.internal.amqp.testutils.testDefaultFactoryNoEvolution
|
import net.corda.serialization.internal.carpenter.*
|
||||||
import net.corda.serialization.internal.amqp.testutils.testDefaultFactoryWithWhitelist
|
|
||||||
import net.corda.serialization.internal.amqp.testutils.serialize
|
|
||||||
import net.corda.serialization.internal.amqp.testutils.deserialize
|
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import kotlin.test.*
|
import kotlin.test.assertEquals
|
||||||
|
import kotlin.test.assertNotEquals
|
||||||
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
@CordaSerializable
|
@CordaSerializable
|
||||||
interface I {
|
interface I {
|
||||||
|
@ -46,8 +46,8 @@ class FingerPrinterTestingTests {
|
|||||||
val factory = SerializerFactory(
|
val factory = SerializerFactory(
|
||||||
AllWhitelist,
|
AllWhitelist,
|
||||||
ClassLoader.getSystemClassLoader(),
|
ClassLoader.getSystemClassLoader(),
|
||||||
EvolutionSerializerGetterTesting(),
|
evolutionSerializerGetter = EvolutionSerializerGetterTesting(),
|
||||||
FingerPrinterTesting())
|
fingerPrinter = FingerPrinterTesting())
|
||||||
|
|
||||||
val blob = TestSerializationOutput(VERBOSE, factory).serializeAndReturnSchema(C(1, 2L))
|
val blob = TestSerializationOutput(VERBOSE, factory).serializeAndReturnSchema(C(1, 2L))
|
||||||
|
|
||||||
|
@ -7,13 +7,7 @@ import com.nhaarman.mockito_kotlin.whenever
|
|||||||
import net.corda.client.rpc.RPCException
|
import net.corda.client.rpc.RPCException
|
||||||
import net.corda.core.CordaException
|
import net.corda.core.CordaException
|
||||||
import net.corda.core.CordaRuntimeException
|
import net.corda.core.CordaRuntimeException
|
||||||
import net.corda.core.contracts.Amount
|
import net.corda.core.contracts.*
|
||||||
import net.corda.core.contracts.Contract
|
|
||||||
import net.corda.core.contracts.ContractAttachment
|
|
||||||
import net.corda.core.contracts.ContractState
|
|
||||||
import net.corda.core.contracts.PrivacySalt
|
|
||||||
import net.corda.core.contracts.StateRef
|
|
||||||
import net.corda.core.contracts.TransactionState
|
|
||||||
import net.corda.core.crypto.Crypto
|
import net.corda.core.crypto.Crypto
|
||||||
import net.corda.core.crypto.SecureHash
|
import net.corda.core.crypto.SecureHash
|
||||||
import net.corda.core.crypto.secureRandomBytes
|
import net.corda.core.crypto.secureRandomBytes
|
||||||
@ -22,48 +16,25 @@ import net.corda.core.identity.AbstractParty
|
|||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.identity.CordaX500Name
|
||||||
import net.corda.core.internal.AbstractAttachment
|
import net.corda.core.internal.AbstractAttachment
|
||||||
import net.corda.core.internal.x500Name
|
import net.corda.core.internal.x500Name
|
||||||
import net.corda.core.serialization.ConstructorForDeserialization
|
import net.corda.core.serialization.*
|
||||||
import net.corda.core.serialization.CordaSerializable
|
|
||||||
import net.corda.core.serialization.EncodingWhitelist
|
|
||||||
import net.corda.core.serialization.MissingAttachmentsException
|
|
||||||
import net.corda.core.serialization.SerializationContext
|
|
||||||
import net.corda.core.serialization.SerializationFactory
|
|
||||||
import net.corda.core.transactions.LedgerTransaction
|
import net.corda.core.transactions.LedgerTransaction
|
||||||
import net.corda.core.utilities.OpaqueBytes
|
import net.corda.core.utilities.OpaqueBytes
|
||||||
import net.corda.node.serialization.amqp.AMQPServerSerializationScheme
|
import net.corda.node.serialization.amqp.AMQPServerSerializationScheme
|
||||||
import net.corda.nodeapi.internal.DEV_INTERMEDIATE_CA
|
import net.corda.nodeapi.internal.DEV_INTERMEDIATE_CA
|
||||||
import net.corda.nodeapi.internal.crypto.ContentSignerBuilder
|
import net.corda.nodeapi.internal.crypto.ContentSignerBuilder
|
||||||
import net.corda.serialization.internal.AllWhitelist
|
import net.corda.serialization.internal.*
|
||||||
import net.corda.serialization.internal.CordaSerializationEncoding
|
|
||||||
import net.corda.serialization.internal.EmptyWhitelist
|
|
||||||
import net.corda.serialization.internal.GeneratedAttachment
|
|
||||||
import net.corda.serialization.internal.amqp.SerializerFactory.Companion.isPrimitive
|
import net.corda.serialization.internal.amqp.SerializerFactory.Companion.isPrimitive
|
||||||
import net.corda.serialization.internal.amqp.testutils.deserialize
|
import net.corda.serialization.internal.amqp.testutils.*
|
||||||
import net.corda.serialization.internal.amqp.testutils.serialize
|
|
||||||
import net.corda.serialization.internal.amqp.testutils.testDefaultFactory
|
|
||||||
import net.corda.serialization.internal.amqp.testutils.testDefaultFactoryNoEvolution
|
|
||||||
import net.corda.serialization.internal.amqp.testutils.testSerializationContext
|
|
||||||
import net.corda.serialization.internal.encodingNotPermittedFormat
|
|
||||||
import net.corda.testing.contracts.DummyContract
|
import net.corda.testing.contracts.DummyContract
|
||||||
import net.corda.testing.core.BOB_NAME
|
import net.corda.testing.core.BOB_NAME
|
||||||
import net.corda.testing.core.SerializationEnvironmentRule
|
import net.corda.testing.core.SerializationEnvironmentRule
|
||||||
import net.corda.testing.core.TestIdentity
|
import net.corda.testing.core.TestIdentity
|
||||||
import net.corda.testing.internal.rigorousMock
|
import net.corda.testing.internal.rigorousMock
|
||||||
import org.apache.activemq.artemis.api.core.SimpleString
|
import org.apache.activemq.artemis.api.core.SimpleString
|
||||||
import org.apache.qpid.proton.amqp.Decimal128
|
import org.apache.qpid.proton.amqp.*
|
||||||
import org.apache.qpid.proton.amqp.Decimal32
|
|
||||||
import org.apache.qpid.proton.amqp.Decimal64
|
|
||||||
import org.apache.qpid.proton.amqp.Symbol
|
|
||||||
import org.apache.qpid.proton.amqp.UnsignedByte
|
|
||||||
import org.apache.qpid.proton.amqp.UnsignedInteger
|
|
||||||
import org.apache.qpid.proton.amqp.UnsignedLong
|
|
||||||
import org.apache.qpid.proton.amqp.UnsignedShort
|
|
||||||
import org.apache.qpid.proton.codec.DecoderImpl
|
import org.apache.qpid.proton.codec.DecoderImpl
|
||||||
import org.apache.qpid.proton.codec.EncoderImpl
|
import org.apache.qpid.proton.codec.EncoderImpl
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.*
|
||||||
import org.assertj.core.api.Assertions.assertThatExceptionOfType
|
|
||||||
import org.assertj.core.api.Assertions.assertThatThrownBy
|
|
||||||
import org.assertj.core.api.Assertions.catchThrowable
|
|
||||||
import org.bouncycastle.cert.X509v2CRLBuilder
|
import org.bouncycastle.cert.X509v2CRLBuilder
|
||||||
import org.bouncycastle.cert.jcajce.JcaX509CRLConverter
|
import org.bouncycastle.cert.jcajce.JcaX509CRLConverter
|
||||||
import org.bouncycastle.jce.provider.BouncyCastleProvider
|
import org.bouncycastle.jce.provider.BouncyCastleProvider
|
||||||
@ -79,20 +50,7 @@ import java.io.NotSerializableException
|
|||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
import java.math.BigInteger
|
import java.math.BigInteger
|
||||||
import java.security.cert.X509CRL
|
import java.security.cert.X509CRL
|
||||||
import java.time.DayOfWeek
|
import java.time.*
|
||||||
import java.time.Duration
|
|
||||||
import java.time.Instant
|
|
||||||
import java.time.LocalDate
|
|
||||||
import java.time.LocalDateTime
|
|
||||||
import java.time.LocalTime
|
|
||||||
import java.time.Month
|
|
||||||
import java.time.MonthDay
|
|
||||||
import java.time.OffsetDateTime
|
|
||||||
import java.time.OffsetTime
|
|
||||||
import java.time.Period
|
|
||||||
import java.time.Year
|
|
||||||
import java.time.YearMonth
|
|
||||||
import java.time.ZonedDateTime
|
|
||||||
import java.time.temporal.ChronoUnit
|
import java.time.temporal.ChronoUnit
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.reflect.full.superclasses
|
import kotlin.reflect.full.superclasses
|
||||||
@ -249,9 +207,13 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
|
|||||||
if (compression != null) doReturn(true).whenever(it).acceptEncoding(compression)
|
if (compression != null) doReturn(true).whenever(it).acceptEncoding(compression)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun defaultFactory() = SerializerFactory(
|
private fun defaultFactory(): SerializerFactory {
|
||||||
AllWhitelist, ClassLoader.getSystemClassLoader(),
|
return SerializerFactory(
|
||||||
EvolutionSerializerGetterTesting())
|
AllWhitelist,
|
||||||
|
ClassLoader.getSystemClassLoader(),
|
||||||
|
evolutionSerializerGetter = EvolutionSerializerGetterTesting()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private inline fun <reified T : Any> serdes(obj: T,
|
private inline fun <reified T : Any> serdes(obj: T,
|
||||||
factory: SerializerFactory = defaultFactory(),
|
factory: SerializerFactory = defaultFactory(),
|
||||||
|
@ -1,16 +1,25 @@
|
|||||||
package net.corda.serialization.internal.amqp.testutils
|
package net.corda.serialization.internal.amqp.testutils
|
||||||
|
|
||||||
|
import net.corda.core.internal.copyTo
|
||||||
|
import net.corda.core.internal.div
|
||||||
|
import net.corda.core.internal.packageName
|
||||||
import net.corda.core.serialization.SerializationContext
|
import net.corda.core.serialization.SerializationContext
|
||||||
import net.corda.core.serialization.SerializedBytes
|
import net.corda.core.serialization.SerializedBytes
|
||||||
import org.apache.qpid.proton.codec.Data
|
import net.corda.core.utilities.OpaqueBytes
|
||||||
import net.corda.serialization.internal.AllWhitelist
|
import net.corda.serialization.internal.AllWhitelist
|
||||||
import net.corda.serialization.internal.EmptyWhitelist
|
import net.corda.serialization.internal.EmptyWhitelist
|
||||||
import net.corda.serialization.internal.amqp.*
|
import net.corda.serialization.internal.amqp.*
|
||||||
|
import net.corda.testing.common.internal.ProjectStructure
|
||||||
|
import org.apache.qpid.proton.codec.Data
|
||||||
|
import org.junit.Test
|
||||||
|
import java.io.File.separatorChar
|
||||||
import java.io.NotSerializableException
|
import java.io.NotSerializableException
|
||||||
|
import java.nio.file.StandardCopyOption.REPLACE_EXISTING
|
||||||
|
|
||||||
fun testDefaultFactory() = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
|
fun testDefaultFactory() = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
|
||||||
fun testDefaultFactoryNoEvolution() = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader(),
|
fun testDefaultFactoryNoEvolution(): SerializerFactory {
|
||||||
EvolutionSerializerGetterTesting())
|
return SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader(), evolutionSerializerGetter = EvolutionSerializerGetterTesting())
|
||||||
|
}
|
||||||
fun testDefaultFactoryWithWhitelist() = SerializerFactory(EmptyWhitelist, ClassLoader.getSystemClassLoader())
|
fun testDefaultFactoryWithWhitelist() = SerializerFactory(EmptyWhitelist, ClassLoader.getSystemClassLoader())
|
||||||
|
|
||||||
class TestSerializationOutput(
|
class TestSerializationOutput(
|
||||||
@ -41,8 +50,25 @@ class TestSerializationOutput(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun testName(): String = Thread.currentThread().stackTrace[2].methodName
|
fun testName(): String {
|
||||||
|
val classLoader = Thread.currentThread().contextClassLoader
|
||||||
|
return Thread.currentThread().stackTrace.first {
|
||||||
|
try {
|
||||||
|
classLoader.loadClass(it.className).getMethod(it.methodName).isAnnotationPresent(Test::class.java)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}.methodName
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Any.testResourceName(): String = "${javaClass.simpleName}.${testName()}"
|
||||||
|
|
||||||
|
fun Any.writeTestResource(bytes: OpaqueBytes) {
|
||||||
|
val dir = ProjectStructure.projectRootDir / "serialization" / "src" / "test" / "resources" / javaClass.packageName.replace('.', separatorChar)
|
||||||
|
bytes.open().copyTo(dir / testResourceName(), REPLACE_EXISTING)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Any.readTestResource(): ByteArray = javaClass.getResourceAsStream(testResourceName()).readBytes()
|
||||||
|
|
||||||
@Throws(NotSerializableException::class)
|
@Throws(NotSerializableException::class)
|
||||||
inline fun <reified T : Any> DeserializationInput.deserializeAndReturnEnvelope(
|
inline fun <reified T : Any> DeserializationInput.deserializeAndReturnEnvelope(
|
||||||
|
@ -2,6 +2,7 @@ package net.corda.serialization.internal.carpenter
|
|||||||
|
|
||||||
import net.corda.core.internal.uncheckedCast
|
import net.corda.core.internal.uncheckedCast
|
||||||
import net.corda.serialization.internal.AllWhitelist
|
import net.corda.serialization.internal.AllWhitelist
|
||||||
|
import org.assertj.core.api.Assertions.assertThatExceptionOfType
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.beans.Introspector
|
import java.beans.Introspector
|
||||||
import java.lang.reflect.Field
|
import java.lang.reflect.Field
|
||||||
@ -145,21 +146,40 @@ class ClassCarpenterTest {
|
|||||||
assertEquals(1, i.b)
|
assertEquals(1, i.b)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = InterfaceMismatchException::class)
|
@Test
|
||||||
fun `mismatched interface`() {
|
fun `unimplemented interface method with lenient = false`() {
|
||||||
val schema1 = ClassSchema(
|
val schemaA = ClassSchema(
|
||||||
"gen.A",
|
"gen.A",
|
||||||
mapOf("a" to NonNullableField(String::class.java)))
|
mapOf("a" to NonNullableField(String::class.java)))
|
||||||
|
|
||||||
val schema2 = ClassSchema(
|
val schemaB = ClassSchema(
|
||||||
"gen.B",
|
"gen.B",
|
||||||
mapOf("c" to NonNullableField(Int::class.java)),
|
mapOf("c" to NonNullableField(Int::class.java)),
|
||||||
schema1,
|
schemaA,
|
||||||
interfaces = listOf(DummyInterface::class.java))
|
interfaces = listOf(DummyInterface::class.java))
|
||||||
|
|
||||||
val clazz = cc.build(schema2)
|
assertThatExceptionOfType(InterfaceMismatchException::class.java).isThrownBy { cc.build(schemaB) }
|
||||||
val i = clazz.constructors[0].newInstance("xa", 1) as DummyInterface
|
}
|
||||||
assertEquals(1, i.b)
|
|
||||||
|
@Test
|
||||||
|
fun `unimplemented interface method with lenient = true`() {
|
||||||
|
val cc = ClassCarpenterImpl(whitelist = AllWhitelist, lenient = true)
|
||||||
|
|
||||||
|
val schemaA = ClassSchema(
|
||||||
|
"gen.A",
|
||||||
|
mapOf("a" to NonNullableField(String::class.java)))
|
||||||
|
|
||||||
|
val schemaB = ClassSchema(
|
||||||
|
"gen.B",
|
||||||
|
mapOf("c" to NonNullableField(Int::class.java)),
|
||||||
|
schemaA,
|
||||||
|
interfaces = listOf(DummyInterface::class.java))
|
||||||
|
|
||||||
|
val classB = cc.build(schemaB)
|
||||||
|
val b = classB.constructors[0].newInstance("xa", 1) as DummyInterface
|
||||||
|
assertEquals("xa", b.a)
|
||||||
|
assertEquals(1, classB.getMethod("getC").invoke(b))
|
||||||
|
assertThatExceptionOfType(AbstractMethodError::class.java).isThrownBy { b.b }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -5,6 +5,7 @@ import net.corda.serialization.internal.amqp.*
|
|||||||
import net.corda.serialization.internal.amqp.Field
|
import net.corda.serialization.internal.amqp.Field
|
||||||
import net.corda.serialization.internal.amqp.Schema
|
import net.corda.serialization.internal.amqp.Schema
|
||||||
import net.corda.serialization.internal.amqp.testutils.serialize
|
import net.corda.serialization.internal.amqp.testutils.serialize
|
||||||
|
import net.corda.serialization.internal.amqp.testutils.testName
|
||||||
|
|
||||||
fun mangleName(name: String) = "${name}__carpenter"
|
fun mangleName(name: String) = "${name}__carpenter"
|
||||||
|
|
||||||
@ -47,7 +48,6 @@ open class AmqpCarpenterBase(whitelist: ClassWhitelist) {
|
|||||||
var factory = SerializerFactoryExternalCarpenter(cc)
|
var factory = SerializerFactoryExternalCarpenter(cc)
|
||||||
|
|
||||||
fun serialise(clazz: Any) = SerializationOutput(factory).serialize(clazz)
|
fun serialise(clazz: Any) = SerializationOutput(factory).serialize(clazz)
|
||||||
fun testName(): String = Thread.currentThread().stackTrace[2].methodName
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
inline fun classTestName(clazz: String) = "${this.javaClass.name}\$${testName()}\$$clazz"
|
inline fun classTestName(clazz: String) = "${this.javaClass.name}\$${testName()}\$$clazz"
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,49 @@
|
|||||||
|
package net.corda.serialization.internal.carpenter
|
||||||
|
|
||||||
|
import net.corda.core.serialization.CordaSerializable
|
||||||
|
import net.corda.core.serialization.SerializationFactory
|
||||||
|
import net.corda.core.serialization.deserialize
|
||||||
|
import net.corda.serialization.internal.amqp.testutils.readTestResource
|
||||||
|
import net.corda.testing.core.SerializationEnvironmentRule
|
||||||
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
|
import org.assertj.core.api.Assertions.assertThatExceptionOfType
|
||||||
|
import org.junit.Rule
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
class SerDeserCarpentryTest {
|
||||||
|
@Rule
|
||||||
|
@JvmField
|
||||||
|
val testSerialization = SerializationEnvironmentRule()
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun implementingGenericInterface() {
|
||||||
|
// Original class that was serialised
|
||||||
|
// data class GenericData(val a: Int) : GenericInterface<String>
|
||||||
|
// writeTestResource(GenericData(123).serialize())
|
||||||
|
|
||||||
|
val data = readTestResource().deserialize<GenericInterface<*>>()
|
||||||
|
assertThat(data.javaClass.getMethod("getA").invoke(data)).isEqualTo(123)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun lenientCarpenter() {
|
||||||
|
// Original class that was serialised
|
||||||
|
// data class Data(val b: Int) : AInterface {
|
||||||
|
// override val a: Int get() = b
|
||||||
|
// }
|
||||||
|
// writeTestResource(Data(123).serialize())
|
||||||
|
|
||||||
|
val data = readTestResource().deserialize<AInterface>(context = SerializationFactory.defaultFactory.defaultContext.withLenientCarpenter())
|
||||||
|
assertThat(data.javaClass.getMethod("getB").invoke(data)).isEqualTo(123)
|
||||||
|
assertThatExceptionOfType(AbstractMethodError::class.java).isThrownBy { data.a }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
|
@CordaSerializable
|
||||||
|
interface GenericInterface<T>
|
||||||
|
|
||||||
|
@CordaSerializable
|
||||||
|
interface AInterface {
|
||||||
|
val a: Int
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
Binary file not shown.
@ -7,6 +7,7 @@ import net.corda.client.jackson.JacksonSupport
|
|||||||
import net.corda.core.internal.isRegularFile
|
import net.corda.core.internal.isRegularFile
|
||||||
import net.corda.core.internal.rootMessage
|
import net.corda.core.internal.rootMessage
|
||||||
import net.corda.core.serialization.SerializationContext
|
import net.corda.core.serialization.SerializationContext
|
||||||
|
import net.corda.core.serialization.SerializationFactory
|
||||||
import net.corda.core.serialization.deserialize
|
import net.corda.core.serialization.deserialize
|
||||||
import net.corda.core.serialization.internal.SerializationEnvironmentImpl
|
import net.corda.core.serialization.internal.SerializationEnvironmentImpl
|
||||||
import net.corda.core.serialization.internal._contextSerializationEnv
|
import net.corda.core.serialization.internal._contextSerializationEnv
|
||||||
@ -33,7 +34,7 @@ fun main(args: Array<String>) {
|
|||||||
if (main.verbose) {
|
if (main.verbose) {
|
||||||
throwable.printStackTrace()
|
throwable.printStackTrace()
|
||||||
} else {
|
} else {
|
||||||
System.err.println("*ERROR*: ${throwable.rootMessage ?: "Use --verbose for more details"}")
|
System.err.println("*ERROR*: ${throwable.rootMessage}. Use --verbose for more details")
|
||||||
}
|
}
|
||||||
exitProcess(1)
|
exitProcess(1)
|
||||||
}
|
}
|
||||||
@ -91,7 +92,8 @@ class Main : Runnable {
|
|||||||
}
|
}
|
||||||
val mapper = JacksonSupport.createNonRpcMapper(factory, fullParties)
|
val mapper = JacksonSupport.createNonRpcMapper(factory, fullParties)
|
||||||
|
|
||||||
val deserialized = bytes.deserialize<Any>()
|
// Deserialise with the lenient carpenter as we only care for the AMQP field getters
|
||||||
|
val deserialized = bytes.deserialize<Any>(context = SerializationFactory.defaultFactory.defaultContext.withLenientCarpenter())
|
||||||
println(deserialized.javaClass.name)
|
println(deserialized.javaClass.name)
|
||||||
mapper.writeValue(System.out, deserialized)
|
mapper.writeValue(System.out, deserialized)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user