Hi folks
First: I'm somewhat new to Java EE and DI, so I may be missing the obvious as I try to wrap my head around the three different DI systems (JSF2, CDI/Weld, EJB) in Java EE 6.1 . I've read the tutorial, done a lot of searching, etc though, so if I'm missing the obvious it's because I'm asking the wrong questions.
I'm running Glassfish 3.0.1 on Linux (Ubuntu 10.04 in case it matters) and having real problems handling injection of my data model EJBs into my JSF2 session scoped models using CDI (Weld). And yes, before you ask, I have beans.xml in place and CDI is activating, trying to inject, and throwing an exception (see below).
I'm trying to inject a local no-interface view of a @Stateless EJB into a JSF2 @Named @SessionScoped backing bean. The EJB is one of several that extend an abstract generic base class.
If I inject it with an @EJB annotation, eg:
[code]@EJB TheEJBClass memberName;[/code]
... the EJB isn't actually injected, leaving memberName null.
If I inject it with a CDI @Inject annotation:
[code]@Inject TheEJBClass memberName;[/code]
... then CDI complains, reporting:
[code]
java.lang.IllegalStateException: Unable to convert ejbRef for ejb TheEJBClass to a business object of type class my.package.name.TheAbstractBase
at com.sun.ejb.containers.EjbContainerServicesImpl.getBusinessObject(EjbContainerServicesImpl.java:104)
at org.glassfish.weld.ejb.SessionObjectReferenceImpl.getBusinessObject(SessionObjectReferenceImpl.java:60)
....
[/code]
I've tried converting the base to concrete class and de-generifying it, but encounter the same problem, so I don't think I'm hitting the Weld bugs with generic bases (
https://jira.jboss.org/browse/WELD-305,
https://jira.jboss.org/browse/WELD-381,
https://jira.jboss.org/browse/WELD-518).
An outline of the code, with full package qualification on annotations added for clarity, is:
[code]
// JSF2 managed backing bean.
@javax.inject.Named
@javax.enterprise.context.SessionScoped
public class SomeJSF2Model implements Serializable {
@javax.inject.Inject TheEJBClass memberName;
// blah blah
}
// One of several EJB classes that extend TheAbstractBase
@javax.ejb.Stateless
public class TheEJBClass extends TheAbstractBase {
// blah blah
}
public abstract class TheAbstractBase {
// blah blah
}
[/code]
I'm really quite lost trying to figure out how all the DI stuff interacts in Java EE 6, and would really, really appreciate a helping hand. Once you figure the lifecycle stuff out and the conceptual structure behind what it's for / how it works, it seems like a good idea, but I'm struggling with the practical aspects. In this case, for example, I can't for the life of me figure out why Weld cares that TheEJBClass extends TheAbstractBase, given that I'm injecting it explicitly via a local no-interface view.
Very similar code that used JSF2's built-in lifecycle and injection features worked, but given that this is a new project and CDI is where things are heading in the future, I thought it best to try to go for CDI. Here's what I started out with using JSF2/EJB injection, which worked:
[code]
// JSF2 managed backing bean. Using @ManagedBean and JSF2's @SessionScoped
// instead of CDI @Named and CDI @SessionScoped this time.
//
@javax.faces.bean.ManagedBean
@javax.faces.bean.SessionScoped
public class SomeJSF2Model implements Serializable {
@javax.ejb.EJB TheEJBClass memberName;
// blah blah
}
// One of several EJB classes that extend TheAbstractBase
// Unchanged from CDI version
@javax.ejb.Stateless
public class TheEJBClass extends TheAbstractBase {
// blah blah
}
// Unchanged from CDI version
public abstract class TheAbstractBase {
// blah blah
}
[/code]
I'm currently working on putting together a self-contained test case, but thought I'd fire off the question now in case this is something where I'm just doing something silly or there's a well known solution my Google-fu isn't up to finding. Why did it work with JSF2/EJB injection, but fail with CDI injection?
[Message sent by forum member 'ringerc']
http://forums.java.net/jive/thread.jspa?messageID=480458