Skip to content

Certain methods cause all REST clients to be indexed as server endpoints #48464

@kdubb

Description

@kdubb

Describe the bug

When upgrading from 3.21.3 to 3.23.3 we ran into an issue where previously working Kotlin REST client methods are reported as invalid by the server indexer; the methods are Kotlin suspend methods that use parameters with @NotBody to add headers to the request. After a deep dive debugging ResteasyReactiveProcessor and EndpointIndexer I discovered the issue was much deeper.. that recent changes have made any Kotlin suspend method, or method that returns Any in a REST client or is a REST resource method, causes all REST clients interfaces to be passed to the server's endpoint indexer. Seemingly by luck, this didn't cause any issues until a recent change in 3.23.0.

Details

The crux of the issue is that certain methods (that suspend or return Any) contribute java.lang.Object to the returnsBySubResources value here:

Having Object in that list causes all checking below to believe that anything being queried is a sub-resource of something, and therefore gets included in the toScan list further down. I believe this started in PR #46464.

This was caused by Kotlin suspend methods in our projects (because all suspend methods return the value or the continuation... so Object). It seemed like a more general problem and I created a minimal reproducer, and confirmed, that if you just return Any from an endpoint it causes the same behavior. It might affect Java resource methods that return Object but I haven't confirmed that.

While the referenced code cause has been causing the server to scan all the REST clients and their methods, it wasn't an issue. First, if the REST client doesn't violate any rules for server methods, it's not causing noticeable problems. Additionally, if a REST client method did violate the rules, no external exceptions was raised because of this code in EndpointIndexer, that essentially ignores all RuntimeErrors produced by interfaces:

I confirmed that all the way back to 3.21.4 a RuntimeException for the violating client methods were being thrown, caught, and ignored here.

So, exceptions were being thrown, and ignored, until PR #47513. That PR changes the RuntimeException thrown to a DeploymentException. This has the effect of having the exception handler in EndpointIndexer @ line 342 immediately rethrow the exception, rather than check if it's an interface and ignore it.

Expected behavior

Methods that don't validate as server endpoints, but are valid client methods, work as expected (and had previously).

Additionally, it seems that no client interfaces should be passed to the server's endpoint indexer. It's adding work that doesn't need to be done and it seems like it will continue to cause issues similar to the one being reported.

Actual behavior

No response

How to Reproduce?

I've attached a simple reproducer. It's a basic project generated from quarkus.io with REST and REST client. I made two changes to the generated project.

  1. Added a POST method to the generated MyRemoteService that uses an @NotBody parameters, this gives us a valid REST client method that is not a valid REST resource method.
  2. I changed the hello method in GreetingResource to be suspend.

Running ./gradlew build will generate the error thrown by the endpoint indexer.

Additionally, to prove that it was not just suspend methods, I changed the hello method to return Any (both are in the reproducer with one commented out). Changing the method and building again will report the same issue.

Changing the hello method to return String and not be a suspend method, will fix the build error reported.

More interestingly...

Leaving the hello method as a suspend method or returning Any and removing the @NotBody header: String parameter from the POST method will cease the build failure as well. Upon inspection you'll see that the endpoint indexer is still getting passed the MyRemotService but since only method is also a valid server method, no errors are reported.

code-with-quarkus.zip

Output of uname -a or ver

MacOS 15.5

Output of java -version

Java 21

Quarkus version or git rev

3.23.3 (affects 3.23.0 and server indexing of client methods happens back to 3.21.4)

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

Gradle 8.13

Additional information

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions