quarkus icon indicating copy to clipboard operation
quarkus copied to clipboard

Build fails with Kotlin coroutine/suspend methods

Open kdubb opened this issue 2 years ago • 18 comments

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

kdubb avatar Oct 07 '22 02:10 kdubb

/cc @evanchooly, @geoand

quarkus-bot[bot] avatar Oct 07 '22 02:10 quarkus-bot[bot]

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

kdubb avatar Oct 07 '22 02:10 kdubb

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?

geoand avatar Oct 07 '22 05:10 geoand

Yep. Just needed to record it while I finished up other things.

kdubb avatar Oct 07 '22 05:10 kdubb

Great, thanks!

geoand avatar Oct 07 '22 05:10 geoand

I tried to reproduce this but I failed...

geoand avatar Oct 07 '22 13:10 geoand

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

u6f6o avatar Oct 07 '22 14:10 u6f6o

Thanks a lot for this!

I'll have a look next week.

geoand avatar Oct 07 '22 14:10 geoand

Ahhh. I'm trying to make a reproducer with no luck. I'll try the clean thing.

kdubb avatar Oct 07 '22 14:10 kdubb

To note, that is exactly what I was doing when I encountered the issue.

kdubb avatar Oct 07 '22 14:10 kdubb

Yep it was the clean that was needed. For posterity here is my reproducer that generates the same error.

code-with-quarkus.zip

kdubb avatar Oct 07 '22 14:10 kdubb

@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?

geoand avatar Oct 07 '22 15:10 geoand

Adding the quarkus-resteasy-reactive-kotlin explicitly appears to solve the issue.

kdubb avatar Oct 07 '22 15:10 kdubb

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)

geoand avatar Oct 07 '22 15:10 geoand

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!

aloubyansky avatar Oct 07 '22 16:10 aloubyansky

Yeah sure I will have a look

glefloch avatar Oct 08 '22 10:10 glefloch

@glefloch Anything I can do to speed this up? Holding up our update.

kdubb avatar Oct 11 '22 18:10 kdubb

@kdubb not really, I found the commit that introduced the issue but not the line of code yet

glefloch avatar Oct 11 '22 20:10 glefloch

@glefloch any news on this one?

gsmet avatar Oct 18 '22 16:10 gsmet

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.

gsmet avatar Oct 19 '22 11:10 gsmet

Yes, reverting this commit fix the issue but I wasn't able to identify which part of the code introduced the regression.

glefloch avatar Oct 19 '22 11:10 glefloch

A reproducer that passes with 2.12.1.Final and fails with EndpointIndexer with 2.13.1.Final code-with-quarkus.zip

kdubb avatar Oct 19 '22 14:10 kdubb