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

Martin Kouba mkouba at redhat.com
Fri Aug 7 05:27:40 EDT 2015


Dne 6.8.2015 v 18:07 arjan tijms napsal(a):
> 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;
>      }

I believe the bean class should not be abstract. It's not clearly 
defined but there are some indirect suggestions: abstract class is not a 
managed bean -> Bean.getBeanClass() returns the bean class of the 
managed bean... etc.

>
>      @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).

The problem here is with the abstract Foo. Let me check the proxy 
bytecode and find out more details.

>
> 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)

No, this is not possible. Qualifiers are tied to a bean definition, not 
to a bean type.


>
> Kind regards,
> Arjan Tijms
> _______________________________________________
> cdi-dev mailing list
> cdi-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/cdi-dev
>
> Note that for all code provided on this list, the provider licenses the code under the Apache License, Version 2 (http://www.apache.org/licenses/LICENSE-2.0.html). For all other ideas provided on this list, the provider waives all patent and other intellectual property rights inherent in such information.
>

-- 
Martin Kouba
Software Engineer
Red Hat, Czech Republic


More information about the cdi-dev mailing list