Adam Bien's Weblog

Monday Jun 29, 2009

EJB 3.1 And REST - The Lightweight Hybrid

The Local / Remote interfaces in EJB 3.1 are optional. You can still, however, expose a Session bean as a RESTFul (JSR-311) service.


package com.abien.patterns.business.rest.boundary;

import com.abien.patterns.business.rest.control.Service;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.ws.rs.GET;
import javax.ws.rs.Path;

@Stateless
@Path("current")
public class ServiceFacade {

    @EJB
    Service service;

    @GET
    public String getDate(){
        return service.getCurrentDate().toString();
    }

}


The Service is just another, usual, @Local bean:


@Stateless
public class Service {

    public Date getCurrentDate(){
        return new Date();
    }
}


A ServiceFacade becomes available via REST, just denoting it with the JAR-RS annotations. Its both an EJB 3.1 and a REST-resource - it is available under http://localhost:8080/EJBRestHybrid/resources/current (tested with Glassfish v3 preview). It will return the current time as String (Mon Jun 29 08:19:32 CEST 2009). The additional @Stateless has the following advantages:

  • Injection capabilities: you can easily inject other EJBs, EntityManagers, JMS-resources, DataSources or JCA connectors
  • Transactions: all changes made in a REST-call will be automatically and transparently synchronized with the database
  • Single threading programming model -> the old EJB goodness.
  • Monitoring: an EJB is visible in JMX
  • Throttling: its easy to restrict the concurrency of an EJB using ThreadPools or bean pools
  • Vendor-independence: EJB 3 runs on multiple containers, without any modification (and without any XML in particular :-))

Exposing a protocol-neutral ServiceFacade directly via REST can make it REST-dependent. E.g. you may pass JAXB-enabled classes as parameters / return - values. It will be hard then to expose the ServiceFacade through other channels. On the other hand - if REST is all you need, it is the simplest and leanest approach. There are no additional libraries needed - everything is already included in a Java EE 6 container (in Glassfish v3 the whole EJB 3.1 container is < 1 MB...). 

The whole example project (tested with Netbeans 6.7rc3 and Glassfish v3 Preview) with source code was pushed into http://kenai.com/projects/javaee-patterns. In Netbeans 6.7 you will have to enable Glassfish v3 capabilities. If you are using vi or emacs :-), you will have to include the Java EE 6 API to the classpath.

[This sample is based on the ServiceFacade pattern from the "Real World Java EE Patterns" book] 



*NEW* Workshop: "Real World Java EE 6/7 Bootstrap" and book: Real World Java EE Night Hacks--Dissecting the Business Tier

Comments:

Yes, I think the EJB31/JAX-RS combination has a bright future (partly why I used this to illustrate the GlassFish v3 distro/packaging feature in http://blogs.sun.com/alexismp/entry/glassfish_v3_custom_distributions_with)

Posted by Alexis MP on June 29, 2009 at 03:42 PM CEST #

@Alexis,

I use this combination in some projects. It was, however, two-layer architecture with GF 2.1. With GF v3 and EJB 3.1 we will be able to eliminate one layer -> always good stuff!,

thanks & regards,

adam

Posted by Adam Bien on June 29, 2009 at 05:13 PM CEST #

How about call performance:
Traditional RMI-IIOP versus http/RestFull ?

Posted by Sakari on May 27, 2010 at 09:21 AM CEST #

Hi, I tried your example with 2 modifications:

1.
@Stateless
@Path("current")
public class ServiceFacade implements TestInterface {
...
}

With TestInterface GF3 wasn't able to deploy service.

2.I tried to package given example into ejb-jar module (instead of war module).
Again packaged as ejb-jar server didn't deploy such package.

Have you any ideas why?
Thank you, nice articles ....

Posted by Felix on October 27, 2010 at 02:56 PM CEST #

Post a Comment:
  • HTML Syntax: NOT allowed
Meta
My Recent Book
Java One 2009/2011
...the last 150 posts
...the last 10 comments
Links
License