3 Replies Latest reply on Oct 29, 2014 11:17 AM by mkouba

    Produces method with interface arg. fails when interface has 2 implementations

    dde

      With Weld 2.1.2 the code below gives me an instance of type OtherPro when I ask the WeldContainer an instance for type Pro without any annotation.  Shouldn't this be rather type MyProducer?

       

      If I move the producer method into a separate class I get a Weld exception saying:

      org.jboss.weld.exceptions.AmbiguousResolutionException: WELD-001318: Cannot resolve an ambiguous dependency between:
        - Managed Bean [class OtherPro] with qualifiers [@Def @Any],
        - Producer Method [Pro] with qualifiers [@Any @Default] declared as [[BackedAnnotatedMethod] @Produces @Singleton public static Factory.create(@Def Pro)]
      
      
      

      It does not matter if I change the return type to MyProduer.

       

      I'm clearly missing something.  Anyone who can explain this behaviour?

       

      public interface Pro {
      
          public void bla();
      }
      
      @Target({ TYPE, METHOD, FIELD, PARAMETER })
      @Retention(RUNTIME)
      @Documented
      @Qualifier
      @Inherited
      public @interface Def {
      
      }
      
      @Singleton
      @Def
      public class OtherPro implements Pro {
      
          @Override
          public void bla() {
          }
      }
      
      public class MyProducer implements Pro {
      
          public MyProducer(final Pro pro) {
      
          }
      
          @Override
          public void bla() {
          }
      
          @Produces
          @Singleton
          public static Pro create(@Def final Pro pro) {
              return new MyProducer(pro);
          }
      }
      
      
      
        • 1. Re: Produces method with interface arg. fails when interface has 2 implementations
          mkouba

          Hi Dieter,

          the example seems to be a bit confused. Where's the definition of the @Jdbc annotation (see MyProducer.create)? Also what's the way you are "asking the container", do you use BeanManager or is there another bean with an injection point? A full stack trace would be also helpful.

          • 2. Re: Produces method with interface arg. fails when interface has 2 implementations
            dde

            I'm sorry, replacing names was not completely done.  @Jdbc should've been @Def.

             

            I retrieve the instance with:

             

            WeldContainer container = new org.jboss.weld.environment.se.Weld.Weld().initialize();

            container.instance().select(new TypeLiteral<Pro>(){}).get();

             

            This code is used for an integration test.

            • 3. Re: Re: Produces method with interface arg. fails when interface has 2 implementations
              mkouba

              Ok. First of all, TypeLiteral only makes sense for parameterized types. So instance.select(Type.class) would be better.  WeldContainer.instance().select(new TypeLiteral<Pro>) is actually looking for a bean with type  Pro and qualifier  @Any (see also org.jboss.weld.environment.se.beans.InstanceManager). In your example OtherPro is the only matching bean - the producer method MyProducer.create is ignored because it's not "a default-access, public, protected or private, non-abstract method of a managed bean class or session bean class" (note that MyProducer is not a bean because it doesn't have an appropriate constructor, see also http://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#producer_method). If you move the producer method into a separate class (probably a valid bean), there are two beans which satisfy the required type and qualifiers, neither of which is an alternative. And so the container complains about ambiguity.