Java constructor reflection throws exception with private classes
I have the following hermetic 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()
}
Annotation @NoArg
is a marker, and the compiler is set up to generate a no argument constructor for these classes.
My problem is trying to instantiate Test1
and Test2
use the 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 originally ran into this issue when trying to load instances of these classes from Mongo database using Spring Data Mongo.
The code I used to generate 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 simply not use a private class that resolves the exception. Is there a way to keep the sealed class and make Java work correctly? I don't think this is entirely intended behavior, but maybe there is some reason for this? If so, I would be interested to know what it is.
I have an example of my problem here: https://github.com/mhlz/playground
source to share
No one has answered this question yet
Check out similar questions: