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

Methods accessed reflectively starting with GraalVM for JDK 23+26 #41283

Closed
zakkak opened this issue Jun 18, 2024 · 5 comments · Fixed by #41581
Closed

Methods accessed reflectively starting with GraalVM for JDK 23+26 #41283

zakkak opened this issue Jun 18, 2024 · 5 comments · Fixed by #41581
Labels
area/native-image kind/bug Something isn't working
Milestone

Comments

@zakkak
Copy link
Contributor

zakkak commented Jun 18, 2024

Describe the bug

Starting with GraalVM for JDK 23 we see a lot of java.lang.BootstrapMethodError: java.lang.NoSuchMethodError, see https://github.com/oracle/graal/actions/runs/9558273459

I don't fully understand what's happening but the issue seems related to https://bugs.openjdk.org/browse/JDK-8229959.

I initially thought that registering the missing methods would be enough, but it looks like this is not the right way to go for all cases as some of the proxied classes may be used by the application itself and we don't know which methods will be reflective accessed in this case. E.g. in

return bodyBuilder.body(new Error(request.getRequestURI() + ":" + e.getMessage()));

the test is invoking getRequestURI on the proxied HttpServletRequest resulting in the following error/trace:

2024-06-18 15:09:11,655 ERROR [io.und.req.io] (executor-thread-1) Exception handling request 039ab309-6350-4f4d-a9b6-bf2b04583f7c-1 to /exception/re/pojo: java.lang.BootstrapMethodError: java.lang.NoSuchMethodError: jakarta.servlet.http.HttpServletRequest.getRequestURI()
	at jdk.proxy4/jdk.proxy4.$Proxy/s995751da.getRequestURI(Unknown Source)
	at io.quarkus.it.spring.web.CustomAdvice.handleResponseEntityException(CustomAdvice.java:37)
	at io.quarkus.spring.web.mappers.HandledResponseEntityException_Mapper_3d26ef0eeceea5013e29d92323a3aaebdec04719.toResponse(Unknown Source)
	at io.quarkus.spring.web.mappers.HandledResponseEntityException_Mapper_3d26ef0eeceea5013e29d92323a3aaebdec04719.toResponse(Unknown Source)
	at org.jboss.resteasy.core.ExceptionHandler.executeExceptionMapper(ExceptionHandler.java:139)
	at org.jboss.resteasy.core.ExceptionHandler.unwrapException(ExceptionHandler.java:183)
	at org.jboss.resteasy.core.ExceptionHandler.handleApplicationException(ExceptionHandler.java:100)
	at org.jboss.resteasy.core.ExceptionHandler.handleException(ExceptionHandler.java:344)
	at org.jboss.resteasy.core.SynchronousDispatcher.writeException(SynchronousDispatcher.java:205)
	at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:452)
	at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:240)
	at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:154)
	at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:321)
	at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:157)
	at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:229)
	at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:222)
	at io.quarkus.resteasy.runtime.ResteasyFilter$ResteasyResponseWrapper.service(ResteasyFilter.java:70)
	at io.quarkus.resteasy.runtime.ResteasyFilter$ResteasyResponseWrapper.sendError(ResteasyFilter.java:76)
	at io.undertow.servlet.handlers.DefaultServlet.doGet(DefaultServlet.java:172)
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:527)
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:614)
	at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74)
	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129)
	at io.quarkus.resteasy.runtime.ResteasyFilter.doFilter(ResteasyFilter.java:31)
	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
	at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)
	at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:63)
	at io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68)
	at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
	at io.undertow.servlet.handlers.RedirectDirHandler.handleRequest(RedirectDirHandler.java:67)
	at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:133)
	at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
	at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
	at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:65)
	at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
	at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
	at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
	at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
	at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:247)
	at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:111)
	at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:108)
	at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
	at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
	at io.quarkus.undertow.runtime.UndertowDeploymentRecorder$9$1.call(UndertowDeploymentRecorder.java:630)
	at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:227)
	at io.undertow.servlet.handlers.ServletInitialHandler.handleRequest(ServletInitialHandler.java:152)
	at io.undertow.server.handlers.CanonicalPathHandler.handleRequest(CanonicalPathHandler.java:49)
	at io.quarkus.undertow.runtime.UndertowDeploymentRecorder$1.handleRequest(UndertowDeploymentRecorder.java:126)
	at io.undertow.server.Connectors.executeRootHandler(Connectors.java:284)
	at io.undertow.server.DefaultExchangeHandler.handle(DefaultExchangeHandler.java:18)
	at io.quarkus.undertow.runtime.UndertowDeploymentRecorder$5$2.run(UndertowDeploymentRecorder.java:445)
	at java.base@24/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
	at java.base@24/java.util.concurrent.FutureTask.run(FutureTask.java:317)
	at io.quarkus.vertx.core.runtime.VertxCoreRecorder$14.runWith(VertxCoreRecorder.java:599)
	at org.jboss.threads.EnhancedQueueExecutor$Task.doRunWith(EnhancedQueueExecutor.java:2516)
	at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2495)
	at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1521)
	at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:11)
	at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:11)
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	at java.base@24/java.lang.Thread.runWith(Thread.java:1588)
	at java.base@24/java.lang.Thread.run(Thread.java:1575)
	at org.graalvm.nativeimage.builder/com.oracle.svm.core.thread.PlatformThreads.threadStartRoutine(PlatformThreads.java:834)
	at org.graalvm.nativeimage.builder/com.oracle.svm.core.thread.PlatformThreads.threadStartRoutine(PlatformThreads.java:810)
Caused by: java.lang.NoSuchMethodError: jakarta.servlet.http.HttpServletRequest.getRequestURI()
	at jdk.proxy4/jdk.proxy4.$Proxy/s995751da.$getMethod(Unknown Source)
	... 68 more

Since we don't know what methods might be invoked on the proxied classes I think we need to register all methods of proxied classes for reflective access. I am not sure how to detect which classes are being proxied though...

Expected behavior

Tests should build and pass as they do with GraalVM for JDK 21 and 22

Actual behavior

Tests fail with errors like the following:

``` 2024-06-18 03:52:55,782 ERROR [io.und.req.io] (executor-thread-1) Exception handling request aa886ec8-cb17-44e6-9d69-b4300fab13ee-1 to /fruits: java.lang.BootstrapMethodError: java.lang.NoSuchMethodError: jakarta.ws.rs.ext.Providers.getContextResolver(java.lang.Class, jakarta.ws.rs.core.MediaType) at jdk.proxy4/jdk.proxy4.$Proxy/sfa608265.getContextResolver(Unknown Source) at com.fasterxml.jackson.jakarta.rs.json.JacksonJsonProvider._locateMapperViaProvider(JacksonJsonProvider.java:197) at com.fasterxml.jackson.jakarta.rs.base.ProviderBase.locateMapper(ProviderBase.java:889) at org.jboss.resteasy.plugins.providers.jackson.ResteasyJackson2Provider.writeTo(ResteasyJackson2Provider.java:226) at org.jboss.resteasy.core.messagebody.AsyncBufferedMessageBodyWriter.asyncWriteTo(AsyncBufferedMessageBodyWriter.java:24) at org.jboss.resteasy.core.interception.jaxrs.ServerWriterInterceptorContext.writeTo(ServerWriterInterceptorContext.java:81) at org.jboss.resteasy.core.interception.jaxrs.AbstractWriterInterceptorContext.asyncProceed(AbstractWriterInterceptorContext.java:190) at org.jboss.resteasy.core.interception.jaxrs.AbstractWriterInterceptorContext.getStarted(AbstractWriterInterceptorContext.java:158) at org.jboss.resteasy.core.interception.jaxrs.ServerWriterInterceptorContext.lambda$getStarted$0(ServerWriterInterceptorContext.java:68) at org.jboss.resteasy.core.interception.jaxrs.ServerWriterInterceptorContext.aroundWriteTo(ServerWriterInterceptorContext.java:87) at org.jboss.resteasy.core.interception.jaxrs.ServerWriterInterceptorContext.getStarted(ServerWriterInterceptorContext.java:68) at org.jboss.resteasy.core.ServerResponseWriter.lambda$writeNomapResponse$3(ServerResponseWriter.java:166) at org.jboss.resteasy.core.interception.jaxrs.ContainerResponseContextImpl.filter(ContainerResponseContextImpl.java:365) at org.jboss.resteasy.core.ServerResponseWriter.executeFilters(ServerResponseWriter.java:243) at org.jboss.resteasy.core.ServerResponseWriter.writeNomapResponse(ServerResponseWriter.java:100) at org.jboss.resteasy.core.ServerResponseWriter.writeNomapResponse(ServerResponseWriter.java:73) at org.jboss.resteasy.core.SynchronousDispatcher.writeResponse(SynchronousDispatcher.java:518) at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:458) at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:240) at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:154) at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:321) at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:157) at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:229) at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:222) at io.quarkus.resteasy.runtime.ResteasyFilter$ResteasyResponseWrapper.service(ResteasyFilter.java:70) at io.quarkus.resteasy.runtime.ResteasyFilter$ResteasyResponseWrapper.sendError(ResteasyFilter.java:76) at io.undertow.servlet.handlers.DefaultServlet.doGet(DefaultServlet.java:172) at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:527) at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:614) at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74) at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129) at io.quarkus.resteasy.runtime.ResteasyFilter.doFilter(ResteasyFilter.java:31) at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84) at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:63) at io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68) at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) at io.undertow.servlet.handlers.RedirectDirHandler.handleRequest(RedirectDirHandler.java:67) at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:133) at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46) at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:65) at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60) at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77) at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50) at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:247) at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:111) at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:108) at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48) at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43) at io.quarkus.undertow.runtime.UndertowDeploymentRecorder$9$1.call(UndertowDeploymentRecorder.java:630) at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:227) at io.undertow.servlet.handlers.ServletInitialHandler.handleRequest(ServletInitialHandler.java:152) at io.undertow.server.handlers.CanonicalPathHandler.handleRequest(CanonicalPathHandler.java:49) at io.quarkus.undertow.runtime.UndertowDeploymentRecorder$1.handleRequest(UndertowDeploymentRecorder.java:126) at io.undertow.server.Connectors.executeRootHandler(Connectors.java:284) at io.undertow.server.DefaultExchangeHandler.handle(DefaultExchangeHandler.java:18) at io.quarkus.undertow.runtime.UndertowDeploymentRecorder$5$2.run(UndertowDeploymentRecorder.java:445) at java.base@24/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572) at java.base@24/java.util.concurrent.FutureTask.run(FutureTask.java:317) at io.quarkus.vertx.core.runtime.VertxCoreRecorder$14.runWith(VertxCoreRecorder.java:599) at org.jboss.threads.EnhancedQueueExecutor$Task.doRunWith(EnhancedQueueExecutor.java:2516) at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2495) at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1521) at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:11) at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:11) at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) at java.base@24/java.lang.Thread.runWith(Thread.java:1588) at java.base@24/java.lang.Thread.run(Thread.java:1575) at org.graalvm.nativeimage.builder/com.oracle.svm.core.thread.PlatformThreads.threadStartRoutine(PlatformThreads.java:834) at org.graalvm.nativeimage.builder/com.oracle.svm.core.thread.PlatformThreads.threadStartRoutine(PlatformThreads.java:810) Caused by: java.lang.NoSuchMethodError: jakarta.ws.rs.ext.Providers.getContextResolver(java.lang.Class, jakarta.ws.rs.core.MediaType) at jdk.proxy4/jdk.proxy4.$Proxy/sfa608265.$getMethod(Unknown Source) ... 76 more ```

How to Reproduce?

  1. Grab the latest GraalVM CE dev build from release https://github.com/graalvm/graalvm-ce-dev-builds/releases
  2. Extract it and set GRAALVM_HOME to point to the extracted directory
  3. ./mvnw -Dnative -pl integration-tests/spring-web -Dnative.surefire.skip -Dformat.skip -Dno-descriptor-tests clean verify -Dquarkus.native.container-build=false -Dtest-containers -Dstart-containers

Output of uname -a or ver

No response

Output of java -version

23 and 24

Mandrel or GraalVM version (if different from Java)

GraalVM for JDK 23 (and 24)

Quarkus version or git rev

5037263

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

No response

Additional information

No response

@zakkak zakkak added kind/bug Something isn't working area/native-image labels Jun 18, 2024
Copy link

quarkus-bot bot commented Jun 18, 2024

/cc @Karm (mandrel), @galderz (mandrel)

@dmlloyd
Copy link
Member

dmlloyd commented Jun 18, 2024

Last time I saw this issue (which was recently, but yet I don't remember where it was), it was because of a class which had javax vs jakarta (i.e. a version mismatch problem). I don't know whether that might be the case here though.

@zakkak zakkak changed the title Methods accessed reflectively starting with GraalVM for JDK 23 Methods accessed reflectively starting with GraalVM for JDK 23+26 Jun 19, 2024
@zakkak
Copy link
Contributor Author

zakkak commented Jun 19, 2024

I don't know whether that might be the case here though.

I think it's not related to this. Note that we see the issue with other packages as well, e.g. java.sql

@zakkak
Copy link
Contributor Author

zakkak commented Jun 27, 2024

This should now be fixed by oracle/graal#9184, I will wait for the CI to confirm.

@jerboaa
Copy link
Contributor

jerboaa commented Jul 1, 2024

Example errors of this look like:

 2024-06-18 03:52:55,782 ERROR [io.und.req.io] (executor-thread-1) Exception handling request aa886ec8-cb17-44e6-9d69-b4300fab13ee-1 to /fruits: java.lang.BootstrapMethodError: java.lang.NoSuchMethodError: jakarta.ws.rs.ext.Providers.getContextResolver(java.lang.Class, jakarta.ws.rs.core.MediaType)
	at jdk.proxy4/jdk.proxy4.$Proxy/sfa608265.getContextResolver(Unknown Source)
	at com.fasterxml.jackson.jakarta.rs.json.JacksonJsonProvider._locateMapperViaProvider(JacksonJsonProvider.java:197)

zakkak added a commit to zakkak/quarkus that referenced this issue Jul 1, 2024
This reverts commit 8b90462.

The need for these additional registrations has been handled in upstream
GraalVM with oracle/graal#9184 so they are no
longer needed.

Closes quarkusio#41283
@quarkus-bot quarkus-bot bot added this to the 3.13 - main milestone Jul 1, 2024
holly-cummins pushed a commit to holly-cummins/quarkus that referenced this issue Jul 31, 2024
This reverts commit 8b90462.

The need for these additional registrations has been handled in upstream
GraalVM with oracle/graal#9184 so they are no
longer needed.

Closes quarkusio#41283
danielsoro pushed a commit to danielsoro/quarkus that referenced this issue Sep 20, 2024
This reverts commit 8b90462.

The need for these additional registrations has been handled in upstream
GraalVM with oracle/graal#9184 so they are no
longer needed.

Closes quarkusio#41283
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/native-image kind/bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants