I already have JPA working well (without the RAD7.5 tooling), and now I want a stateful bean. So I make a plain Java project and put my existing WAS6.1+EJB30FeatPak library in its build path. Now all the annotations such as @Stateful and @EJB are correctly found. I define an interface, then a bean that implements it, annotated with @Stateful. I reference this new EJB bean in my UI bean, using the @EJB annotation. As far as the various books and articles I have access to, that is all you need. It looks clean. I am working from the books "Pro EJB3 Java Persistence Architecture" by Mike keith and Merrick Schincariol, and "Java Persistence with Hibernate" by Christian Bauer and Gavin King. Both of these books cover stateless and stateful session beans, although not exhaustively. I have also looked at at least 6 articles on the Web with names like "Getting Started with EJB3.0" or somesuch.
When I tried to run it (WAS 6.1.0.25), I got the following at server startup time:
com.ibm.ws.exception.RuntimeWarning: com.ibm.ws.exception.RuntimeError: java.lang.ClassCastException: org.eclipse.jst.j2ee.application.internal.impl.EjbModuleImpl incompatible with org.eclipse.jst.j2ee.commonarchivecore.internal.ModuleFile
at com.ibm.ws.runtime.component.ApplicationMgrImpl.startApplications(ApplicationMgrImpl.java:809)
at com.ibm.ws.runtime.component.ApplicationMgrImpl.start(ApplicationMgrImpl.java:563)
at com.ibm.ws.runtime.component.ContainerImpl.startComponents(ContainerImpl.java:977)
..
Have I missed something? Is there something else I need to do to make this work?
Chris Gage
Gage Information Services Inc.
Raleigh, NC, USA
+1 919 623 5764
Now I get a NullPointerException when I try to use the bean which should have been injected.
The bean itself is defined with:
{code}
@Stateful
@TransactionManagement(javax.ejb.TransactionManagementType.CONTAINER)
public class ActivityBean implements IActivity {
@PersistenceContext(unitName = "MOCData")
protected EntityManager em;
{code}
The reference to the bean is defined with:
{code}
@EJB
private IActivity activityBean;
{code}
The code in the UI that fails:
{code}
activityList = activityBean.search(activitySearch);
{code}
This is a fairly straightforward search method passing an object that contains the search terms, expecting a List of Activity objects in return.
EJB injection can fail for a number of reasons. When the bean/servlet/client whose field you want injected was started (either when the app started, or when the client was initialized/looked up), were there any warnings or errors in the logs?
If the client is in another EAR, then you must provide a binding to tell the injection engine where to lookup the bean - AutoLink/EJBLink only works within an application.
Another possibility is that the ActivityBean failed to initialize. Log output should also show this possibility.
Andy
I see nothing in the server startup that is different from when this was all done by Spring dependency injection.
Since my post I have tried the @PostConstruct annotation and using ejbContext.lookup() (from the Keith/Schincariol book) but neither the PostConstruct init() method nor the injecting setSessionContext() method get invoked, and I still get an NPE.
Here is the relevant part of my UI manager bean (which is actually a JSF managed bean):
{code}@EJB(name = "activity", beanInterface = ActivityBean.class)
public class ActivityUiManager extends UiManager {
private ActivitySearch activitySearch;
private List activityList;
private SessionContext sessionContext;
@EJB
private IActivity activityBean;
@PostConstruct
public void init() {
activityBean = (IActivity) ejbContext.lookup("ActivityBean");
}
public void setSessionContext(SessionContext sessionContext) {
this.sessionContext = sessionContext;
}
..
activityList = activityBean.search(activitySearch);
..
{code}
Here is my Interface:
{code}public interface IActivity {
List search(ActivitySearch activitySearch);
}
{code}
and the front part of my stateful bean:
{code}@Stateful
@TransactionManagement(javax.ejb.TransactionManagementType.CONTAINER)
public class ActivityBean implements IActivity {
protected final Logger log = Logger.getLogger(getClass().getName());
@PersistenceContext(unitName = "MyData")
protected EntityManager em;
..
public List search(ActivitySearch activitySearch) {
..
{code}
I remember how hard EJB 2.1 was from several years ago. EJB3 session beans are supposed to be simpler, POJO based, do not require anything but annotations, do not require an ejb xml file. I have combed Google for examples, but clearly I have missed something really fundamental, because I cannot make any of the various techniques described in books or websites work correctly.