mirror of
https://github.com/corda/corda.git
synced 2025-06-13 04:38:19 +00:00
CORDA-540: Expose and fix AMQP serialization problem with UniquenessException (#1470)
This commit is contained in:
@ -37,6 +37,7 @@ class MapSerializer(private val declaredType: ParameterizedType, factory: Serial
|
||||
}
|
||||
|
||||
fun deriveParameterizedType(declaredType: Type, declaredClass: Class<*>, actualClass: Class<*>?): ParameterizedType {
|
||||
declaredClass.checkSupportedMapType()
|
||||
if(supportedTypes.containsKey(declaredClass)) {
|
||||
// Simple case - it is already known to be a map.
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
@ -71,7 +72,7 @@ class MapSerializer(private val declaredType: ParameterizedType, factory: Serial
|
||||
}
|
||||
|
||||
override fun writeObject(obj: Any, data: Data, type: Type, output: SerializationOutput) {
|
||||
obj.javaClass.checkNotUnsupportedHashMap()
|
||||
obj.javaClass.checkSupportedMapType()
|
||||
// Write described
|
||||
data.withDescribed(typeNotation.descriptor) {
|
||||
// Write map
|
||||
@ -96,7 +97,7 @@ class MapSerializer(private val declaredType: ParameterizedType, factory: Serial
|
||||
input.readObjectOrNull(entry.value, schema, declaredType.actualTypeArguments[1])
|
||||
}
|
||||
|
||||
internal fun Class<*>.checkNotUnsupportedHashMap() {
|
||||
internal fun Class<*>.checkSupportedMapType() {
|
||||
if (HashMap::class.java.isAssignableFrom(this) && !LinkedHashMap::class.java.isAssignableFrom(this)) {
|
||||
throw IllegalArgumentException(
|
||||
"Map type $this is unstable under iteration. Suggested fix: use java.util.LinkedHashMap instead.")
|
||||
|
@ -75,7 +75,7 @@ class SerializerFactory(val whitelist: ClassWhitelist, cl: ClassLoader) {
|
||||
(Map::class.java.isAssignableFrom(declaredClass) ||
|
||||
(actualClass != null && Map::class.java.isAssignableFrom(actualClass))) -> {
|
||||
val declaredTypeAmended= MapSerializer.deriveParameterizedType(declaredType, declaredClass, actualClass)
|
||||
serializersByType.computeIfAbsent(declaredClass) {
|
||||
serializersByType.computeIfAbsent(declaredTypeAmended) {
|
||||
makeMapSerializer(declaredTypeAmended)
|
||||
}
|
||||
}
|
||||
@ -288,7 +288,7 @@ class SerializerFactory(val whitelist: ClassWhitelist, cl: ClassLoader) {
|
||||
|
||||
private fun makeMapSerializer(declaredType: ParameterizedType): AMQPSerializer<Any> {
|
||||
val rawType = declaredType.rawType as Class<*>
|
||||
rawType.checkNotUnsupportedHashMap()
|
||||
rawType.checkSupportedMapType()
|
||||
return MapSerializer(declaredType, this)
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,7 @@ class ThrowableSerializer(factory: SerializerFactory) : CustomSerializer.Proxy<T
|
||||
extraProperties[prop.name] = prop.readMethod!!.invoke(obj)
|
||||
}
|
||||
} catch(e: NotSerializableException) {
|
||||
logger.warn("Unexpected exception", e)
|
||||
}
|
||||
obj.originalMessage
|
||||
} else {
|
||||
|
@ -2,10 +2,9 @@ package net.corda.nodeapi.internal.serialization.amqp
|
||||
|
||||
import org.assertj.core.api.Assertions
|
||||
import org.junit.Test
|
||||
import java.io.NotSerializableException
|
||||
import java.util.*
|
||||
|
||||
class DeserializeCollectionTests {
|
||||
class DeserializeMapTests {
|
||||
companion object {
|
||||
/**
|
||||
* If you want to see the schema encoded into the envelope after serialisation change this to true
|
||||
@ -82,7 +81,7 @@ class DeserializeCollectionTests {
|
||||
|
||||
// expected to throw
|
||||
Assertions.assertThatThrownBy { TestSerializationOutput(VERBOSE, sf).serialize(c) }
|
||||
.isInstanceOf(NotSerializableException::class.java).hasMessageContaining("Cannot derive map type for declaredType")
|
||||
.isInstanceOf(IllegalArgumentException::class.java).hasMessageContaining("Unable to serialise deprecated type class java.util.Hashtable. Suggested fix: prefer java.util.map implementations")
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -92,7 +91,7 @@ class DeserializeCollectionTests {
|
||||
|
||||
// expect this to throw
|
||||
Assertions.assertThatThrownBy { TestSerializationOutput(VERBOSE, sf).serialize(c) }
|
||||
.isInstanceOf(NotSerializableException::class.java).hasMessageContaining("Cannot derive map type for declaredType")
|
||||
.isInstanceOf(IllegalArgumentException::class.java).hasMessageContaining("Map type class java.util.HashMap is unstable under iteration. Suggested fix: use java.util.LinkedHashMap instead.")
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -101,7 +100,7 @@ class DeserializeCollectionTests {
|
||||
val c = C (WeakHashMap (mapOf("A" to 1, "B" to 2)))
|
||||
|
||||
Assertions.assertThatThrownBy { TestSerializationOutput(VERBOSE, sf).serialize(c) }
|
||||
.isInstanceOf(NotSerializableException::class.java).hasMessageContaining("Cannot derive map type for declaredType")
|
||||
.isInstanceOf(IllegalArgumentException::class.java).hasMessageContaining("Weak references with map types not supported. Suggested fix: use java.util.LinkedHashMap instead.")
|
||||
}
|
||||
|
||||
@Test
|
||||
|
Reference in New Issue
Block a user