CORDA-1403 - Generics serialization issue (#3030)

When implementing a generic interface subtype check fails, need
to compare to the actual raw type
This commit is contained in:
Katelyn Baker 2018-05-01 16:27:54 +01:00 committed by GitHub
parent 33b9040efb
commit 0c680ae530
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 31 additions and 2 deletions

View File

@ -7,6 +7,10 @@ release, see :doc:`upgrade-notes`.
Unreleased 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.
* Fixed incorrect exception handling in ``NodeVaultService._query()``. * Fixed incorrect exception handling in ``NodeVaultService._query()``.
* Avoided a memory leak deriving from incorrect MappedSchema caching strategy. * Avoided a memory leak deriving from incorrect MappedSchema caching strategy.

View File

@ -480,10 +480,10 @@ internal fun Type.asParameterizedType(): ParameterizedType {
} }
internal fun Type.isSubClassOf(type: Type): Boolean { 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 { internal fun suitableForObjectReference(type: Type): Boolean {
val clazz = type.asClass() val clazz = type.asClass()
return type != ByteArray::class.java && (clazz != null && !clazz.isPrimitive && !Primitives.unwrap(clazz).isPrimitive) return type != ByteArray::class.java && (clazz != null && !clazz.isPrimitive && !Primitives.unwrap(clazz).isPrimitive)

View File

@ -1310,5 +1310,30 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
C(12).serializeE() C(12).serializeE()
}.withMessageContaining("has synthetic fields and is likely a nested inner class") }.withMessageContaining("has synthetic fields and is likely a nested inner class")
} }
interface DataClassByInterface<V> {
val v : V
}
@Test
fun dataClassBy() {
data class C (val s: String) : DataClassByInterface<String> {
override val v: String = "-- $s"
}
data class Inner<T>(val wrapped: DataClassByInterface<T>) : DataClassByInterface<T> 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")
}
}
} }