Skip to content

Conversation

kdubb
Copy link
Contributor

@kdubb kdubb commented Jun 19, 2025

As detailed in #48464 certain methods cause the server endpoint indexer to scan all REST client methods, which can lead to errors if any client method violates the requirements for resource methods.

This fixes this in two ways:

1. Detect java.lang.Object returning methods and attempt further deduction.

Since the crux of the issue is java.lang.Object infecting the candidate list (which causes any query of does X derive Y to always result in true) this step tries to reduce the false positives here. The only method I could implement was for Kotlin suspend methods, since by view of Java they always return Object. If the method is a suspend method we extract the real return type.

Unfortunately while this reduces the pollution of the list dramatically, any method must be allowed to return Object (or Kotlin Any) which may dynamically return a sub-resource.

2. Check candidates for annotations from one of the Q-REST, MP-REST, or JAX-RS REST client pacakges.

Since we can’t always ensure the return type list is “free” of Object, the candidates are filtered based on if the class or method uses any annotatoins from the spec client packages. Reasonably this should filter the majority of client interfaces because they generally have at least one client annotation (e.g. RegisterRestClient).

—-

These issuees are tested were tested in our, fairly large set of projects, which all use Kotlin. and even include some methods returning Any. with no client interfaces being sent to the server indexer.

This wont fully ensure all client interfaces won’t ever be scanned by the server indexer, but the likelihood has been reduced dramatically. To get a REST client scanned by the server indexer you would need to:

  1. Write a Java method returning java.lang.Object or Kotlin.Any, this could be anywhere in the project.
  2. Write an interface with no client specific annotations and register it programmatically.

In this scenario, the liklihood of an issue arising is further reduced by the fact that errors are only raised when a method on the client interface fails to validate as a server method as well. From my investigation this seems very unlikely. E.g., in the REST client that triggered the error in our project, the method used an extra parameter annotated with @NotBody together with the @ClientHeaders annotation to add special client request headers. Now, the presence of either of thse annotations causes the interface to be filtered before being scanned.

…oint indexer from scanning REST clients

As detailed in quarkusio#48464 certail methods cause the server endpoint indexer to scan _all_ REST client methods, which can lead to errors if any client method violates the requirements for resource methods.

This fixes this in two ways:
### 1.  Detect `java.lang.Object` returning methods and attempt further deduction.

Since the crux of the issue is `java.lang.Object` infecting the candidate list (which causes any query of does X derive Y to always result in true) this step tries to reduce the false positives here. The only method I could implement was for Kotlin suspend methods, since by view of Java they always return `Object`. If the method is a suspend method we extract the real return type.

Unfortunately while this reduces the pollution of the list dramatically, any method must be allowed to return `Object` (or Kotlin `Any`) which may dynamically return a sub-resource.

### 2. Check candidates for annotations from one of the Q-REST, MP-REST, or JAX-RS REST client pacakges.

Since we can’t always ensure the return type list is “free” of `Object`, the candidates are filtered based on if the class or method uses any annotatoins from the spec client packages. Reasonably this _should_ filter the majority of client interfaces because they generally have at least one client annotation (e.g. `RegisterRestClient`).

—-

These issuees are tested were tested in our, fairly large set of projects, which all use Kotlin. and even include some methods returning `Any`. with no client interfaces being sent to the server indexer.

This wont fully ensure all client interfaces won’t ever be scanned by the server indexer, but the likelihood has been reduced dramatically. To get a REST client scanned by the server indexer you would need to:
1. Write a Java method returning `java.lang.Object` or `Kotlin.Any`, this could be anywhere in the project.
2. Write an interface with no client specific annotations and register it programmatically.

In this scenario, the liklihood of an issue arising is further reduced by the fact that errors are only raised when a method on the client interface fails to validate as a server method as well. From my investigation this seems very unlikely. E.g., in the REST client that triggered the error in our project, the method used an extra parameter annotated with `@NotBody` together with the `@ClientHeaders` annotation to add special client request headers. Now, the presence of either of thse annotations causes the interface to be filtered before being scanned.
@kdubb kdubb force-pushed the fix/rest-server-scanning-clients branch from bf3e51e to 2c6ed6f Compare June 19, 2025 15:08
@kdubb
Copy link
Contributor Author

kdubb commented Jun 19, 2025

@geoand I took a stab at it. It passes the local tests and I tested it in our code base to verify it solved the issues. We'll see if it passes the integration tests.

There are no tests, I didn't immediately know where/how to add them. The triggering scenario (Kotlin Any/suspend method plus invalid server resource method in a client) can be created as a test to verify it's not producing errors incorrectly but a step further would probably be better; something like running the REST processor and comparing the classes that were indexed vs a known list of what should have been indexed. As I said originally, I have very little time right now to spend on this so I couldn't spend the time figuring the testing out.

@kdubb kdubb requested a review from geoand June 19, 2025 15:22

This comment has been minimized.

Copy link
Contributor

@geoand geoand left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot @kdubb!

@geoand geoand added triage/waiting-for-ci Ready to merge when CI successfully finishes triage/backport labels Jun 20, 2025
Copy link

quarkus-bot bot commented Jun 20, 2025

Status for workflow Quarkus CI

This is the status report for running Quarkus CI on commit 2c6ed6f.

✅ The latest workflow run for the pull request has completed successfully.

It should be safe to merge provided you have a look at the other checks in the summary.

You can consult the Develocity build scans.

@geoand geoand merged commit 013b5d4 into quarkusio:main Jun 20, 2025
97 of 98 checks passed
@quarkus-bot quarkus-bot bot added this to the 3.25 - main milestone Jun 20, 2025
@quarkus-bot quarkus-bot bot added kind/bugfix and removed triage/waiting-for-ci Ready to merge when CI successfully finishes labels Jun 20, 2025
@gsmet gsmet modified the milestones: 3.25 - main, 3.24.1 Jun 24, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

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

3 participants