diff --git a/docs/source/changelog.rst b/docs/source/changelog.rst index 74f188ea0b..9837cf9f86 100644 --- a/docs/source/changelog.rst +++ b/docs/source/changelog.rst @@ -7,6 +7,10 @@ release, see :doc:`upgrade-notes`. Unreleased ========== +* Fix CORDA-1403 where a property of a class that implemented a generic interface could not be deserialised in + a factory without a serialiser as the subtype check for the class instance failed. Fix is to compare the raw + type. + * Fix CORDA-1229. Setter-based serialization was broken with generic types when the property was stored as the raw type, List for example. diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/SerializationHelper.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/SerializationHelper.kt index 7a207f3cd1..14061faa0b 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/SerializationHelper.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/SerializationHelper.kt @@ -471,10 +471,10 @@ internal fun Type.asParameterizedType(): ParameterizedType { } internal fun Type.isSubClassOf(type: Type): Boolean { - return TypeToken.of(this).isSubtypeOf(type) + return TypeToken.of(this).isSubtypeOf(TypeToken.of(type).rawType) } -// ByteArrays, primtives and boxed primitives are not stored in the object history +// ByteArrays, primitives and boxed primitives are not stored in the object history internal fun suitableForObjectReference(type: Type): Boolean { val clazz = type.asClass() return type != ByteArray::class.java && (clazz != null && !clazz.isPrimitive && !Primitives.unwrap(clazz).isPrimitive) diff --git a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/SerializationOutputTests.kt b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/SerializationOutputTests.kt index 6d106e698a..a7440f9d30 100644 --- a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/SerializationOutputTests.kt +++ b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/SerializationOutputTests.kt @@ -1146,4 +1146,29 @@ class SerializationOutputTests { // The "test" is that this doesn't throw, anything else is a success PrivateAckWrapper.serialize() } + + interface DataClassByInterface { + val v : V + } + + @Test + fun dataClassBy() { + data class C (val s: String) : DataClassByInterface { + override val v: String = "-- $s" + } + + data class Inner(val wrapped: DataClassByInterface) : DataClassByInterface by wrapped { + override val v = wrapped.v + } + + val i = Inner(C("hello")) + + val bytes = SerializationOutput(testDefaultFactory()).serialize(i) + + try { + val i2 = DeserializationInput(testDefaultFactory()).deserialize(bytes) + } catch (e : NotSerializableException) { + throw Error ("Deserializing serialized \$C should not throw") + } + } }