Minor: fix an incorrect use (process specific) of reflection hashCodes in the Kryo wrapper.

This commit is contained in:
Mike Hearn 2016-02-03 12:47:24 +01:00
parent f51aa73687
commit 0417e24fae

View File

@ -26,11 +26,8 @@ import java.lang.reflect.InvocationTargetException
import java.security.KeyPairGenerator import java.security.KeyPairGenerator
import java.time.Instant import java.time.Instant
import java.util.* import java.util.*
import kotlin.reflect.KClass import kotlin.reflect.*
import kotlin.reflect.KMutableProperty
import kotlin.reflect.jvm.javaType import kotlin.reflect.jvm.javaType
import kotlin.reflect.memberProperties
import kotlin.reflect.primaryConstructor
/** /**
* Serialization utilities, using the Kryo framework with a custom serialiser for immutable data classes and a dead * Serialization utilities, using the Kryo framework with a custom serialiser for immutable data classes and a dead
@ -106,9 +103,16 @@ class ImmutableClassSerializer<T : Any>(val klass: KClass<T>) : Serializer<T>()
assert(props.none { it is KMutableProperty<*> }) assert(props.none { it is KMutableProperty<*> })
} }
// Just a utility to help us catch cases where nodes are running out of sync versions.
private fun hashParameters(params: List<KParameter>): Int {
return params.map {
(it.name ?: "") + it.index.toString() + it.type.javaType.typeName
}.hashCode()
}
override fun write(kryo: Kryo, output: Output, obj: T) { override fun write(kryo: Kryo, output: Output, obj: T) {
output.writeVarInt(constructor.parameters.size, true) output.writeVarInt(constructor.parameters.size, true)
output.writeInt(constructor.parameters.hashCode()) output.writeInt(hashParameters(constructor.parameters))
for (param in constructor.parameters) { for (param in constructor.parameters) {
val kProperty = propsByName[param.name!!]!! val kProperty = propsByName[param.name!!]!!
when (param.type.javaType.typeName) { when (param.type.javaType.typeName) {
@ -138,7 +142,7 @@ class ImmutableClassSerializer<T : Any>(val klass: KClass<T>) : Serializer<T>()
if (numFields != constructor.parameters.size) if (numFields != constructor.parameters.size)
throw KryoException("Mismatch between number of constructor parameters and number of serialised fields " + throw KryoException("Mismatch between number of constructor parameters and number of serialised fields " +
"for ${klass.qualifiedName} ($numFields vs ${constructor.parameters.size})") "for ${klass.qualifiedName} ($numFields vs ${constructor.parameters.size})")
if (fieldTypeHash != constructor.parameters.hashCode()) if (fieldTypeHash != hashParameters(constructor.parameters))
throw KryoException("Hashcode mismatch for parameter types for ${klass.qualifiedName}: unsupported type evolution has happened.") throw KryoException("Hashcode mismatch for parameter types for ${klass.qualifiedName}: unsupported type evolution has happened.")
val args = arrayOfNulls<Any?>(numFields) val args = arrayOfNulls<Any?>(numFields)