mirror of
https://github.com/corda/corda.git
synced 2025-01-31 08:25:50 +00:00
Use Java reflection for determining if a type is a Kotlin singleton. (#2446)
Kotlin's own reflection has a habit of throwing weird errors and does not work for private objects - thus the unit test which tests this feature has actually never worked properly, but somehow works by accident. An attempt to upgrade to the latest Kotlin revealed the issue so it must have always been unstable.
This commit is contained in:
parent
82ece34ac8
commit
38ccd0572c
@ -6,14 +6,15 @@ import com.esotericsoftware.kryo.io.Output
|
|||||||
import com.esotericsoftware.kryo.serializers.FieldSerializer
|
import com.esotericsoftware.kryo.serializers.FieldSerializer
|
||||||
import com.esotericsoftware.kryo.util.DefaultClassResolver
|
import com.esotericsoftware.kryo.util.DefaultClassResolver
|
||||||
import com.esotericsoftware.kryo.util.Util
|
import com.esotericsoftware.kryo.util.Util
|
||||||
import net.corda.nodeapi.internal.AttachmentsClassLoader
|
|
||||||
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.serialization.SerializationContext
|
import net.corda.core.serialization.SerializationContext
|
||||||
import net.corda.core.utilities.contextLogger
|
import net.corda.core.utilities.contextLogger
|
||||||
|
import net.corda.nodeapi.internal.AttachmentsClassLoader
|
||||||
import net.corda.nodeapi.internal.serialization.amqp.hasAnnotationInHierarchy
|
import net.corda.nodeapi.internal.serialization.amqp.hasAnnotationInHierarchy
|
||||||
import net.corda.nodeapi.internal.serialization.kryo.ThrowableSerializer
|
import net.corda.nodeapi.internal.serialization.kryo.ThrowableSerializer
|
||||||
import java.io.PrintWriter
|
import java.io.PrintWriter
|
||||||
|
import java.lang.reflect.Modifier
|
||||||
import java.lang.reflect.Modifier.isAbstract
|
import java.lang.reflect.Modifier.isAbstract
|
||||||
import java.nio.charset.StandardCharsets
|
import java.nio.charset.StandardCharsets
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
@ -74,10 +75,21 @@ class CordaClassResolver(serializationContext: SerializationContext) : DefaultCl
|
|||||||
|
|
||||||
override fun registerImplicit(type: Class<*>): Registration {
|
override fun registerImplicit(type: Class<*>): Registration {
|
||||||
val targetType = typeForSerializationOf(type)
|
val targetType = typeForSerializationOf(type)
|
||||||
|
// Is this a Kotlin object? We use our own reflection here rather than .kotlin.objectInstance because Kotlin
|
||||||
|
// reflection won't work for private objects, and can throw exceptions in other circumstances as well.
|
||||||
val objectInstance = try {
|
val objectInstance = try {
|
||||||
targetType.kotlin.objectInstance
|
targetType.declaredFields.singleOrNull {
|
||||||
|
it.name == "INSTANCE" &&
|
||||||
|
it.type == type &&
|
||||||
|
Modifier.isStatic(it.modifiers) &&
|
||||||
|
Modifier.isFinal(it.modifiers) &&
|
||||||
|
Modifier.isPublic(it.modifiers)
|
||||||
|
}?.let {
|
||||||
|
it.isAccessible = true
|
||||||
|
type.cast(it.get(null)!!)
|
||||||
|
}
|
||||||
} catch (t: Throwable) {
|
} catch (t: Throwable) {
|
||||||
null // objectInstance will throw if the type is something like a lambda
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
// We have to set reference to true, since the flag influences how String fields are treated and we want it to be consistent.
|
// We have to set reference to true, since the flag influences how String fields are treated and we want it to be consistent.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user