1

I am writing a web app using the Quarkus framework, v2.12.3. I have a simple JAX-RS class and method that look something like this:

    @Path("/{token")
    @GET
    @Produces({"text/plan"}
    public Response processRequest(@PathParam("token") String enrollmentToken) {
   ...snip...
}

The request, however, contains a digital signature, so I have created a JAX-RS ContainerRequestFilter to validate the signature before passing the request along to processRequest. Since not all of my methods will have signed requests, I created a Qualifier annotation that my filter uses to determine if the signature should be validated. My annotation looks like this:

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE })
public @interface SignedRequest {

}

So, I update my JAX-RS method to include the Qualifier:

    @Path("/{token")
    @GET
    @Produces({"text/plan"}
    @SignedRequest
    public Response processRequest(@PathParam("token") String enrollmentToken) {
   ...snip...
}

However, once I do this I get the following Exception when trying to build the class:

[ERROR] Failed to execute goal io.quarkus:quarkus-maven-plugin:2.12.3.Final:build (default) on project myproj: Failed to build quarkus application: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
[ERROR]     [error]: Build step io.quarkus.arc.deployment.ArcProcessor#validate threw an exception: javax.enterprise.inject.spi.DeploymentException: javax.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type java.lang.String and qualifiers [@Default]
[ERROR]     - java member: com.myproj.MyService#processRequest():enrollmentToken
[ERROR]     - declared on PRODUCER METHOD bean [types=[javax.ws.rs.core.Response, java.lang.AutoCloseable, java.lang.Object], qualifiers=[@SignedRequest, @Any], target=javax.ws.rs.core.Response processRequest(java.lang.String enrollmentToken), declaringBean=com.myproj.MyService]
[ERROR]     The following beans match by type, but none have matching qualifiers:
[ERROR]         - Bean [class=java.lang.String, qualifiers=[@ConfigProperty, @Any]]
[ERROR]         - Bean [class=java.lang.String, qualifiers=[@Any, @Claim(value = "")]]
[ERROR]     at io.quarkus.arc.processor.BeanDeployment.processErrors(BeanDeployment.java:1215)
[ERROR]     at io.quarkus.arc.processor.BeanDeployment.init(BeanDeployment.java:275)
[ERROR]     at io.quarkus.arc.processor.BeanProcessor.initialize(BeanProcessor.java:140)
[ERROR]     at io.quarkus.arc.deployment.ArcProcessor.validate(ArcProcessor.java:496)
[ERROR]     at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[ERROR]     at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[ERROR]     at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[ERROR]     at java.base/java.lang.reflect.Method.invoke(Method.java:566)
[ERROR]     at io.quarkus.deployment.ExtensionLoader$3.execute(ExtensionLoader.java:909)
[ERROR]     at io.quarkus.builder.BuildContext.run(BuildContext.java:281)
[ERROR]     at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
[ERROR]     at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2449)
[ERROR]     at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1478)
[ERROR]     at java.base/java.lang.Thread.run(Thread.java:834)
[ERROR]     at org.jboss.threads.JBossThread.run(JBossThread.java:501)
[ERROR] Caused by: javax.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type java.lang.String and qualifiers [@Default]
[ERROR]     - java member: com.myproj.MyService#processRequest():enrollmentToken
[ERROR]     - declared on PRODUCER METHOD bean [types=[javax.ws.rs.core.Response, java.lang.AutoCloseable, java.lang.Object], qualifiers=[@SignedRequest, @Any], target=javax.ws.rs.core.Response processRequest(java.lang.String enrollmentToken), declaringBean=com.myproj.MyService]
[ERROR]     The following beans match by type, but none have matching qualifiers:
[ERROR]         - Bean [class=java.lang.String, qualifiers=[@ConfigProperty, @Any]]
[ERROR]         - Bean [class=java.lang.String, qualifiers=[@Any, @Claim(value = "")]]
[ERROR]     at io.quarkus.arc.processor.Beans.resolveInjectionPoint(Beans.java:411)
[ERROR]     at io.quarkus.arc.processor.BeanInfo.init(BeanInfo.java:536)
[ERROR]     at io.quarkus.arc.processor.BeanDeployment.init(BeanDeployment.java:263)
[ERROR]     ... 13 more
[ERROR] -> [Help 1]

If I remove the @SignedRequest annotation, everything builds properly again. I've also found that if I remove the enrollmentToken method parameter everything builds properly as well. It's the combination of the @SignedRequest annotation and a method parameter that causes problems.

Can anyone shed some light on what's happening here? I've never run into this issue before and am stumped.

Shadowman
  • 11,150
  • 19
  • 100
  • 198
  • Did you want JAX-RS [Name Binding instead](https://eclipse-ee4j.github.io/jersey.github.io/documentation/latest/filters-and-interceptors.html#d0e10054)? – Paul Samsotha Sep 21 '22 at 20:56
  • 2
    Just to explain the error message: JAX-RS resource classes are always beans in Quarkus, and if a bean's method is annotated with a qualifier, Quarkus considers it a producer method (even if it is not annotated `@Produces`). Parameters of producer methods are injection points, so Quarkus attempts to resolve a bean of type `String` and fails. That's what the failure means. Your annotation isn't really a qualifier, because it is not used to qualify any beans. – Ladicek Sep 22 '22 at 07:55
  • @Ladicek that makes sense. It would also explain why I didn’t see this issue running the code under Wildfly, only when migrating to Quarkus. Thanks for the explanation! – Shadowman Sep 22 '22 at 12:52

0 Answers0