quarkus
quarkus copied to clipboard
Build fails with Kotlin coroutine/suspend methods
Describe the bug
With latest release the build fails with this error message:
Build step io.quarkus.resteasy.reactive.server.deployment.ResteasyReactiveProcessor#setupEndpoints threw an exception: java.lang.RuntimeException: java.lang.RuntimeException: Failed to process method 'io.outfoxx.cloud.api.admin.server.AdminAPI#createAccount'
and the final cause error message is:
Resource method java.lang.Object createAccount(java.lang.String tenantId, io.outfoxx.cloud.api.CreateAccountParams body, javax.ws.rs.core.UriInfo uriInfo, kotlin.coroutines.Continuation<? super javax.ws.rs.core.Response> $completion) can only have a single body parameter: $completion
Notice the complaint about the $completion
parameter in the method.
The suspend method is defined in an interface with the following signature:
@Path(value = "/admin/api/v1.0")
@Produces(value = ["application/json","application/cbor"])
@Consumes(value = ["application/json"])
interface AdminAPI
//...
@POST
@Path(value = "/tenants/{tenantId}/accounts")
public suspend fun createAccount(
@PathParam(value = "tenantId") tenantId: String,
@Valid body: CreateAccountParams,
@Context uriInfo: UriInfo
): Response
//...
}
An implementation class then derives from the interface and implements the methods. It builds fine in 2.13.0.Final
Expected behavior
Kotlin suspend methods work as they did in previous releases.
Actual behavior
Kotlin suspend methods in interfaces fails the
How to Reproduce?
No response
Output of uname -a
or ver
macOS 12.6
Output of java -version
OpenJDK 17.0.1
GraalVM version (if different from Java)
No response
Quarkus version or git rev
2.13.1.Final
Build tool (ie. output of mvnw --version
or gradlew --version
)
Gradle 7.5
Additional information
No response
/cc @evanchooly, @geoand
Here is the entire stack trace, it references EndpointIndexer.createEndpoints
.
java.lang.RuntimeException: java.lang.RuntimeException: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
[error]: Build step io.quarkus.resteasy.reactive.server.deployment.ResteasyReactiveProcessor#setupEndpoints threw an exception: java.lang.RuntimeException: java.lang.RuntimeException: Failed to process method 'io.outfoxx.cloud.api.admin.server.AdminAPI#createAccount'
at org.jboss.resteasy.reactive.common.processor.EndpointIndexer.createEndpoints(EndpointIndexer.java:315)
at io.quarkus.resteasy.reactive.server.deployment.ResteasyReactiveProcessor.setupEndpoints(ResteasyReactiveProcessor.java:593)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at io.quarkus.deployment.ExtensionLoader$3.execute(ExtensionLoader.java:909)
at io.quarkus.builder.BuildContext.run(BuildContext.java:281)
at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2449)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1478)
at java.base/java.lang.Thread.run(Thread.java:833)
at org.jboss.threads.JBossThread.run(JBossThread.java:501)
Caused by: java.lang.RuntimeException: Failed to process method 'io.outfoxx.cloud.api.admin.server.AdminAPI#createAccount'
at org.jboss.resteasy.reactive.common.processor.EndpointIndexer.createResourceMethod(EndpointIndexer.java:703)
at org.jboss.resteasy.reactive.common.processor.EndpointIndexer.createEndpoints(EndpointIndexer.java:405)
at org.jboss.resteasy.reactive.common.processor.EndpointIndexer.createEndpoints(EndpointIndexer.java:452)
at org.jboss.resteasy.reactive.common.processor.EndpointIndexer.createEndpoints(EndpointIndexer.java:286)
... 12 more
Caused by: java.lang.RuntimeException: Resource method java.lang.Object createAccount(java.lang.String tenantId, io.outfoxx.cloud.api.CreateAccountParams body, javax.ws.rs.core.UriInfo uriInfo, kotlin.coroutines.Continuation<? super javax.ws.rs.core.Response> $completion) can only have a single body parameter: $completion
at org.jboss.resteasy.reactive.common.processor.EndpointIndexer.createResourceMethod(EndpointIndexer.java:551)
... 15 more
Very interesting... I wonder if the bump to the latest Kotlin caused a regression...
Any chance you can attach a minimal sample that exhibits this problem?
Yep. Just needed to record it while I finished up other things.
Great, thanks!
I tried to reproduce this but I failed...
I had kind of a similar issue in my project. @geoand asked me to share my reproducer here.
In order to get the exception, you'd have to execute ./gradlew clean quarkusDev
. Funnily, if you execute only ./gradlew quarkusDev
afterwards, it successfully starts up.
Here is the reproducer: https://github.com/u6f6o/suspenderino
And the stacktrace:
2022-10-07 16:42:46,506 INFO [io.qua.dep.dev.IsolatedDevModeMain] (main) Attempting to start live reload endpoint to recover from previous Quarkus startup failure
2022-10-07 16:42:46,673 ERROR [io.qua.dep.dev.IsolatedDevModeMain] (main) Failed to start quarkus: java.lang.RuntimeException: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
[error]: Build step io.quarkus.resteasy.reactive.server.deployment.ResteasyReactiveProcessor#setupEndpoints threw an exception: java.lang.RuntimeException: java.lang.RuntimeException: Failed to process method 'org.acme.GreetingResource#streamUrl'
at org.jboss.resteasy.reactive.common.processor.EndpointIndexer.createEndpoints(EndpointIndexer.java:315)
at io.quarkus.resteasy.reactive.server.deployment.ResteasyReactiveProcessor.setupEndpoints(ResteasyReactiveProcessor.java:593)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at io.quarkus.deployment.ExtensionLoader$3.execute(ExtensionLoader.java:909)
at io.quarkus.builder.BuildContext.run(BuildContext.java:281)
at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2449)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1478)
at java.base/java.lang.Thread.run(Thread.java:833)
at org.jboss.threads.JBossThread.run(JBossThread.java:501)
Caused by: java.lang.RuntimeException: Failed to process method 'org.acme.GreetingResource#streamUrl'
at org.jboss.resteasy.reactive.common.processor.EndpointIndexer.createResourceMethod(EndpointIndexer.java:703)
at org.jboss.resteasy.reactive.common.processor.EndpointIndexer.createEndpoints(EndpointIndexer.java:405)
at org.jboss.resteasy.reactive.common.processor.EndpointIndexer.createEndpoints(EndpointIndexer.java:286)
... 12 more
Caused by: java.lang.RuntimeException: Resource method java.lang.Object streamUrl(java.lang.String userAgent, java.lang.String authorization, java.lang.String deviceToken, java.lang.String forwardedFor, java.lang.String correlationId, org.acme.GreetingResource$StreamUrlRequest request, kotlin.coroutines.Continuation<? super javax.ws.rs.core.Response> $completion) can only have a single body parameter: $completion
at org.jboss.resteasy.reactive.common.processor.EndpointIndexer.createResourceMethod(EndpointIndexer.java:551)
... 14 more
at io.quarkus.runner.bootstrap.AugmentActionImpl.runAugment(AugmentActionImpl.java:335)
at io.quarkus.runner.bootstrap.AugmentActionImpl.createInitialRuntimeApplication(AugmentActionImpl.java:252)
at io.quarkus.runner.bootstrap.AugmentActionImpl.createInitialRuntimeApplication(AugmentActionImpl.java:60)
at io.quarkus.deployment.dev.IsolatedDevModeMain.firstStart(IsolatedDevModeMain.java:86)
at io.quarkus.deployment.dev.IsolatedDevModeMain.accept(IsolatedDevModeMain.java:447)
at io.quarkus.deployment.dev.IsolatedDevModeMain.accept(IsolatedDevModeMain.java:59)
at io.quarkus.bootstrap.app.CuratedApplication.runInCl(CuratedApplication.java:149)
at io.quarkus.bootstrap.app.CuratedApplication.runInAugmentClassLoader(CuratedApplication.java:104)
at io.quarkus.deployment.dev.DevModeMain.start(DevModeMain.java:131)
at io.quarkus.deployment.dev.DevModeMain.main(DevModeMain.java:62)
Caused by: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
[error]: Build step io.quarkus.resteasy.reactive.server.deployment.ResteasyReactiveProcessor#setupEndpoints threw an exception: java.lang.RuntimeException: java.lang.RuntimeException: Failed to process method 'org.acme.GreetingResource#streamUrl'
at org.jboss.resteasy.reactive.common.processor.EndpointIndexer.createEndpoints(EndpointIndexer.java:315)
at io.quarkus.resteasy.reactive.server.deployment.ResteasyReactiveProcessor.setupEndpoints(ResteasyReactiveProcessor.java:593)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at io.quarkus.deployment.ExtensionLoader$3.execute(ExtensionLoader.java:909)
at io.quarkus.builder.BuildContext.run(BuildContext.java:281)
at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2449)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1478)
at java.base/java.lang.Thread.run(Thread.java:833)
at org.jboss.threads.JBossThread.run(JBossThread.java:501)
Caused by: java.lang.RuntimeException: Failed to process method 'org.acme.GreetingResource#streamUrl'
at org.jboss.resteasy.reactive.common.processor.EndpointIndexer.createResourceMethod(EndpointIndexer.java:703)
at org.jboss.resteasy.reactive.common.processor.EndpointIndexer.createEndpoints(EndpointIndexer.java:405)
at org.jboss.resteasy.reactive.common.processor.EndpointIndexer.createEndpoints(EndpointIndexer.java:286)
... 12 more
Caused by: java.lang.RuntimeException: Resource method java.lang.Object streamUrl(java.lang.String userAgent, java.lang.String authorization, java.lang.String deviceToken, java.lang.String forwardedFor, java.lang.String correlationId, org.acme.GreetingResource$StreamUrlRequest request, kotlin.coroutines.Continuation<? super javax.ws.rs.core.Response> $completion) can only have a single body parameter: $completion
at org.jboss.resteasy.reactive.common.processor.EndpointIndexer.createResourceMethod(EndpointIndexer.java:551)
... 14 more
at io.quarkus.builder.Execution.run(Execution.java:123)
at io.quarkus.builder.BuildExecutionBuilder.execute(BuildExecutionBuilder.java:79)
at io.quarkus.deployment.QuarkusAugmentor.run(QuarkusAugmentor.java:160)
at io.quarkus.runner.bootstrap.AugmentActionImpl.runAugment(AugmentActionImpl.java:331)
... 9 more
Caused by: java.lang.RuntimeException: java.lang.RuntimeException: Failed to process method 'org.acme.GreetingResource#streamUrl'
at org.jboss.resteasy.reactive.common.processor.EndpointIndexer.createEndpoints(EndpointIndexer.java:315)
at io.quarkus.resteasy.reactive.server.deployment.ResteasyReactiveProcessor.setupEndpoints(ResteasyReactiveProcessor.java:593)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at io.quarkus.deployment.ExtensionLoader$3.execute(ExtensionLoader.java:909)
at io.quarkus.builder.BuildContext.run(BuildContext.java:281)
at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2449)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1478)
at java.base/java.lang.Thread.run(Thread.java:833)
at org.jboss.threads.JBossThread.run(JBossThread.java:501)
Caused by: java.lang.RuntimeException: Failed to process method 'org.acme.GreetingResource#streamUrl'
at org.jboss.resteasy.reactive.common.processor.EndpointIndexer.createResourceMethod(EndpointIndexer.java:703)
at org.jboss.resteasy.reactive.common.processor.EndpointIndexer.createEndpoints(EndpointIndexer.java:405)
at org.jboss.resteasy.reactive.common.processor.EndpointIndexer.createEndpoints(EndpointIndexer.java:286)
... 12 more
Caused by: java.lang.RuntimeException: Resource method java.lang.Object streamUrl(java.lang.String userAgent, java.lang.String authorization, java.lang.String deviceToken, java.lang.String forwardedFor, java.lang.String correlationId, org.acme.GreetingResource$StreamUrlRequest request, kotlin.coroutines.Continuation<? super javax.ws.rs.core.Response> $completion) can only have a single body parameter: $completion
at org.jboss.resteasy.reactive.common.processor.EndpointIndexer.createResourceMethod(EndpointIndexer.java:551)
... 14 more
Thanks a lot for this!
I'll have a look next week.
Ahhh. I'm trying to make a reproducer with no luck. I'll try the clean thing.
To note, that is exactly what I was doing when I encountered the issue.
Yep it was the clean that was needed. For posterity here is my reproducer that generates the same error.
@aloubyansky it seems like io.quarkus:quarkus-resteasy-reactive-kotlin
is not getting included in the build (it's included in quarkus-resteasy-reactive
here and here).
The problem does not happen with 2.13.0.Final
, it starts showing up with 2.13.1.Final
(and also affects main
). Moreover, it seems to be limited to Gradle (or at least I haven't been able to reproduce it on Maven).
Do you have any idea what's going on?
Adding the quarkus-resteasy-reactive-kotlin
explicitly appears to solve the issue.
Yes, it does. This seems to indicate a problem with the conditional adding of extensions in 2.13.1.Final
(I also think the problem is limited to Gradle)
It appears https://github.com/quarkusio/quarkus/commit/827f778c9ab71478b19ce230ac5a5265bfdba592 has introduced a regression and that we don't have a sufficient test coverage for this use-case. @AdlerFleurant or @glefloch would one of you like to dig into this? Thanks!
Yeah sure I will have a look
@glefloch Anything I can do to speed this up? Holding up our update.
@kdubb not really, I found the commit that introduced the issue but not the line of code yet
@glefloch any news on this one?
I will review https://github.com/quarkusio/quarkus/commit/827f778c9ab71478b19ce230ac5a5265bfdba592#diff-f039c32dd9e6b278cc24a035089a6c1c686f3e56365b794ac7559f2f49ae116aR73 and revert everything that is not directly related to the bugfix.
This PR got extremely out of hands with a ton of unrelated changes that IMO don't make the code easier to read.
Yes, reverting this commit fix the issue but I wasn't able to identify which part of the code introduced the regression.
A reproducer that passes with 2.12.1.Final
and fails with EndpointIndexer
with 2.13.1.Final
code-with-quarkus.zip