0

I'm trying to manage a class through CDI called MongoQuery, which contains logic for querying MongoDB. This will need information from caches being managed through ArC CDI (Quarkus flavor CDI implementation for substrateVM). I can create it manually in my ListingResource class (see commented out code in said class for how I was doing it), but not when I set it to be managed in the request scope.

The items all individually work, its when I put it all together that it falls apart and complains that there are unresolved dependencies. I've included a stack trace that I get when attempting to build, as well as some relevant code snippets of the classes that are causing issues building.

What is causing the issues in CDI? The only thing I could think of that would cause this issue is type erasure causing issues when doing a lookup for relevant beans, but I have generics sprinkled through the code and haven't had issues up to this point.

Actual code has been pushed to a GitHub fork in the current state if anyone wishes to see full code.

org.eclipsefoundation.marketplace.resource.ListingResource

@Path("/listings")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@RequestScoped
public class ListingResource {
    private static final Logger LOGGER = LoggerFactory.getLogger(ListingResource.class);

    @Inject
    MongoDao dao;
    @Inject
    CachingService<List<Listing>> cachingService;
    @Inject
    RequestWrapper params;
    @Inject
    DtoFilter<Listing> dtoFilter;
    @Inject
    MongoQuery<Listing> q;

    /**
     * Endpoint for /listing/ to retrieve all listings from the database along with
     * the given query string parameters.
     * 
     * @param listingId int version of the listing ID
     * @return response for the browser
     */
    @GET
    public Response select() {
        //MongoQuery<Listing> q = new MongoQuery<>(params, dtoFilter);

        ...

org.eclipsefoundation.marketplace.model.MongoQuery

@RequestScoped
public class MongoQuery<T> {
    private static final Logger LOGGER = LoggerFactory.getLogger(MongoQuery.class);
    
    @Inject
    RequestWrapper wrapper;
    @Inject
    DtoFilter<T> dtoFilter;

    private Bson filter;
    private Bson sort;

    // flag that indicates that aggregate should be used as filter
    private boolean useAggregate = false;

    ...

Stacktrace:


[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 org.eclipsefoundation.marketplace.model.MongoQuery<org.eclipsefoundation.marketplace.dto.Listing> and qualifiers [@Default]
    - java member: org.eclipsefoundation.marketplace.resource.ListingResource#q
    - declared on CLASS bean [types=[org.eclipsefoundation.marketplace.resource.ListingResource, java.lang.Object], qualifiers=[@Default, @Any], target=org.eclipsefoundation.marketplace.resource.ListingResource]
    at io.quarkus.arc.processor.BeanDeployment.processErrors(BeanDeployment.java:835)
    at io.quarkus.arc.processor.BeanDeployment.init(BeanDeployment.java:214)
    at io.quarkus.arc.processor.BeanProcessor.initialize(BeanProcessor.java:106)
    at io.quarkus.arc.deployment.ArcProcessor.validate(ArcProcessor.java:249)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at io.quarkus.deployment.ExtensionLoader$1.execute(ExtensionLoader.java:768)
    at io.quarkus.builder.BuildContext.run(BuildContext.java:415)
    at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
    at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:2011)
    at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1535)
    at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1426)
    at java.lang.Thread.run(Thread.java:748)
    at org.jboss.threads.JBossThread.run(JBossThread.java:479)```
Community
  • 1
  • 1
  • Is adding a scope enough to make it a cdi managed bean? – Kukeltje Sep 26 '19 at 13:56
  • Why do you use a request scope on your resource class? I can understand the needs to use it on you MongoQuery (and all other classes that are statefull to a request) but I think that your ressource can be application scoped (so no specific annotation as in Quarkus having `@Path` is enought). Can you remove the `@RequestScoped` annotation on your resource and see if you still have the issue ? – loicmathieu Sep 26 '19 at 14:31
  • @Kukeltje Quarkus doesn't use a beans.xml, and instead relies on annotations for registering classes into ArC (their CDI) – Martin Lowe Sep 26 '19 at 14:43
  • @loicmathieu I still have the issue after removing the `@RequestScoped` yeah. When I was trying to fix request information persisting post request, adding the scope fixed it in the interim – Martin Lowe Sep 26 '19 at 14:47
  • @Martin: It might, but normally in CDI it is either annotations where **usually** a scope is **not enough** (@Named is needed as well) or it scans all classess with an empty constructor and you do not seem to have either. But that is my limited knowledge... So I _**can**_ be wrong ;-) – Kukeltje Sep 26 '19 at 14:47
  • @Kukeltje the [CDI reference guide](https://quarkus.io/guides/cdi-reference) for Quarkus does not specifically call out `@Named` as required for ArC. My implementations are based on the examples given within the guide – Martin Lowe Sep 26 '19 at 15:11
  • Did you **try**? Vet is more Simple than posting this as a comment – Kukeltje Sep 26 '19 at 15:44
  • Still recieving the error after adding `@Named` to MongoQuery: ``` Unsatisfied dependency for type org.eclipsefoundation.marketplace.model.MongoQuery and qualifiers [@Default] - java member: org.eclipsefoundation.marketplace.resource.ListingResource#q - declared on CLASS bean [types=[org.eclipsefoundation.marketplace.resource.ListingResource, java.lang.Object], qualifiers=[@Default, @Any], target=org.eclipsefoundation.marketplace.resource.ListingResource]``` – Martin Lowe Sep 26 '19 at 15:51
  • `@Named` isn't required, to make it a bean in an implicit bean archive (in CDI that's archive w/o `beans.xml`) you have to use a bean defining annotation. Scope is a bean defining annotation, so that one is enough to pick it up as a bean assuming the class in on classpath. This holds true for both, Weld and Arc. But note that Arc does require `beans.xml` but only uses it as marker file (to say "hey, this archive has beans, process it"). – Siliarus Sep 27 '19 at 07:39
  • Also, I think it may be the generics, because bean `MongoQuery` is a bit too generic for injection point `@Inject MongoQuery q;`. The bean is effectively `MongoQuery`. Looking at [CDI spec for this](https://docs.jboss.org/cdi/spec/2.0/cdi-spec.html#assignable_parameters), you then break the rules, because `Object` isn't assignable to `Listing`. Changing your bean to `MongoQuery` should do the trick as at that moment, the bean is `MongoQuery`. I might be wrong though, it's Fri and we are talking generics ;) – Siliarus Sep 27 '19 at 07:47
  • @Silarius: isn't the `@Named` required or not also dependend on the CDI version? (just to increase my knowledge, since I noticed in my (java-ee7 environment) a class is not recognized as a bean if there is just a scope annotation)... – Kukeltje Sep 27 '19 at 13:53
  • @Siliarus the idea with the generic in the query is that it can be applied to any domain transfer object from MongoDB. Limiting it to just Listing would end up defeating its purpose. I think the answer here is that its a little too generic for CDI to properly inject. – Martin Lowe Sep 30 '19 at 17:49
  • That's what I tried explaining to you; that with your generics, CDI cannot infer the types as you expect it to. The bean type and the injection point type won't match according to rules defined in CDI specification, see the link I had in the previous comment. – Siliarus Oct 01 '19 at 08:46
  • Future readers may want to check out this: https://stackoverflow.com/questions/55513502/how-to-create-a-jandex-index-in-quarkus-for-classes-in-a-external-module/55513723#55513723 and this : https://www.byteslounge.com/tutorials/java-ee-cdi-beans-deployed-in-external-library-web-inf-lib-jar-file – granadaCoder Oct 22 '19 at 12:32

0 Answers0