How do @Produces and generics work together?
cadin Nov 4, 2012 7:01 AMHello 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?