EJB3 With WebWork

The letters ‘E J B’ cause me to slouch back and say “oh no…”. But after a few encouraging words to myself, I gave it a shot. If you look at my previous blog on WebWork you will see that WebWork was used as the web-tier framework and Spring was used to manage the business/service tier. On the service tier there existed a ‘TimeService’ which would (you are right) return the time of the day. One WebWork action, named Timer, would “talk” to the business tier to get the time. WebWork can be configured to inject Spring objects into the action. That is the mechanism I used to get the job done there.

Now I decided to use the exact same sample in the EJB example here.Instead of the Spring based service tier I wrote up the service tier as EJB (only stateless sessions beans). My aim was to inject the EJB service into the WebWork action. There is no Spring in this example.Spring is gone. I am neither from the Spring camp or the EJB3 camp. I am from ‘lets get the job done camp’. And with EJB3 I do see a good alternate programming model. Its all dependency injection in EJB3 so it will smell and feel a little like Spring. BTW I ran this example on JBoss 4.0.5.

Here is the service interface for the time service.

And here is the stateless session bean implementation of the service.As you can see its clearly a POJO. No pesky interfaces and callbacks to implement. Here is where it smells and feels like Spring (or any other decent IOC engine).

The only thing that tells me this is an EJB is the annotations. This is marked as a stateless session bean with a local interface of TimeService.

Now lets see the Timer action class in the web tier. This is the WebWork action class.

As you can see its really simple. Wait … what is the @InjectService annotation here. You can see that in the getTime method I call out to the service to get the time. In the WebWork+Springblog I could depend on the WebWork+Spring integration for the service to be injected in. Not any more. Now my TimeService is an EJB. I could do away with the @InjectService and instead directly lookup the JNDIcontext for the EJB. But that would not be a good architectural approach. You want to consolidate the service locator feature into one place. With the introduction of annotations in Java 5 you now have apowerful way of moving such features into annotations. Note in EJB3 you can do dependency injection within and between container managed objects. The Timer class is not an EJB3 managed object. So you are on your own.

Here is the annotation.

This is a marker annotation used to mark where service injection is required at the field level. I am not a fan of setter injection for such things. Why write a setTimeService method just to have injection done there and a false sense of OO compliance?

Finally, to inject the service I wrote up a quick WebWork interceptor that looked up the JNDI context and injected the desired service. This code can be more robust, but this works.

To configure the interceptor, update the xwork.xml file as follows.

Compile and deploy the application. The download jar contains the full source and the ant script to create the ear file. Now when you hit the URL localhost:9090/webworks/askfortime.jsp you will see.

Enter name and hit ‘Get Time’. You should now see:

To download the code click here. The code is missing all of the external jar files for EJB3. This project was built with JBoss. The generated ear file myapp.ear will contain

– service.ejb3 (this is a jar file named with .ejb3 extension so that JBoss knows to look inside for all EJB3 beans).
– webworks.war (all of the code and libraries for the WebWork supported client tier).
– META-INF/application.xml (contains references to the web module and ejb module)

Also I had the following JBoss libraries in my eclipse/Ant classpath for compilation. Don’t package these with the ear file please.

  • jboss-4.0.5.GA/server/all/deploy/ejb3.deployer/ejb3-persistence.jar
  • jboss-4.0.5.GA/server/all/deploy/ejb3.deployer/jboss-ejb3x.jar
  • jboss-4.0.5.GA/server/all/deploy/ejb3.deployer/jboss-ejb3.jar

Other than this I had the following jars for WebWork support in the war file. You can drop them in the lib folder of the project:

  • xwork.jar
  • webwork-2.2.4.jar
  • tiles-core.jar
  • rife-continuations.jar
  • oscore.jar
  • ognl.jar
  • freemarker.jar
  • commons-logging-1.0.4.jar
  • commons-digester-1.6.jar
  • commons-beanutils-1.7.0.jar

I started JBoss with run.sh -c all.

As you can see its clearly possible to build a system around EJB3 (this is for those of us for whom EJB1 and 2 left a bad taste in our mouths).For those starting new from EJB3 … it does not matter.