lud
lud

Reputation: 2001

Cannot have inject dynamic instance in quarkus when using @Dependent

I am using a library that is not thread safe and I want a fresh instance of that library object whenever I use it. I made a test repo here : https://github.com/lud/test-quarkus-arc

The library comes with two classes, SomeLibraryClass, which I need to use, and SomeLibraryClassDependency which is required by the former, and which is the thread-unsafe one.

I was trying to get all that working by using this factory-ish class:

@ApplicationScoped
public class MyAppFactory {
  @Dependent
  @Produces
  SomeLibraryClassDependency getDep() {
    return new SomeLibraryClassDependency();
  }

  @Dependent
  @Produces
  SomeLibraryClass getUsable(SomeLibraryClassDependency dep) {
    return new SomeLibraryClass(dep);
  }

  @Inject
  Instance<MyAppClass> myClass;

  public MyAppClass getNewMyClass() {
    return myClass.get();                // <-- this fails
  }
}

This is some test code I would like to compile. I am calling the factory getter twice, and I verify that my class uses a different instance of the SomeLibraryClassDependency class.

@Test
public void testHelloEndpoint() {
  var a = factory.getNewMyClass();
  var b = factory.getNewMyClass();
  assertNotEquals(a.getUsabeId(), b.getUsabeId());
}

Here is the class that should be instantiated by calling Instance<MyAppClass>#get:

@Dependent
public class MyAppClass {
  @Inject
  SomeLibraryClass usable;

  public MyAppClass() {

  }

  public Integer getUsabeId() {
    return usable.getId();
  }
}

Finally here is the code for the library mocks:

public class SomeLibraryClass {

  private SomeLibraryClassDependency dep;

  public SomeLibraryClass(SomeLibraryClassDependency dep) {
    this.dep = dep;
  }

  public Integer getId() {
    return dep.getId();
  }
}


public class SomeLibraryClassDependency {

  private static Integer n = 0;
  private Integer id;

  public SomeLibraryClassDependency() {
    n += 1;
    this.id = n;
  }

  public Integer getId() {
    return id;
  }
}

When trying to compile that, I have the following error, and I do not understand why

[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 io.quarkus.arc.runtime.BeanContainer$Instance<org.acme.getting.started.MyAppClass> and qualifiers [@Default]

  • java member: org.acme.getting.started.MyAppFactory#myClass
  • declared on CLASS bean [types=[org.acme.getting.started.MyAppFactory, java.lang.Object], qualifiers=[@Default, @Any], target=org.acme.getting.started.MyAppFactory]

I was thinking that since MyAppClass has the @Dependent annotation, it should be resolved.

Edit: I know I can also define a producer for my class, but my end goal is to be able to @Inject other things in that class (like a logger) and let the container do its job.

Upvotes: 1

Views: 1998

Answers (1)

Ladicek
Ladicek

Reputation: 6577

The error message says Unsatisfied dependency for type io.quarkus.arc.runtime.BeanContainer$Instance<org.acme.getting.started.MyAppClass>, which suggests that you have a wrong import for the Instance class. The correct one is javax.enterprise.inject.Instance.

Upvotes: 1

Related Questions