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

A NoSuchMethodException is raised when a rest resource is called with a Jakarta Reader/Writer interceptor defined #44564

Closed
filsero opened this issue Nov 18, 2024 · 5 comments · Fixed by #44613
Labels
area/native-image kind/bug Something isn't working
Milestone

Comments

@filsero
Copy link

filsero commented Nov 18, 2024

Describe the bug

I defined a class that implements the Jakarta WriterInterceptor and ReaderInterceptor to interceptor all rest resources in my Quarkus 3.8.5 application.
It happens that, when the native application is running, some resource methods are missing, raising a java.lang.NoSuchMethodException. Everything works fine with the non-native application.
Everything works fine also with the native application if I annotate the resource class with RegisterForReflection or if I delete the interceptor.

I uploaded a simple Quarkus app to reproduce the issue here: https://github.com/filsero/quarkus-issue-no-such-method.

The following is the complete stacktrace of the error:

__  ____  __  _____   ___  __ ____  ______ 
 --/ __ \/ / / / _ | / _ \/ //_/ / / / __/
 -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/
2024-11-18 13:40:03,620 INFO  [io.quarkus] (main) quarkus-issue-no-such-method 1.0.0 native (powered by Quarkus 3.8.5) started in 0.025s. Listening on: http://0.0.0.0:8081
2024-11-18 13:40:03,620 INFO  [io.quarkus] (main) Profile prod activated.
2024-11-18 13:40:03,620 INFO  [io.quarkus] (main) Installed features: [cdi, config-yaml, resteasy-reactive, resteasy-reactive-jackson, smallrye-context-propagation, vertx]
2024-11-18 13:40:06,473 ERROR [io.qua.ver.htt.run.QuarkusErrorHandler] (vert.x-eventloop-thread-1) HTTP Request to /operator failed, error id: 9a2ee4da-64f2-432f-8f93-dfc830b9183e-1: java.lang.RuntimeException: java.lang.NoSuchMethodException: com.example.nosuchmethodexception.resource.OperatorResource.getOperator()
        at org.jboss.resteasy.reactive.server.spi.ResteasyReactiveResourceInfo.getMethod(ResteasyReactiveResourceInfo.java:84)
        at org.jboss.resteasy.reactive.server.spi.ResteasyReactiveResourceInfo.getAnnotations(ResteasyReactiveResourceInfo.java:101)
        at org.jboss.resteasy.reactive.server.core.ResteasyReactiveRequestContext.getMethodAnnotations(ResteasyReactiveRequestContext.java:565)
        at org.jboss.resteasy.reactive.server.core.ResteasyReactiveRequestContext.getAllAnnotations(ResteasyReactiveRequestContext.java:543)
        at org.jboss.resteasy.reactive.server.core.ServerSerialisers.invokeWriter(ServerSerialisers.java:222)
        at org.jboss.resteasy.reactive.server.core.serialization.DynamicEntityWriter.write(DynamicEntityWriter.java:106)
        at org.jboss.resteasy.reactive.server.handlers.ResponseWriterHandler.handle(ResponseWriterHandler.java:32)
        at io.quarkus.resteasy.reactive.server.runtime.QuarkusResteasyReactiveRequestContext.invokeHandler(QuarkusResteasyReactiveRequestContext.java:147)
        at org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:147)
        at org.jboss.resteasy.reactive.server.handlers.RestInitialHandler.beginProcessing(RestInitialHandler.java:48)
        at org.jboss.resteasy.reactive.server.vertx.ResteasyReactiveVertxHandler.handle(ResteasyReactiveVertxHandler.java:23)
        at org.jboss.resteasy.reactive.server.vertx.ResteasyReactiveVertxHandler.handle(ResteasyReactiveVertxHandler.java:10)
        at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1285)
        at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:177)
        at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:137)
        at io.quarkus.vertx.http.runtime.options.HttpServerCommonHandlers$1.handle(HttpServerCommonHandlers.java:62)
        at io.quarkus.vertx.http.runtime.options.HttpServerCommonHandlers$1.handle(HttpServerCommonHandlers.java:40)
        at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1285)
        at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:177)
        at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:137)
        at io.quarkus.resteasy.reactive.server.runtime.ResteasyReactiveRecorder$13.handle(ResteasyReactiveRecorder.java:339)
        at io.quarkus.resteasy.reactive.server.runtime.ResteasyReactiveRecorder$13.handle(ResteasyReactiveRecorder.java:332)
        at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1285)
        at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:177)
        at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:137)
        at io.vertx.ext.web.impl.RouterImpl.handle(RouterImpl.java:68)
        at io.vertx.ext.web.impl.RouterImpl.handle(RouterImpl.java:37)
        at io.quarkus.vertx.http.runtime.options.HttpServerCommonHandlers$2.handle(HttpServerCommonHandlers.java:86)
        at io.quarkus.vertx.http.runtime.options.HttpServerCommonHandlers$2.handle(HttpServerCommonHandlers.java:69)
        at io.quarkus.vertx.http.runtime.VertxHttpRecorder$1.handle(VertxHttpRecorder.java:147)
        at io.quarkus.vertx.http.runtime.VertxHttpRecorder$1.handle(VertxHttpRecorder.java:123)
        at io.vertx.core.http.impl.Http1xServerRequestHandler.handle(Http1xServerRequestHandler.java:67)
        at io.vertx.core.http.impl.Http1xServerRequestHandler.handle(Http1xServerRequestHandler.java:30)
        at io.vertx.core.impl.ContextImpl.emit(ContextImpl.java:328)
        at io.vertx.core.impl.DuplicatedContext.emit(DuplicatedContext.java:166)
        at io.vertx.core.http.impl.Http1xServerConnection.handleMessage(Http1xServerConnection.java:174)
        at io.vertx.core.net.impl.ConnectionBase.read(ConnectionBase.java:159)
        at io.vertx.core.net.impl.VertxHandler.channelRead(VertxHandler.java:153)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
        at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:93)
        at io.netty.handler.codec.http.websocketx.extensions.WebSocketServerExtensionHandler.onHttpRequestChannelRead(WebSocketServerExtensionHandler.java:160)
        at io.netty.handler.codec.http.websocketx.extensions.WebSocketServerExtensionHandler.channelRead(WebSocketServerExtensionHandler.java:83)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
        at io.vertx.core.http.impl.Http1xUpgradeToH2CHandler.channelRead(Http1xUpgradeToH2CHandler.java:124)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
        at io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:289)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
        at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:346)
        at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:333)
        at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:455)
        at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:290)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
        at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
        at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
        at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
        at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788)
        at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724)
        at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650)
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562)
        at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
        at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
        at [email protected]/java.lang.Thread.runWith(Thread.java:1596)
        at [email protected]/java.lang.Thread.run(Thread.java:1583)
        at org.graalvm.nativeimage.builder/com.oracle.svm.core.thread.PlatformThreads.threadStartRoutine(PlatformThreads.java:896)
        at org.graalvm.nativeimage.builder/com.oracle.svm.core.thread.PlatformThreads.threadStartRoutine(PlatformThreads.java:872)
Caused by: java.lang.NoSuchMethodException: com.example.nosuchmethodexception.resource.OperatorResource.getOperator()
        at [email protected]/java.lang.Class.checkMethod(DynamicHub.java:1078)
        at [email protected]/java.lang.Class.getMethod(DynamicHub.java:1063)
        at org.jboss.resteasy.reactive.server.spi.ResteasyReactiveResourceInfo.getMethod(ResteasyReactiveResourceInfo.java:79)
        ... 77 more

Expected behavior

Adding the Jakarta interceptor should not affect the availability of the rest resource methods in the native application.

Actual behavior

The java.lang.NoSuchMethodException exception is raised when a rest resource is called in a Quarkus native app if a Jakarta Reader/Writer interceptor is defined

How to Reproduce?

Steps to reproduce the behavior:

  1. Define a rest resource: https://quarkus.io/version/3.8/guides/resteasy#creating-the-first-json-rest-service
  2. Intercept all requests and responses by extending Jakarta reader and writer on a class annotated with @Provider
  3. Build the application with the native compiler
  4. Call the rest resource exposed by the native application

Output of uname -a or ver

No response

Output of java -version

OpenJDK 64-Bit Server VM Temurin-21.0.2+13 (build 21.0.2+13-LTS, mixed mode, sharing)

Mandrel or GraalVM version (if different from Java)

No response

Quarkus version or git rev

3.8.5

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

Apache Maven 3.8.1

Additional information

No response

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

quarkus-bot bot commented Nov 18, 2024

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

@gsmet
Copy link
Member

gsmet commented Nov 19, 2024

Interesting. I would have thought #42941 would have fixed it given your report is nearly identical to #42919 but I updated the reproducer to Quarkus 3.16.3 and we still have the exact same issue:

Caused by: java.lang.NoSuchMethodException: com.example.nosuchmethodexception.resource.OperatorResource.postOperator(com.example.nosuchmethodexception.resource.Operator)
	at [email protected]/java.lang.Class.checkMethod(DynamicHub.java:1075)
	at [email protected]/java.lang.Class.getMethod(DynamicHub.java:1060)
	at org.jboss.resteasy.reactive.server.spi.ResteasyReactiveResourceInfo.getMethod(ResteasyReactiveResourceInfo.java:79)
	... 21 more

/cc @geoand

@geoand
Copy link
Contributor

geoand commented Nov 21, 2024

Thanks for the ping @gsmet!

This should have been addressed in #32798 so I need to see what's going on

@geoand
Copy link
Contributor

geoand commented Nov 21, 2024

Ah no, we actually never did anything for interceptors... I need to fix that

@geoand
Copy link
Contributor

geoand commented Nov 21, 2024

#44613 fixes the issue

@gsmet gsmet closed this as completed in 314e3d5 Nov 21, 2024
gsmet added a commit that referenced this issue Nov 21, 2024
Register method for reflection when read or write interceptors exist
@quarkus-bot quarkus-bot bot added this to the 3.18 - main milestone Nov 21, 2024
@gsmet gsmet modified the milestones: 3.18 - main, 3.17.1 Nov 27, 2024
gsmet pushed a commit to gsmet/quarkus that referenced this issue Nov 27, 2024
This is needed because the interceptors need to get method
metadata

Fixes: quarkusio#44564
(cherry picked from commit 314e3d5)
@gsmet gsmet modified the milestones: 3.17.2, 3.15.3 Dec 12, 2024
gsmet pushed a commit to gsmet/quarkus that referenced this issue Dec 12, 2024
This is needed because the interceptors need to get method
metadata

Fixes: quarkusio#44564
(cherry picked from commit 314e3d5)
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