6 Replies Latest reply on Nov 5, 2012 7:02 AM by cadin

    How do @Produces and generics work together?

    cadin

      Hello friends!

       

      I'm having a hard time figuring out how does @Produces work with generics. I'm trying to get a specific solution to work.

       

      I'm using Java EE 6 on JBoss 7.1.1.Final. Although there is a bit of code in this post, I tried to make it fairly simple to understand (I hope).

       

      Nice!

       

      First, I created a TestBean class which is just a holder for another object by using generics. I also created a qualifier @Ignore so that I can create a producer for the default injection.

       

      package rc;
      import static java.lang.annotation.ElementType.FIELD;
      import static java.lang.annotation.ElementType.METHOD;
      import static java.lang.annotation.ElementType.PARAMETER;
      import static java.lang.annotation.ElementType.TYPE;
      import static java.lang.annotation.RetentionPolicy.RUNTIME;
      import java.lang.annotation.Retention;
      import java.lang.annotation.Target;
      import javax.inject.Qualifier;
      @Qualifier
      @Retention(RUNTIME)
      @Target({ TYPE, METHOD, FIELD, PARAMETER })
      public @interface Ignore {}
      

       

      package rc;
      @Ignore
      public class TestBean<T> {
         private T instance;
         public T get() {
            return instance;
         }
         public void set(T instance) {
            this.instance = instance;
         }
      }
      

       

      Simple as that... Next I created a producer for that TestBean.

       

      package rc;
      import javax.ejb.Stateless;
      import javax.enterprise.inject.Produces;
      @Stateless
      public class TestProducer {
         @Produces
         public <T> TestBean<T> getTestBean() {
            return new TestBean<>();
         }
      }
      

       

      Again, very simple code... Next I created a ManagedBean that injects the TestBean.

       

       

      package rc;
      import javax.ejb.Stateful;
      import javax.enterprise.inject.Model;
      import javax.inject.Inject;
      @Model
      @Stateful
      public class TestView {
         @Inject
         private TestBean<String> testBean;
         public TestBean<String> getTestBean() {
            return testBean;
         }
      }
      

       

      Perfect! All of the above code works nicely! Congratulations to Java EE 6.

       

      Problem!

       

      Problem starts when I try to inject another generic type...

       

      package rc;
      import java.util.List;
      import javax.ejb.Stateful;
      import javax.enterprise.inject.Model;
      import javax.inject.Inject;
      @Model
      @Stateful
      public class TestView {
         @Inject
         private TestBean<List<String>> testBean;
         public TestBean<List<String>> getTestBean() {
            return testBean;
         }
      }
      

       

      Using the code above for the TestView, I get this wonderful Exception.

       

      org.jboss.weld.exceptions.DeploymentException: WELD-001408 Unsatisfied dependencies for type [TestBean<List<String>>] with qualifiers [@Default] at injection point [[field] @Inject private rc.TestView.testBean]
      

       

      Help!

       

      I know this is probably 'cause I'm miss understanding the use of generics for injection. But I believe I should be able to make it work somehow, 'cause Weld designers did it!

      Here is an example:

       

      @Inject
      private Event<String> event;
      

       

      and

       

      @Inject
      private Event<List<String>> event;
      

       

      Both work fine! That's what I'm trying to achieve!

       

      Can someone help me, please?

       

      Thank you all!