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

+3


source to share





All Articles