I have the following sealed class in a Kotlin project:
sealed class Test {
abstract val test: String
@NoArg
data class Test1(
override val test: String
) : Test()
@NoArg
data class Test2(
override val test: String
) : Test()
}
The @NoArg
annotation is a marker and the compiler is configured to generate a no argument constructor for these classes.
My problem is that trying to instantiate Test1
and Test2
using Java reflection results in the following exception:
Exception in thread "main" java.lang.reflect.InvocationTargetException
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at MainKt.main(Main.kt:27)
Caused by: java.lang.IllegalAccessError: tried to access method Test.<init>()V from class Test$Test1
at Test$Test1.<init>(Main.kt)
... 5 more
I initially encountered this problem when trying to load instances of these classes from a Mongo database using Spring Data Mongo.
The code I used to instantiate them during this test is the following:
val javaConstructor = Test.Test1::class.java.getConstructor()
?: error("Did not find constructor")
val instance = javaConstructor.newInstance()
My current workaround is to just not use a sealed class which solves the Exception. Is there a way I can keep the sealed class and make Java reflection work correctly? I don't think this is quite the intended behaviour, but maybe there is some sort of reason to this? If so, I'd be interested to hear what it is.
I have an example of my problem here: http://ift.tt/2srtbyy
Aucun commentaire:
Enregistrer un commentaire