Search code examples
javacdiweld

@Produces @Named gives a WELD-001408


I'm trying to get my head around CDI and in this case the annotations @Produces and @Named

I have the following code

@RunWith(CdiRunner.class)
public class cdiTest {

@Inject
protected CDIModel em;

@Test
public void injectionTest(){
    Assert.assertEquals("this", em.getMyString());
}

}

public class CDIModel {

String myString;

public CDIModel(String myString) {
    this.myString = myString;
}

public String getMyString() {
    return myString;
}
}

public class EntityProducer {

@Produces
@Named("this")
@Singleton
public CDIModel doThis() {
    return new CDIModel("this");
}

@Produces
@Named("that")
@Singleton
public CDIModel doThat() {
    return new CDIModel("that");
}

}

Why do i get

org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied 
dependencies for type CDIModel with qualifiers @Named
  at injection point [UnbackedAnnotatedField] @Inject @Named protected 
persistence.dao.cdiTest.em
  at persistence.dao.cdiTest.em(cdiTest.java:0)

After adding @AdditionalClasses(EntityProducer.class) I get

org.jboss.weld.exceptions.DeploymentException: WELD-001409: Ambiguous 
dependencies for type CDIModel with qualifiers @Default
at injection point [UnbackedAnnotatedField] @Inject protected 
dk.nykredit.lanc.persistence.dao.cdiTest.em
at dk.nykredit.lanc.persistence.dao.cdiTest.em(cdiTest.java:0)
Possible dependencies: 
- Producer Method [CDIModel] with qualifiers [@Default @Named @Any] declared 
as [[BackedAnnotatedMethod] @Produces @Named @Singleton public 
persistence.dao.EntityProducer.doThat()],
- Producer Method [CDIModel] with qualifiers [@Default @Named @Any] declared 
as [[BackedAnnotatedMethod] @Produces @Named @Singleton public 
persistence.dao.EntityProducer.doThis()]

Solution

  • CDI-Unit does not scan all classes so it does not knwo about EntityProducer class. So you must manually add classes/packages that you want to be scanned by CDI.

    You can use the @AdditionalClasses annotation :

    @RunWith(CdiRunner.class)
    @AdditionalClasses(EntityProducer.class)
    public class cdiTest {
        ....
        ....
    
    }
    

    EDIT

    Then you got an ambigous dependency because you did not properly qualified your injection. You should use @Named("this") or @Named("that") in the test class :

    @Inject
    @Named("this") // or @Named("that")
    protected CDIModel em;
    

    Note also that in CDI we usually use @Qualifier instead of @Named