« RichFaces and Protot... | Main | Ubuntu 10.4, Glassfi... »

EJB 3.0 and WebServices

If you are interesting in programming EJB 3.0 (JEE5 / JEE6) you may be also try to implement a web service. Developing WebServices in JEE5 is not so hard. There are a lot of good books about all this stuff. I spent a lot of time the last two years in developing JEE5 WebServices.

But now after I started to migrate the Imixs Workfow Project  to Glassfish 3 I run into a lot of problems. And today I found out that there is a really big trap where I stumbled into.

In most of the JEE5 EJB/WebService examples you learn to annotate simply your stateless session ejb with the @webservice annotation to generate a new web service. So these examples combine EJB and Webservice in one implementation. The code result cann look something like this:

 .....
@DeclareRoles( { "myrole1",
        "myrole2" })
@RolesAllowed( { "myrole1" })
@Stateless
@Remote(org.imixs.workflow.jee.ws.WorkflowWebService.class)
@WebService(name = "WorkflowManagerService", targetNamespace = "http://imixs.org/workflow/services", serviceName = "WorkflowManagerService", portName = "WorkflowManagerServicePort", wsdlLocation = "ix_workflowservice.wsdl")
public class WorkflowWebServiceBean implements
        WorkflowWebService {

    @EJB
    SomeServiceEJB myService;
....

    @WebMethod
    public Entity myMethod(@WebParam(name = "workitemid", mode = Mode.IN)String uniqueid)
            throws Exception {
        ....
    }
....

This is a code snippet out of the Imixs workflow project which works very well in Glassfish 2.1.
At the end the combination of @Stateless and @WebService annotations looks interesting but I dissuade you to do so! You may run into a lot of problems make it hard to get a platform independent ejb code. The reason is that you are forced to provide a lot of application server specific deployment configuration in your descriptors. For example in Glassfish you have to define the authentifcation method in the sun-ejb-jar.xml. Also providing wsdl files is not so easy as they are now mixed with your ejb code. This seems to be mostly a problem for JEE6 / Glassfish 3. I run into these problems when I tried to deploy my bullet proved code from Glassfish 2.1 on Glassfish 3 or JBoss 5. JEE6 makes things easier and the goal should be to move away as many declarations in source code as possible.

So at the end my recommendation is to saperate allways(!) the web service implementation from the EJB module. Do not bundle stateless session ejbs together with webservices in a JEE EJB 3.0 module. The best way seems to be to implement the webservice classes (those classes which use the @WebSerivce annotation) in a web module. You can simply add this web module to you ear package to make use of EJB code like I do in my code example above. This will work in JEE5 (Glassfish 2.1) as well as in JEE6 (Glassfish 3).

And finally if you separate your code in different modules you can kick the webservice module if you do not need it in your application. In most cases web services are long-winded code. Better work with REST services ... ;-)