Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kotlin reflection fails in native build in some cases that Java reflection success #8479

Closed
kdubb opened this issue Apr 8, 2020 · 16 comments · Fixed by #23419
Closed

Kotlin reflection fails in native build in some cases that Java reflection success #8479

kdubb opened this issue Apr 8, 2020 · 16 comments · Fixed by #23419
Assignees
Labels
area/kotlin kind/bug Something isn't working
Milestone

Comments

@kdubb
Copy link
Contributor

kdubb commented Apr 8, 2020

Kotlin method references (e.g. this::someMethod) have a s nice shorthand for retrieving the reflection java.lang.reflect.Method via the javaMethod property as in this::someMethod.javaMethod.

When using a JAX-RS UriInfo to build location headers, using the reflected method reference is a great way to keep things DRY so as not to repeat path information stated in a @Path annotation.

For example:

    @POST
    fun create(@Context uriInfo: UriInfo) =
    	Response
    		.created(
    			uriInfo.requestUriBuilder
    				.path(this::fetch.javaMethod) // Fetches path from the @Path annotation of the "fetch" method
    				.buildFromMap(mapOf(
    					"id" to "12345"
    				))
    		)
    		.entity(mapOf("id" to "12345", "name" to "test"))
    		.build()


    @GET
    @Path("{id}")
    fun fetch(@PathParam("id") id: String) =
    	Response
    		.ok()
    		.entity(mapOf("id" to "12345", "name" to "test"))
    		.build()

Using Kotlin references is a great shorthand and keeps things type safe and compile type checked as compared to using Java...

In Kotlin

path(this::fetch.javaMethod)

In Java

path(GreetingResource::class.java.getDeclaredMethod("fetch", String::class.java))

As usual, all is well in JVM mode (and both examples work correctly) but in native mode the Kotlin version throws an error deep in the bowels of its reflection library.

Expected behavior

Kotlin's reflection tools work the same as equivalent Java reflection in both JVM and native builds.

Actual behavior

In native builds Kotlin reflection for method references fails.

To Reproduce

rest-kotlin-quickstart.zip

Environment (please complete the following information):

  • Output of uname -a or ver:

     Darwin #### 19.4.0 Darwin Kernel Version 19.4.0: Wed Mar  4 22:28:40 PST 2020; root:xnu-6153.101.6~15/RELEASE_X86_64 x86_64`
    
  • Output of java -version:

     openjdk version "14" 2020-03-17
     OpenJDK Runtime Environment (build 14+36-1461)
     OpenJDK 64-Bit Server VM (build 14+36-1461, mixed mode, sharing)
    
  • Quarkus version or git rev:

     1.3.2
    
  • Build tool (ie. output of mvnw --version or gradlew --version):

     Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
     Default locale: en_US, platform encoding: UTF-8
     OS name: "mac os x", version: "10.15.4", arch: "x86_64", family: "Mac"
    
@kdubb kdubb added the kind/bug Something isn't working label Apr 8, 2020
@geoand
Copy link
Contributor

geoand commented Apr 9, 2020

Can you paste the error you get please?

@kdubb
Copy link
Contributor Author

kdubb commented Apr 9, 2020

The error is related to invalid state deep inside Kotlin's library. Here is the stack trace...

java.lang.IllegalStateException: @NotNull method kotlin/reflect/jvm/internal/impl/builtins/KotlinBuiltIns.getBuiltInClassByFqName must not return null
        at kotlin.reflect.jvm.internal.impl.builtins.KotlinBuiltIns.$$$reportNull$$$0(KotlinBuiltIns.java)
        at kotlin.reflect.jvm.internal.impl.builtins.KotlinBuiltIns.getBuiltInClassByFqName(KotlinBuiltIns.java:357)
        at kotlin.reflect.jvm.internal.impl.builtins.jvm.JavaToKotlinClassMap.mapJavaToKotlin(JavaToKotlinClassMap.kt:130)
        at kotlin.reflect.jvm.internal.impl.builtins.jvm.JavaToKotlinClassMap.mapJavaToKotlin$default(JavaToKotlinClassMap.kt:126)
        at kotlin.reflect.jvm.internal.impl.load.java.lazy.types.JavaTypeResolver.mapKotlinClass(JavaTypeResolver.kt:161)
        at kotlin.reflect.jvm.internal.impl.load.java.lazy.types.JavaTypeResolver.computeTypeConstructor(JavaTypeResolver.kt:135)
        at kotlin.reflect.jvm.internal.impl.load.java.lazy.types.JavaTypeResolver.computeSimpleJavaClassifierType(JavaTypeResolver.kt:117)
        at kotlin.reflect.jvm.internal.impl.load.java.lazy.types.JavaTypeResolver.transformJavaClassifierType(JavaTypeResolver.kt:93)
        at kotlin.reflect.jvm.internal.impl.load.java.lazy.types.JavaTypeResolver.transformJavaType(JavaTypeResolver.kt:52)
        at kotlin.reflect.jvm.internal.impl.load.java.lazy.descriptors.LazyJavaClassDescriptor$LazyJavaClassTypeConstructor.computeSupertypes(LazyJavaClassDescriptor.kt:191)
        at kotlin.reflect.jvm.internal.impl.types.AbstractTypeConstructor$supertypes$1.invoke(AbstractTypeConstructor.kt:80)
        at kotlin.reflect.jvm.internal.impl.types.AbstractTypeConstructor$supertypes$1.invoke(AbstractTypeConstructor.kt:26)
        at kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$LockBasedLazyValue.invoke(LockBasedStorageManager.java:355)
        at kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$LockBasedLazyValueWithPostCompute.invoke(LockBasedStorageManager.java:428)
        at kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$LockBasedNotNullLazyValueWithPostCompute.invoke(LockBasedStorageManager.java:459)
        at kotlin.reflect.jvm.internal.impl.types.AbstractTypeConstructor.getSupertypes(AbstractTypeConstructor.kt:27)
        at kotlin.reflect.jvm.internal.impl.types.AbstractTypeConstructor.getSupertypes(AbstractTypeConstructor.kt:26)
        at kotlin.reflect.jvm.internal.impl.load.java.lazy.descriptors.LazyJavaClassMemberScope.computeFunctionNames(LazyJavaClassMemberScope.kt:78)
        at kotlin.reflect.jvm.internal.impl.load.java.lazy.descriptors.LazyJavaClassMemberScope.computeFunctionNames(LazyJavaClassMemberScope.kt:67)
        at kotlin.reflect.jvm.internal.impl.load.java.lazy.descriptors.LazyJavaScope$functionNamesLazy$2.invoke(LazyJavaScope.kt:253)
        at kotlin.reflect.jvm.internal.impl.load.java.lazy.descriptors.LazyJavaScope$functionNamesLazy$2.invoke(LazyJavaScope.kt:59)
        at kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$LockBasedLazyValue.invoke(LockBasedStorageManager.java:355)
        at kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$LockBasedNotNullLazyValue.invoke(LockBasedStorageManager.java:474)
        at kotlin.reflect.jvm.internal.impl.storage.StorageKt.getValue(storage.kt:42)
        at kotlin.reflect.jvm.internal.impl.load.java.lazy.descriptors.LazyJavaScope.getFunctionNamesLazy(LazyJavaScope.kt)
        at kotlin.reflect.jvm.internal.impl.load.java.lazy.descriptors.LazyJavaScope.getFunctionNames(LazyJavaScope.kt:257)
        at kotlin.reflect.jvm.internal.impl.load.java.lazy.descriptors.LazyJavaScope.getContributedFunctions(LazyJavaScope.kt:266)
        at kotlin.reflect.jvm.internal.impl.load.java.lazy.descriptors.LazyJavaClassMemberScope.getContributedFunctions(LazyJavaClassMemberScope.kt:747)
        at kotlin.reflect.jvm.internal.KClassImpl.getFunctions(KClassImpl.kt:208)
        at kotlin.reflect.jvm.internal.KDeclarationContainerImpl.findFunctionDescriptor(KDeclarationContainerImpl.kt:151)
        at kotlin.reflect.jvm.internal.KFunctionImpl$descriptor$2.invoke(KFunctionImpl.kt:56)
        at kotlin.reflect.jvm.internal.KFunctionImpl$descriptor$2.invoke(KFunctionImpl.kt:36)
        at kotlin.reflect.jvm.internal.ReflectProperties$LazySoftVal.invoke(ReflectProperties.java:92)
        at kotlin.reflect.jvm.internal.ReflectProperties$Val.getValue(ReflectProperties.java:31)
        at kotlin.reflect.jvm.internal.KFunctionImpl.getDescriptor(KFunctionImpl.kt)
        at kotlin.reflect.jvm.internal.KFunctionImpl$caller$2.invoke(KFunctionImpl.kt:62)
        at kotlin.reflect.jvm.internal.KFunctionImpl$caller$2.invoke(KFunctionImpl.kt:36)
        at kotlin.reflect.jvm.internal.ReflectProperties$LazyVal.invoke(ReflectProperties.java:62)
        at kotlin.reflect.jvm.internal.ReflectProperties$Val.getValue(ReflectProperties.java:31)
        at kotlin.reflect.jvm.internal.KFunctionImpl.getCaller(KFunctionImpl.kt)
        at kotlin.reflect.jvm.ReflectJvmMapping.getJavaMethod(ReflectJvmMapping.kt:62)

@sherl0cks
Copy link
Contributor

sherl0cks commented Jun 30, 2020

@geoand I just hit this. It's a known issue oracle/graal#2306. The workaround only partially worked for me, requiring tweak to resources.json. Probably needs a fix in quarkus-kotlin or a new quarkus-kotlin-reflect extension.

oracle/graal#2306

{
  "resources": [
    {
      "pattern": "META-INF/.*.kotlin_module$"
    },
    {
      "pattern": "META-INF/services/kotlin.reflect.jvm.internal.impl.builtins.BuiltInsLoader"
    },
    {
      "pattern": "META-INF/services/kotlin.reflect.jvm.internal.impl.resolve.ExternalOverridabilityCondition"
    },
    {
      "pattern": ".*.kotlin_builtins"
    }
  ]
}

With the resources.json in place, Jackson started breaking with:

Failed to run lambda: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Class com.acme.MyClass[] is instantiated reflectively but was never registered. Register the class by using org.graalvm.nativeimage.hosted.RuntimeReflection

I have never seen the com.acme.MyClass[] syntax before. Apparently it is not legal in Kotlin? What is this even called in Java? Either way, adding a reflection-config.json to my build worked (in addition to annotating the class with @RegisterForReflection. )

[
  { 
    "name": "com.acme.MyClass[]",
    "allPublicMethods": true,
    "allDeclaredFields":true,
    "allDeclaredMethods":true,
    "allDeclaredConstructors":true
  }
]

Anyhow, with all these tweaks it works. Quarkus 1.5.2 and graal 20.1.0-java8

@geoand
Copy link
Contributor

geoand commented Jul 1, 2020

Thanks for the information @sherl0cks.

I think we can probably make the current quarkus-kotlin extension register the info automatically, shouldn't be hard.

@RotBolt would you perhaps like to take a look?

@sherl0cks
Copy link
Contributor

Sounds good @geoand.

I'd really love some more info on the MyClass[] syntax. What is the name of this syntax? Why does Graal need it? Why does it not work with kotlin and @RegisterForReflection? One of the strangest things I've seen in my graal/quarkus journey...

@geoand
Copy link
Contributor

geoand commented Jul 1, 2020

I think it's just the array syntax written in a more readable form.
Can you try substituting MyClass[] with [LMyClass?

@RotBolt
Copy link
Contributor

RotBolt commented Jul 1, 2020

@geoand will look into this 👍

@sherl0cks
Copy link
Contributor

This seems to be the info on syntax. Why it doesn't work in @registerForReflection is still a mystery to me: https://stackoverflow.com/questions/41207060/how-to-get-a-kclass-of-array

@marc-christian-schulze
Copy link

marc-christian-schulze commented Jul 5, 2020

A similar error occurs in Quarkus 1.6.0.CR1 when trying to serialize a built-in Kotlin List, e.g.

@DefaultConstructor
@RegisterForReflection
data class Example(
    var name: String
)

@GET
@Path("/example")
fun getListOfExamples(): List<Example>  // <-- kotlin.collections.List<Example>

JVM-mode works fine but in native-mode (GraalVM 20.1) the following errors occurs:

[io.qua.ver.htt.run.QuarkusErrorHandler] (executor-thread-1) HTTP Request to /example failed, error id: 66d7f184-0352-42f5-880a-b7792076f675-1: org.jboss.resteasy.spi.UnhandledException: java.lang.IllegalStateException: @NotNull method kotlin/reflect/jvm/internal/impl/builtins/KotlinBuiltIns.getBuiltInClassByFqName must not return null
	at org.jboss.resteasy.core.ExceptionHandler.handleException(ExceptionHandler.java:381)
	at org.jboss.resteasy.core.SynchronousDispatcher.writeException(SynchronousDispatcher.java:216)
	at org.jboss.resteasy.core.SynchronousDispatcher.writeResponse(SynchronousDispatcher.java:610)
	at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:520)
	at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:259)
	at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:160)
	at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:364)
	at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:163)
	at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:245)
	at io.quarkus.resteasy.runtime.standalone.RequestDispatcher.service(RequestDispatcher.java:73)
	at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.dispatch(VertxRequestHandler.java:132)
	at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.access$000(VertxRequestHandler.java:37)
	at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler$1.run(VertxRequestHandler.java:94)
	at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
	at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:2046)
	at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1578)
	at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1452)
	at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)
	at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)
	at java.lang.Thread.run(Thread.java:834)
	at org.jboss.threads.JBossThread.run(JBossThread.java:479)
	at com.oracle.svm.core.thread.JavaThreads.threadStartRoutine(JavaThreads.java:517)
	at com.oracle.svm.core.posix.thread.PosixJavaThreads.pthreadStartRoutine(PosixJavaThreads.java:193)
Caused by: java.lang.IllegalStateException: @NotNull method kotlin/reflect/jvm/internal/impl/builtins/KotlinBuiltIns.getBuiltInClassByFqName must not return null
	at kotlin.reflect.jvm.internal.impl.builtins.KotlinBuiltIns.$$$reportNull$$$0(KotlinBuiltIns.java)
	at kotlin.reflect.jvm.internal.impl.builtins.KotlinBuiltIns.getBuiltInClassByFqName(KotlinBuiltIns.java:357)
	at kotlin.reflect.jvm.internal.impl.builtins.jvm.JavaToKotlinClassMap.mapJavaToKotlin(JavaToKotlinClassMap.kt:130)
	at kotlin.reflect.jvm.internal.impl.builtins.jvm.JavaToKotlinClassMap.mapJavaToKotlin$default(JavaToKotlinClassMap.kt:126)
	at kotlin.reflect.jvm.internal.impl.load.java.lazy.types.JavaTypeResolver.mapKotlinClass(JavaTypeResolver.kt:161)
	at kotlin.reflect.jvm.internal.impl.load.java.lazy.types.JavaTypeResolver.computeTypeConstructor(JavaTypeResolver.kt:135)
	at kotlin.reflect.jvm.internal.impl.load.java.lazy.types.JavaTypeResolver.computeSimpleJavaClassifierType(JavaTypeResolver.kt:117)
	at kotlin.reflect.jvm.internal.impl.load.java.lazy.types.JavaTypeResolver.transformJavaClassifierType(JavaTypeResolver.kt:97)
	at kotlin.reflect.jvm.internal.impl.load.java.lazy.types.JavaTypeResolver.transformJavaType(JavaTypeResolver.kt:52)
	at kotlin.reflect.jvm.internal.impl.load.java.lazy.descriptors.LazyJavaScope.resolveValueParameters(LazyJavaScope.kt:215)
	at kotlin.reflect.jvm.internal.impl.load.java.lazy.descriptors.LazyJavaClassMemberScope.resolveConstructor(LazyJavaClassMemberScope.kt:600)
	at kotlin.reflect.jvm.internal.impl.load.java.lazy.descriptors.LazyJavaClassMemberScope.access$resolveConstructor(LazyJavaClassMemberScope.kt:67)
	at kotlin.reflect.jvm.internal.impl.load.java.lazy.descriptors.LazyJavaClassMemberScope$constructors$1.invoke(LazyJavaClassMemberScope.kt:89)
	at kotlin.reflect.jvm.internal.impl.load.java.lazy.descriptors.LazyJavaClassMemberScope$constructors$1.invoke(LazyJavaClassMemberScope.kt:67)
	at kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$LockBasedLazyValue.invoke(LockBasedStorageManager.java:355)
	at kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$LockBasedNotNullLazyValue.invoke(LockBasedStorageManager.java:474)
	at kotlin.reflect.jvm.internal.impl.load.java.lazy.descriptors.LazyJavaClassDescriptor.getConstructors(LazyJavaClassDescriptor.kt:129)
	at kotlin.reflect.jvm.internal.impl.load.java.lazy.descriptors.LazyJavaClassDescriptor.getConstructors(LazyJavaClassDescriptor.kt:42)
	at kotlin.reflect.jvm.internal.KClassImpl.getConstructorDescriptors(KClassImpl.kt:200)
	at kotlin.reflect.jvm.internal.KClassImpl$Data$constructors$2.invoke(KClassImpl.kt:91)
	at kotlin.reflect.jvm.internal.KClassImpl$Data$constructors$2.invoke(KClassImpl.kt:44)
	at kotlin.reflect.jvm.internal.ReflectProperties$LazySoftVal.invoke(ReflectProperties.java:92)
	at kotlin.reflect.jvm.internal.ReflectProperties$Val.getValue(ReflectProperties.java:31)
	at kotlin.reflect.jvm.internal.KClassImpl$Data.getConstructors(KClassImpl.kt)
	at kotlin.reflect.jvm.internal.KClassImpl.getConstructors(KClassImpl.kt:235)
	at kotlin.reflect.jvm.ReflectJvmMapping.getKotlinFunction(ReflectJvmMapping.kt:144)
	at com.fasterxml.jackson.module.kotlin.ReflectionCache.kotlinFromJava(ReflectionCache.kt:44)
	at com.fasterxml.jackson.module.kotlin.KotlinNamesAnnotationIntrospector$hasCreatorAnnotation$1.invoke(KotlinNamesAnnotationIntrospector.kt:54)
	at com.fasterxml.jackson.module.kotlin.KotlinNamesAnnotationIntrospector$hasCreatorAnnotation$1.invoke(KotlinNamesAnnotationIntrospector.kt:20)
	at com.fasterxml.jackson.module.kotlin.ReflectionCache.checkConstructorIsCreatorAnnotated(ReflectionCache.kt:46)
	at com.fasterxml.jackson.module.kotlin.KotlinNamesAnnotationIntrospector.hasCreatorAnnotation(KotlinNamesAnnotationIntrospector.kt:52)
	at com.fasterxml.jackson.databind.AnnotationIntrospector.findCreatorAnnotation(AnnotationIntrospector.java:1261)
	at com.fasterxml.jackson.databind.introspect.AnnotationIntrospectorPair.findCreatorAnnotation(AnnotationIntrospectorPair.java:804)
	at com.fasterxml.jackson.databind.introspect.AnnotationIntrospectorPair.findCreatorAnnotation(AnnotationIntrospectorPair.java:804)
	at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector._addCreatorParam(POJOPropertiesCollector.java:498)
	at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector._addCreators(POJOPropertiesCollector.java:465)
	at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.collectAll(POJOPropertiesCollector.java:313)
	at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.getJsonValueAccessor(POJOPropertiesCollector.java:196)
	at com.fasterxml.jackson.databind.introspect.BasicBeanDescription.findJsonValueAccessor(BasicBeanDescription.java:252)
	at com.fasterxml.jackson.databind.ser.BasicSerializerFactory.findSerializerByAnnotations(BasicSerializerFactory.java:346)
	at com.fasterxml.jackson.databind.ser.BeanSerializerFactory._createSerializer2(BeanSerializerFactory.java:216)
	at com.fasterxml.jackson.databind.ser.BeanSerializerFactory.createSerializer(BeanSerializerFactory.java:165)
	at com.fasterxml.jackson.databind.SerializerProvider._createUntypedSerializer(SerializerProvider.java:1388)
	at com.fasterxml.jackson.databind.SerializerProvider._createAndCacheUntypedSerializer(SerializerProvider.java:1356)
	at com.fasterxml.jackson.databind.SerializerProvider.findValueSerializer(SerializerProvider.java:551)
	at com.fasterxml.jackson.databind.ser.std.AsArraySerializerBase.createContextual(AsArraySerializerBase.java:201)
	at com.fasterxml.jackson.databind.SerializerProvider.handleSecondaryContextualization(SerializerProvider.java:1004)
	at com.fasterxml.jackson.databind.SerializerProvider.findValueSerializer(SerializerProvider.java:561)
	at com.fasterxml.jackson.databind.SerializerProvider.findTypedValueSerializer(SerializerProvider.java:758)
	at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.forRootType(ObjectWriter.java:1396)
	at com.fasterxml.jackson.databind.ObjectWriter.forType(ObjectWriter.java:403)
	at org.jboss.resteasy.plugins.providers.jackson.ResteasyJackson2Provider.writeTo(ResteasyJackson2Provider.java:296)
	at org.jboss.resteasy.core.messagebody.AsyncBufferedMessageBodyWriter.asyncWriteTo(AsyncBufferedMessageBodyWriter.java:24)
	at org.jboss.resteasy.core.interception.jaxrs.ServerWriterInterceptorContext.writeTo(ServerWriterInterceptorContext.java:87)
	at org.jboss.resteasy.core.interception.jaxrs.AbstractWriterInterceptorContext.asyncProceed(AbstractWriterInterceptorContext.java:203)
	at org.jboss.resteasy.core.interception.jaxrs.AbstractWriterInterceptorContext.getStarted(AbstractWriterInterceptorContext.java:166)
	at org.jboss.resteasy.core.interception.jaxrs.ServerWriterInterceptorContext.lambda$getStarted$0(ServerWriterInterceptorContext.java:73)
	at org.jboss.resteasy.core.interception.jaxrs.ServerWriterInterceptorContext.aroundWriteTo(ServerWriterInterceptorContext.java:93)
	at org.jboss.resteasy.core.interception.jaxrs.ServerWriterInterceptorContext.getStarted(ServerWriterInterceptorContext.java:73)
	at org.jboss.resteasy.core.ServerResponseWriter.lambda$writeNomapResponse$3(ServerResponseWriter.java:163)
	at org.jboss.resteasy.core.interception.jaxrs.ContainerResponseContextImpl.filter(ContainerResponseContextImpl.java:404)
	at org.jboss.resteasy.core.ServerResponseWriter.executeFilters(ServerResponseWriter.java:252)
	at org.jboss.resteasy.core.ServerResponseWriter.writeNomapResponse(ServerResponseWriter.java:101)
	at org.jboss.resteasy.core.ServerResponseWriter.writeNomapResponse(ServerResponseWriter.java:74)
	at org.jboss.resteasy.core.SynchronousDispatcher.writeResponse(SynchronousDispatcher.java:590)
	... 20 more

@geoand
Copy link
Contributor

geoand commented Jul 6, 2020

Looks like something that would be addressed by #3954 (comment).

@RotBolt do you want to take it?

@sherl0cks
Copy link
Contributor

Just hit this again. Any progress on a fix? Anyway I can help?

@lenalebt
Copy link
Contributor

lenalebt commented May 9, 2021

Same here, I'm also running into these kinds of troubles. Mainly writing this down for the next person to find some help.

For me it mostly is connected to Jackson serialization together with the jackson-kotlin module. After manually registering a lot of array-valued classes (using @RegisterForReflection(targets = [Array<Foobar>::class])) I end up with a kotlin.reflect.jvm.internal.KotlinReflectionInternalError: Could not compute caller for function: public open fun equals(other: kotlin.Any?): kotlin.Boolean defined in com.example.Foobar[DeserializedSimpleFunctionDescriptor@1aa577b5] (member = null). This is happening while it is trying to resolve that javaMethod call the OP is doing directly, and I don't have a good idea how to overcome it currently.

This is what I needed to do to go past that @NotNull method kotlin/reflect/jvm/internal/impl/builtins/KotlinBuiltIns.getBuiltInClassByFqName must not return null error:

@RegisterForReflection(
  targets = [
    kotlin.reflect.jvm.internal.ReflectionFactoryImpl::class,
    KotlinVersion::class,
    Array<KotlinVersion>::class,
    KotlinVersion.Companion::class,
    Array<KotlinVersion.Companion>::class,
  ]
)
class ReflectionRegistrator

I additionally registered my own classes - although they were already marked with @RegisterForReflection, it also needed their Array counterparts. I don't understand why, because I'm not using them in Arrays, but who knows what Jackson is doing under the hood exactly.

@lenalebt
Copy link
Contributor

lenalebt commented May 9, 2021

Okay, after some heavy debugging I could find out what was causing the issue in my case. It may sound weird, but this is how it goes:

Everything works in the whole piece of software until I start using something that uses Kotlin coroutines under the hood. Then it all breaks, showing the symptoms you can see above. Even without manually registering the classes as I did in my previous post, it just works - until there is a single coroutine call somewhere in my application.

This seems to be what #7999 states - I just was not realizing it, because it looked like something else.

This is what I needed to change to fix my system. Removing:

val elements = sequence<DbEvent?> { sendOne() }.filterNotNull()

Instead writing

val elements = listOf(sendOne()).filterNotNull()

does not show the symptoms. I tried whether I need to actually call the code causing it, which does not seem to be the case. Having this:

if (Math.random() > 2.0)
      sequence<DbEvent?> { sendOne() }.filterNotNull()

will make it fail as well.

@Shpota
Copy link

Shpota commented Sep 6, 2021

I am running into this issue with Quarkus 2.0.1 and the workaround suggested here doesn't seem to work.

If I apply the configuration like this:

quarkus:
  native:
    additional-build-args: -H:ResourceConfigurationFiles=resources-config.json,-H:ReflectionConfigurationFiles=reflection-config.json

The application would fail on start:

java.util.ServiceConfigurationError: org.eclipse.microprofile.config.spi.ConfigSource: Provider org.jboss.resteasy.microprofile.config.ServletConfigSource not found
	at java.util.ServiceLoader.fail(ServiceLoader.java:589)
	at java.util.ServiceLoader$LazyClassPathLookupIterator.nextProviderClass(ServiceLoader.java:1212)
	at java.util.ServiceLoader$LazyClassPathLookupIterator.hasNextService(ServiceLoader.java:105)
	at java.util.ServiceLoader$LazyClassPathLookupIterator.hasNext(ServiceLoader.java:1265)
	at java.util.ServiceLoader$2.hasNext(ServiceLoader.java:1300)
	at java.util.ServiceLoader$3.hasNext(ServiceLoader.java:1385)
	at io.smallrye.config.SmallRyeConfigBuilder.discoverSources(SmallRyeConfigBuilder.java:95)
	at io.smallrye.config.SmallRyeConfig.buildConfigSources(SmallRyeConfig.java:76)
	at io.smallrye.config.SmallRyeConfig.<init>(SmallRyeConfig.java:68)
	at io.smallrye.config.SmallRyeConfigBuilder.build(SmallRyeConfigBuilder.java:402)
	at io.quarkus.runtime.generated.Config.readConfig(Config.zig:1723)
	at io.quarkus.deployment.steps.RuntimeConfigSetup.deploy(RuntimeConfigSetup.zig:42)
	at io.quarkus.runner.ApplicationImpl.doStart(ApplicationImpl.zig:436)
	at io.quarkus.runtime.Application.start(Application.java:101)
	at io.quarkus.runtime.ApplicationLifecycleManager.run(ApplicationLifecycleManager.java:101)
	at io.quarkus.runtime.Quarkus.run(Quarkus.java:66)
	at io.quarkus.runtime.Quarkus.run(Quarkus.java:42)
	at io.quarkus.runtime.Quarkus.run(Quarkus.java:119)
	at io.quarkus.runner.GeneratedMain.main(GeneratedMain.zig:29)

If I pass the resources in the yaml file like this:

quarkus:
  native:
    additional-build-args: "-H:ReflectionConfigurationFiles=reflection-config.json"
    resources:
      includes: META-INF/.*.kotlin_module$,META-INF/services/.*,.*.kotlin_builtins

It would start but it would fail with the same error.

java.lang.IllegalStateException: @NotNull method kotlin/reflect/jvm/internal/impl/builtins/KotlinBuiltIns.getBuiltInClassByFqName must not return null

@nielsenteixeira
Copy link

Any progress on a fix? I'm facing the same problem...

@evanchooly
Copy link
Member

Found the fix. just need to integrate it.

@evanchooly evanchooly self-assigned this Feb 3, 2022
@quarkus-bot quarkus-bot bot added this to the 2.8 - main milestone Feb 15, 2022
jmartisk pushed a commit to jmartisk/quarkus that referenced this issue Feb 15, 2022
@gsmet gsmet modified the milestones: 2.8 - main, 2.7.2.Final Feb 21, 2022
gsmet pushed a commit to gsmet/quarkus that referenced this issue Feb 21, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/kotlin kind/bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.