4

I am trying to use @Qualifier to create an annotation on an Alternative class that will be used instead of the default class marked with @Default. However , when I do this weld reports the error. I am trying to inject demo.cdi.ProductB (the default is demo.cdi.ProductA)

This is the error I get:

Exception in thread "main" org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type Product with qualifiers @Video
  at injection point [BackedAnnotatedParameter] Parameter 1 of [BackedAnnotatedMethod] @Inject public demo.cdi.OrderManagementImpl2.OrderManagementImpl2(@Video Product)
  at demo.cdi.OrderManagementImpl2.OrderManagementImpl2(OrderManagementImpl2.java:0)
WELD-001475: The following beans match by type, but none have matching qualifiers:
  - Managed Bean [class demo.cdi.productA] with qualifiers [@Default @Any]

if I modify beans.xml by adding other alternatives I get the error below:

<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
    <alternatives>
        <!-- <class>demo.cdi.ProductA</class> -->
        <class>demo.cdi.ProductB</class>
        <class>demo.cdi.ProductC</class>
        <class>demo.cdi.productD</class>
    </alternatives>
</beans>      

(the error):

org.jboss.weld.exceptions.DeploymentException: WELD-001409:
    Ambiguous dependencies for type Product with qualifiers @Default

How do I create Qualifier notations for the non-default class?

the rest of the code is below for reference:

(ProductA):

package demo.cdi;
import java.util.LinkedList;
import javax.enterprise.inject.Default;

@Default
public class ProductA implements Product
{
    @Override
    public LinkedList<Feature> getFeatures()
    {
        LinkedList<Feature> rtn = new LinkedList<Feature>();
        rtn.add(new Feature("FKA", "FVA"));
        return rtn;
    }

}

(VideoProduct):

package demo.cdi;
import java.util.LinkedList;
import javax.enterprise.inject.Alternative;
import javax.enterprise.inject.Produces;

@Alternative
@Video
public class VideoProduct implements Product
{
    private VideoProduct() {}

    @Produces
    public Product factoryCreate()
    {
        return new VideoProduct();
    }

    @Override
    public LinkedList<Feature> getFeatures()
    {
        LinkedList<Feature> rtn = new LinkedList<Feature>();
        rtn.add( new Feature("FKB","FVB") );
        return rtn;
    }

}

(Video):

package demo.cdi;    
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;    
import javax.inject.Qualifier;    

@Qualifier
@Retention(RUNTIME)
@Target({TYPE, METHOD, FIELD, PARAMETER})
public @interface Video
{

} 

(OrderManagementImpl2):

package demo.cdi;
import javax.inject.Inject;
import javax.inject.Named;

public class OrderManagementImpl2 implements OrderManagement
{
    private Product product = null;

    @Inject
    public void OrderManagementImpl2(@Video Product _product)
    {
        System.out.println(" [ setProduct ] [ _product = "+_product+"]");
        this.product=_product;
    }

    @Override
    public void createProduct()
    {
        System.out.println(" [ createProduct ] [ product = "+product+"]");
    }
}

(MainApp2):

package demo.cdi;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jboss.weld.Container;
import org.jboss.weld.environment.se.Weld;
import org.jboss.weld.environment.se.WeldContainer;

public class MainApp2
{
    public static void main(String[] args)
    {
        Weld weld = new Weld();
        WeldContainer weldContainer = weld.initialize();
        OrderManagementImpl2 impl = weldContainer.instance().select(OrderManagementImpl2.class).get();
        impl.createProduct();
        weld.shutdown();
    }
} 
Nikos Paraskevopoulos
  • 39,514
  • 12
  • 85
  • 90

1 Answers1

1

The @Video qualifier without the @Alternative annotation on VideoProduct should be enough to inject it as:

@Inject
public void OrderManagementImpl2(@Video Product _product) { ... }

The ProductA, being @Default, should be injected into points like:

@Inject Product x; // no qualifier
Nikos Paraskevopoulos
  • 39,514
  • 12
  • 85
  • 90
  • removing Alternative annotation on video makes Video annotation work, but if I remove the @Video from OrderManagementImpl2 it fails with error: WELD-001409: Ambiguous dependencies for type Product with qualifiers Default, listing ProductA and ProductB as types. It doesn't seem to ignore ProductB when the Video annotation is removed and pick up only the default –  Jan 22 '14 at 16:41
  • 1
    CDI spec, par. 2.3.1: "If a bean does not explicitly declare a qualifier other than `@Named`, the bean has exactly one additional qualifier, of type `@Default`." So actually both beans have the `@Default` qualifier (one explicitly, the other implicitly) thus the error. – Nikos Paraskevopoulos Jan 22 '14 at 21:27
  • ok, so if you are going to use qualifier types its must be best not to use default or alternative at all and make everything a qualifier? –  Jan 23 '14 at 12:57