Adam Bien's Weblog

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.


import javax.ejb.EJB;
import javax.ejb.Stateless;

public class ServiceFacade {

    Service service;

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


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

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 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 2016: Java EE 7 Workshops: Bootstrap, Effective, Architectures, April, 4th-6th, Munich's Airport
On demand workshops: Java EE 7 Bootstrap, Effective Java EE 7 and NEW: Java EE 7 Testing are available for streaming


A book about rethinking Java EE Patterns


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

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


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,


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

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

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

Hi, I tried your example with 2 modifications:

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 04:56 PM CEST #

Hi ,

Thanks for the article !!

I have few queries regarding EJb to ResT.

I have created an EJB 3.0 application and converted it to ReST service. I'm able to invoke methods on this ReST service using the url some thing like this: http://localhost:9080/EJB2TOReSTWeb/rest/customers

Now I'm trying to invoke the methods on my EJB by getting the EJB object through JNDI lookup.

but when I do initialConetext.lookup("jndiName");

I'm getting NameNotFoundException on client side. I have checked for this jndi name on my server, but i dont see any ejb registered with that name.

My Question here is : If we convert an EJB (either 2.1 or 3.0) into ReST service, can we still do the lookup of that EJB the way we do it in normal way using initialContext.lookUp();

I'm using JBoss 4.2.3 server, i tried on WAS6.1 also.

Any help would be really appreciated.


Rajesh V

Posted by Rajesh V on March 07, 2012 at 10:30 AM CET #

Felix, its been a couple years since your post but I wound up needing to access an EJB that was deployed in an EAR file via my REST servlet and did it using JNDI... use the JBOSS jmx-console to find the exact JNDI name for my EJB and then use something like:

try {
Context initialContext = new InitialContext();
if (initialContext == null) {
log.error("JNDI problem. Cannot get InitialContext.");
personsManagerJndi = (PersonsManagerInterface) initialContext.lookup("CDB080409/PersonsManager/local");
if (personsManagerJndi != null) {"RestBean.initializeLists: personsManagerJNDI not null");
} else {
log.error("Failed to lookup personsManagerJNDI");
} catch (NamingException ex) {
log.error("Cannot get connection: " + ex);

from withen the pojo bean that the REST servlet finds via the @Path annotation.

Posted by Jim on September 21, 2012 at 02:53 AM CEST #

This doesnt work in jboss 6.x, EJB injection returns null in every call. After looking for a solution for @EJB injection with rest (resteasy or jersey) for two days, i'm starting to give up on finding a solution.

Posted by Joe on March 13, 2013 at 01:04 PM CET #



Is the @EJB annotation inside the facade class correct?

There is an @Inject annotation in the repository source example.


Posted by Ehsun on April 16, 2013 at 01:10 PM CEST #

Hello Adam,

A question on JAX-RS and how to return an aggregated object ( an object with a list ) .

I am followed this example , a very good example:

The Example has one Player and one Team, I added a third table :

So now , one player has one or many Phones.
But when calling the restful services, I get everything from all the getters except the list !?

I get the following :
<lastspokenwords>I will be back</lastspokenwords>

But where are my phonenumbers ?

regards, Ingo

Posted by inki on November 25, 2013 at 02:21 PM CET #

Hello Adam,

what is the difference between a rest interface with only @path annotation and the other one with @stateless ejb annotation besides the services offered by ejb container ?

Posted by Sam on July 11, 2014 at 08:47 PM CEST #

I have put up an example for this at
Tested with JBOSS AS 7.1.1. Note that a war file is needed in the ear, with a web.xml . This is using JBOSS inbuilt RESTEasy.

Posted by Alex Punnen on August 08, 2014 at 06:48 AM CEST #

Can you please provide me the full project?

Posted by naren on September 23, 2014 at 01:02 PM CEST #

What you describe in this article works with TomEE?

Posted by Leonardo on January 26, 2015 at 01:10 PM CET #

What you describe here works with TomEE?


Posted by Leonardo on January 26, 2015 at 01:11 PM CET #

I realize this post is pretty old by now, but any idea why I can't get this simple example to work with a fresh install of WebLogic 12.1.3? I get a NullPointerException on this line:

return service.getCurrentDate().toString();

and upon inspection it turns out that the service-EJB is indeed NULL.
It works fine in Glassfish 3.1 (as expected).

Posted by ldwl on June 01, 2015 at 01:41 PM CEST #

Post a Comment:
  • HTML Syntax: NOT allowed
Online Workshops
...the last 150 posts
...the last 10 comments