Open brucejpp opened 8 months ago
/cc @cescoffier (rest-client), @geoand (rest-client)
I'm pretty sure we've discussed this in the past...
@Ladicek probably knows the outcome of that discussion (because he has a great memory)
The jax.rs specification says that the annotations are inherited (section 3.6) which is why it was very confusing to find that these are not: https://download.oracle.com/otn-pub/jcp/jaxrs-2_0_rev_A-mrel-eval-spec/jsr339-jaxrs-2.0-final-spec.pdf?AuthParam=1710314633_0852fc20bcf0438b26aa009ada61dc73
I don't think we discussed this particular situation, or at least I don't remember it (and my memory is not as good as Clement might think...), and the MP RestClient specification doesn't mention annotation inheritance at all.
It seems natural to fall back on the JAX-RS rules for annotation inheritance, which RestClient Reactive seems to do: https://github.com/quarkusio/quarkus/blob/3.7.2/extensions/resteasy-reactive/rest-client-reactive/deployment/src/main/java/io/quarkus/rest/client/reactive/deployment/RestClientReactiveProcessor.java#L433
Technically, the code example in the description of this issue doesn't follow the JAX-RS rules for annotation inheritance, because
Note that inheritance of class or interface annotations is not supported.
which means that the @Path
annotation must be repeated on B
(which it isn't), but that doesn't seem to be an issue here.
I'll try to reproduce and see.
I can't reproduce. This seems to work both on Quarkus 3.7.2 and on current 999-SNAPSHOT.
Ok, my apologies - the scenario as described in my original report DOES indeed work. However...
Additionally, I had a class C in the project, such that:
package org.acme.rest.client;
import org.eclipse.microprofile.rest.client.inject.RestClient;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
@ApplicationScoped
public class C {
@Inject
@RestClient
B bService;
public C() {
}
}
Running quarkus dev
results in:
2024-03-14 15:55:31,538 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.arc.deployment.ArcProcessor#validate threw an exception: jakarta.enterprise.inject.spi.DeploymentException: jakarta.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type org.acme.rest.client.B and qualifiers [@RestClient]
- injection target: org.acme.rest.client.C#bService
- declared on CLASS bean [types=[org.acme.rest.client.C, java.lang.Object], qualifiers=[@Default, @Any], target=org.acme.rest.client.C]
This does not happen if you modify the injection in C (of B) with the superclass A (with added @RegisterRestClient
)
Sorry for the confusion.
When I was trying to reproduce, I of course tried to inject the sub-interface into a class. It worked flawlessly.
ok - I understand what is happening with this issue example on my system. I can repeat the failure in a case I have, but the project structure is a bit different. Should I close this and reopen in another issue or provide complete example here?
Feel free to continue in this issue.
In my real code where I encountered this problem, I have multiple maven projects. You can refactor the example above in a similar way. Create a new quarkus project using:
quarkus create app org.acme:Foo
Move the superclass A.java and Extension.java into this new project, and add a dependency in the original rest-client-reactive-quickstart project to this, like:
<dependency>
<groupId>org.acme</groupId>
<artifactId>Foo</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
Build the project Foo, then run the rest-client-reactive-quickstart project with quarkus dev. You should then see:
2024-03-15 10:06:59,141 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.arc.deployment.ArcProcessor#validate threw an exception: jakarta.enterprise.inject.spi.DeploymentException: jakarta.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type org.acme.rest.client.B and qualifiers [@RestClient]
- injection target: org.acme.rest.client.C#bService
- declared on CLASS bean [types=[org.acme.rest.client.C, java.lang.Object], qualifiers=[@Default, @Any], target=org.acme.rest.client.C]
I'm facing a similar issue. I have a RestClient:
package com.test;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
@Path("/api/v2")
@RegisterRestClient
@ApplicationScoped
public interface TestClient {
@GET
@Path("/test")
Response test();
}
And I'm trying to inject this Rest Client:
package com.test;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import org.eclipse.microprofile.rest.client.inject.RestClient;
@ApplicationScoped
public class TestBean {
@Inject
@RestClient
TestClient client;
}
but I'm getting this error:
Caused by: jakarta.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type com.test.TestClient and qualifiers [@RestClient]
- injection target: com.test.TestBean#client
- declared on CLASS bean [types=[com.test.TestBean, java.lang.Object], qualifiers=[@Default, @Any], target=com.test.TestBean]
at io.quarkus.arc.processor.Beans.resolveInjectionPoint(Beans.java:519)
at io.quarkus.arc.processor.BeanInfo.init(BeanInfo.java:638)
at io.quarkus.arc.processor.BeanDeployment.init(BeanDeployment.java:308)
This only happens if I update from quarkus-resteasy-client and quarkus-resteasy-client-deployment to quarkus-rest-client and quarkus-rest-client-deployment
Does the problem above persist if you remove @ApplicationScoped
?
@geoand yes, I have tried that, it fails with same error. It only works if I use resteasy-client instead of rest-client. However, as this is an extension, I cannot use resteasy as it conflicts with the new "rest" from Quarkus 3.9 when I add this extension to a Quarkus 3.9 project:
Multiple producers of item class io.quarkus.security.spi.DefaultSecurityCheckBuildItem (io.quarkus.resteasy.reactive.common.deployment.ResteasyReactiveCommonProcessor#setUpDenyAllJaxRs)
That's very weird. Please attach a sample application that exhibits this behavior so we can check.
@geoand nvm, I have found the solution on #34180 I was using AdditionalBeanBuildItem instead of AdditionalIndexedClassesBuildItem. It is working now that I have changed. Thanks!
Describe the bug
Using extensions/resteasy-reactive/rest-client-reactive Follow the tutorial here: https://quarkus.io/guides/rest-client-reactive ...but instead of creating the interface described, create 2 interfaces (A and B). Place the jakarta.ws.rs annotations on interface A, and then make the second interface B extend A. (See attached) At compile time, this failes to build with an error:
[error]: Build step io.quarkus.arc.deployment.ArcProcessor#validate threw an exception: jakarta.enterprise.inject.spi.DeploymentException: jakarta.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type org.acme.rest.client.B and qualifiers [@RestClient]
Expected behavior
The annotations in the superinterface should be inherited and processed correctly
Actual behavior
Superinterface annotations are ignored
How to Reproduce?
Follow the example linked about, but replace the interface class with these two:
Output of
uname -a
orver
23.3.0 Darwin Kernel Version 23.3.0: Wed Dec 20 21:31:00 PST 2023; root:xnu-10002.81.5~7/RELEASE_ARM64_T6020 arm64
Output of
java -version
java version "17.0.8" 2023-07-18 LTS
Quarkus version or git rev
3.7.2
Build tool (ie. output of
mvnw --version
orgradlew --version
)maven 3.9.4
Additional information
No response