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.
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 java.base@21.0.5/java.lang.Thread.runWith(Thread.java:1596)
at java.base@21.0.5/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 java.base@21.0.5/java.lang.Class.checkMethod(DynamicHub.java:1078)
at java.base@21.0.5/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
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:
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
orver
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
orgradlew --version
)Apache Maven 3.8.1
Additional information
No response