[cdi-dev] Bean<T> that only qualifies super types?

arjan tijms arjan.tijms at gmail.com
Thu Aug 6 12:07:54 EDT 2015


Hi,

I'm wondering if it's possible in CDI to only require a qualifier for
one of the Types in the getTypes collection of a Bean<T>
implementation.

The use case is that I have an abstract class, say Foo, that
implements some interface, say Map:

public abstract class Foo implements Map<String, Object> {
    public abstract void someMethod();
}

Then a Bean<T> implementation creates an instance of Foo:

public class MyBean implements Bean<Foo> {

    @Override
    public Class<?> getBeanClass() {
        return Foo.class;
    }

    @Override
    public Set<Type> getTypes() {
        return new HashSet<Type>(asList(Foo.class, Map.class));
    }

    @Override
    public Integer create(CreationalContext<Integer> creationalContext) {
        return new FooImpl();
    }

    @Override
    public Class<? extends Annotation> getScope() {
        return RequestScoped.class;
    }

    // ...
}

Now the problem is that I don't want to produce Map really, as this
may cause an ambiguity with possibly other Map producers. I only want
to produce Foo.

However, when I limit the getTypes set to contain only Foo:

    @Override
    public Set<Type> getTypes() {
        return new HashSet<Type>(asList(Foo.class));
    }

And I subsequently inject Foo:

@Inject
private Foo foo;

And then call a method from Map on foo:

foo.clear();

CDI (Weld 2.2.2.Final in this case) will throw an exception:

"java.lang.AbstractMethodError: Method
org/jboss/weldx/test/Foo$Proxy$_$$_WeldClientProxy.clear()V is
abstract"

So it looks like CDI (Weld) needs Map.class listed in the getTypes
collection to fully create the proxy. Without it, the proxy only
implements methods that are directly defined by Foo (only
someMethod(); in this example).

I therefor would like to add a qualifier such that the Map portion of
the type needs the qualifier:

@Inject @SomeQualifier
private Map map;

But Foo can still be injected without qualifier:

@Inject
private Foo foo;

Is this possible already? Does something in the spec needs to be
changed for this? (the concrete use case btw is the CDI alignment of
JSF 2.3, where I'm trying to create a Bean<T> for
javax.faces.context.Flash)

Kind regards,
Arjan Tijms


More information about the cdi-dev mailing list