BT

Java EE6: EJB3.1 Is a Compelling Evolution

by Josh Long on Feb 15, 2010 |

The Enterprise Java Bean 3.0 (EJB 3) specification marked a very important way-point in the long march of Java in the enterprise. The specification was built very apparently with input from the community. It represented a much more consistent services paradigm, one that was more POJO-friendly and generally less complicated. The level of indirection afforded by Java 5's annotations made the paradigm more powerful while requiring less of the developer. The willingness to forsake bad legacy decisions for different, new solutions, made the framework interesting to people who might have previously shunned EJB. EJB Entity Beans disappeared, replaced with JPA Entities. The handful (or more) of Java classes and interfaces required for your average bean in EJB 2.1 or before became 2+ Java classes or interfaces. Convention-over-configuration based defaults were put into place to make it more straightforward to get up and running. EJB 3.0 was a revolution.

If EJB 3.0 was a revolution, EJB 3.1 is a very capable, welcome evolution. EJB 3.1 features a raft of features that feel like they should have been available in EJB 3.0. One can forgive the cautious pace of the specification - better to get 80% right than to freeze an imperfect model into the glacial evolution of a specification. Its arrival isn't unwelcome, of course. It is also telling that - even with all these new features - the EJB 3.1 specification and all the backwards compatibility and additions that if offers - is 626 pages, 14 pages shorter than the EJB 2.1 specification from almost a decade ago!

We will review some of these features in this post, and address their use.

New Features in EJB 3.1

Some of the biggest changes in EJB 3.1 are not additions to the platform, but reductions in the required ceremony in using the platform. Some increase the surface area of the user-facing APIs to introduce more flexibility. Some simply bring more flexibility.

Singletons

A singleton is a new type of session bean that provides one extra guarantee: the bean will only be created once per running JVM. There are many use cases that are better served with this feature: caching, for example. Another is the ability to guarantee a shared view on a resource that the application server doesn't already provide. Simple storage for valuable data that needn't be persisted but that might be too expensive to recreate is another option. Let's look at a (contrived) example. We'll assume that the User entity has already been created elsewhere (perhaps using the JPA 2.0).

@javax.ejb.Singleton 
public class ChatRoom { 

   private java.util.Map<User,Collection<String>> userComments; 

   @PostConstruct 
   public void setup (){ 
     userComments = new java.util.concurrent.ConcurrentHashMap<User,Collection<String>>(); 
     /* ...*/
   }
   public void join(User usr){ /* ...*/ }
   public void disconnect(User usr){  /* ...*/ }
   public void say(String msg){ /* ...*/  }
}

All clients can update the same mutable state by simple acquiring a reference to the ChatRoom instance. Clients are guaranteed access to the same instance upon acquisition. As this is a session bean, it offers the same guarantees as any other session bean: this bean is fully thread safe.

@javax.ejb.EJB 
private  ChatRoom  chatRoom ; 

 /* ... */

chatRoom.join(myUser) ;
chatRoom.say( "Hello, world!");
chatRoom.disconnect();

Singletons are designed for concurrent access. The specification gives the developer sophisticated control over concurrency control. You may use the container to force certain types of access in a declarative way. This behavior is the default. You may explicityly declare as using container-managed concurrency by annotating it with @javax.ejb.ConcurrencyManagement(CONTAINER). If you want to exert more control over the bean, use @javax.ejb.ConcurrencyManagement(BEAN). Container-managed concurrency lets you stipulate the type of access at the method-level or class-level. You might by default stipulate that all business methods are to be serialized by using @javax.ejb.Lock(WRITE) at the class level and then optimize for the case where a method is effectively "read-only," with no state-modifying side-effects. You would annotate that read-only method with @Lock(READ). All access on a method annotated with @Lock(WRITE) is serialized, and blocks client access until completion, or a timeout occurs. You may exercise control over the length of a timeout using the @AccessTimeout annotation, which takes a value of java.util.concurrent.TimeUnit. Thus, we might be able to rework the code in the first implementation of the ChatRoom to take advantage of this concurrency control.

@javax.ejb.Singleton 
@javax.ejb.Lock(WRITE)
public class ChatRoom { 

   private java.util.Map<User,Collection<String>> userComments; 

   @PostConstruct 
   public void setup (){ 
     userComments = new java.util.concurrent.ConcurrentHashMap<User,Collection<String>>(); 
     /* ...*/
   }
   public void join(User usr){ /* ...*/ }
   public void disconnect(User usr){  /* ...*/ }
   public void say(String msg){ /* ...*/  }

   @javax.ejb.Lock(READ)
   public int getCountOfActiveUsers(){ /* ... run through the map and count ... */ } 
}

Naturally, such a ChatRoom will ultimately die a memory starved death as the number of users and posts overwhelms the application server's memory. Some sort of expiration mechanism is in order. For the sake of demonstration, let's imagine a periodic garbage collector that runs through the ChatRoom posts and LRU destroys (or, perhaps using JPA and the EntityManager. persists and then destroys) old chat data.

The EJB Timer

EJB has had a Timer mechanism since EJB 2.1. However, it's always worked in terms of millisecond intervals and been fairly tedious to set up. The situation was a bit improved with EJB 3.0, but the fact remained that timers were still essentially procedurally declared and interval-based. If you want to set something up at the beginning of the week, for example, then you faced challenges. EJB 3.1 improves things by providing a declarative, flexible timer service that pulls the rug out from under various other schedulers like Quartz or Flux. For most simple scheduling needs, including CRON-like scheduling, EJB 3.1 is a fine solution. Let's revisit our ChatRoom. We want to schedule a bean to go through and garbage collect old data.

@javax.ejb.Singleton 
public class ChatRoom {

   private java.util.Map<User,Collection<String>> userComments;
        
   @javax.ejb.Schedule(minute="1", hour="*") 
   public void cleanOutOldDataFromChatLogs() { 
      /** ... not reprinting all the existing code ... */
   }
}

We've written a method that will go through and run a quick check on the data and - as necessary - expunge old /irrelevant chat logs so that we can keep things manageable. Here, we're using a declarative model to ensure that the method runs every hour. We could, of course, still inject the TimerService from EJB 3.0.

No-Interface Views

In EJB 3.0 beans were required to support at least one interface (a local or remote business interface) that would be used as the view of the bean to the clients of that bean. While indirection via interfaces is a very powerful technique, it sometimes just complicates things. In EJB 3.1 you may write a bean that has no interfaces. The client view is then the public methods as exposed by the class.

@javax.ejb.Stateless 
public class Calculator { 

  public float add ( float a , float b) { 
    return a + b; 
  } 

  public float subtract (float a , float b){ 
    return a - b ; 
  }

} 

Clients of this bean may simply accquire as usual with injection and invoke it:

@javax.ejb.EJB 
private Calculator calculator; 

...
float result = calculator.add( 10 , 10 ) ;
...

Asynchronous Services

The simple way to handle scaling issues is... to simply not handle them (until capacity is available)! This approach is most famously characterized by the SEDA (staged event driven architecture) pattern, wherein bottlenecks are avoided by queuing work. This lets submissions of work being queued and the client proceed. If a component downstream takes a long time, and the system is under load, this pattern ensures that the slow component doesn't bring the system to its knees.

Another approach to scaling is to not block client invocations on one-way message exchanges. Another approach still is to simply work asynchronously, letting execution on the client proceed until a result comes back. All of these approaches are embodied in the new asynchronous support for services in EJB 3.1. A bean class, or individual methods, may be annotated with the @javax.ejb.Asynchronous annotation to tell the container that clients should not block on the result of the invocation. This lets the client proceed instantaneously, and - in theory - it would enable a container to buffer the work until it's better able to perform it.

If a bean class, or a business interfaces, is annotated with @Asynchronous, then all methods on the bean are deferred. Otherwise, only methods that are annotated with @Asynchronous are deferred. Asynchronous methods may return void, or an instance of java.util.concurrent.Future<V>. The client may consult the instance of Future<V> for the result at any time later, but the result of the invocation proceeds instantly in the client thread, and doesn't block. This way, if the EJB takes an hour or two, then it doesn't matter - the client is unaffected. Conceptually this is the same as calling a service with the sole job of sending the request to a JMS queue.

The instance of Future<V> may be used to cancel the job, or wait for the result. A client's transactional context is not propagated to the asynchronous method. REQUIRED, then, is effectively REQUIRES_NEW for the asynchronous method.

Let's take a look at an example: we want to build a service that talks to several other web services and aggregates the results. We want the results, but we can't leave the client request (a web page, perhaps?) hanging. Such a service might look as follows:

@javax.ejb.Stateless
public CarHotelAndAirLineBookingServiceBean implements CarHotelAndAirLineBookingService  {
  @javax.ejb.Asynchronous  
  public Future<BookingConfirmation> bookCarHotelAndAirLine( Car rental, Hotel hotel, AirLine airLine) { 
    /**  ...  */
   } 
 } 

In the client - a JSF action - we might invoke such a service as follows:

@Named 
public BookingAction { 

        @javax.ejb.EJB  private  CarHotelAndAirLineBookingServiceBean bookingService; 

        private Future<BookingConfirmation> confirmation;

        public String makeRequest(){ 

                Hotel hotelSelection = ... ;
                Car rentalSelection = ... ;
                AirLine airLineSelection = ... ; 

                confirmation = bookingService.bookCarHotelAndAirLine(
                    rentalSelection, hotelSelection, airLineSelection ) ; 
                return "showConfirmationPending";
        }

        public Future<BookingConfirmation> getConfirmation(){ /* ... */ }

        /* ... */
}

Simplified Deployment

EJB 3.1 also marks the first version of the specification to provide a dramatically simpler deployment paradigm with support for deployment inside a in .WAR file. A class with a component-defining annotation becomes an enterprise bean component when packaged within WEB-INF/classes or as a .jar in WEB-INF/lib. Enterprise beans may also be defined using a WEB-INF/ejb-jar.xml file. Beans packaged in a .WAR share a single namespace, and become part of the .WAR's environment. Packaging a .jar in WEB-INF/lib is thus semantically equivalent to putting the classes in WEB-INF/classes.

Another novel feature of the new specification is EJB Lite. For many applications, EJB technology is more than is required. EJB Lite provides a more streamlined subset centered around the use of session-bean components. It provides a way to use EJB components in an embeddable fashion, too, which simplifies unit tests. EJB Lite supports stateless, stateful and singleton session beans. Beans may have a local-, or no-interface view. They may work with interceptors, and use container services like transactions and security.

EJB 3.1 is a powerful tool in the developers toolkit, and is clearly being evolved into something that'll meet the 80% use cases of most applications. The future looks good for the specification. This is also the first release of the specification to target certain specification features for future removal using the Java SE pruning mechanism. Aspects of the specification that have been marked for possible future removal include pre-3.0 support for older forms of container-managed and bean-managed persistence, the EJB 2.1 client view of entity beans, EJB QL (the query language from EJB 2.1), and JAX-RPC based web service support (both endpoints and client views; they were added in J2EE 1.4)

Clearly, EJB 3.1 is a compelling, backwards-compatible upgrade, and represents a fine next step from the work started in JSR 220 (EJB 3.0) more than 5 years ago.

Hello stranger!

You need to Register an InfoQ account or to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Tell us what you think

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Great Article :) by Razib Shahriar

Your article nicely summarizes the great features EJB3.1 provides the developers to take advantage of. It would be great if you could write more on the CDI/DI features. Keep up the good work!

Re: Great Article :) by Charles Humble

Thanks for the feedback - glad you like the article.

We have covered CDI as part of this series of posts - see www.infoq.com/news/2010/01/javaee6-di

There's also a Q&A with spec lead Gavin King here
www.infoq.com/news/2009/11/weld10

Is that enough or would you like to see more detail on CDI?

Charles

It's an improvement but by Jean Luc Picard

The productivity level and code maintainability is still far from frameworks focused on developer comfort such as grails, jruby on rails or lift-web.

Re: It's an improvement but by Dean JJ

You are comparing orange to apple. Grails, Rails or Lift are full web application stack frameworks. To be fair, pound-for-pound, I think you should wait for Seam3 as a good candidate.



my 2 cents

S. Chalermthai

Re: It's an improvement but by Luis Espinal

The productivity level and code maintainability is still far from frameworks focused on developer comfort such as grails, jruby on rails or lift-web.


Uh, why do you compare what is basically a back-end for high-volume systems (what EJB 3.x is) vs a set of frameworks for web development? Forgive me for being blunt, but I don't think you understand the role of either type of technologies.

Nothing wrong with the technologies you mentioned (hell, I love Ruby), but... man. I know you wanted to use this opportunity to trumpet the value of grails, rails or lift-web, but c'mon... apples and oranges.

A more valid comparison would have been EJB 3.1 vs, say, Spring Framework.


As up to EJB 3.0, I was still doubting the value proposition of it vs Spring Framework, but with the introduction of no-interface views (pretty much nameless POJOs), that is pretty cool.

Re: It's an improvement but by Luis Espinal

The productivity level and code maintainability is still far from frameworks focused on developer comfort such as grails, jruby on rails or lift-web.


Also, you are wrong in saying these frameworks are focused on developer comfort. They are focus on simpler conventions for (in general) web development that by its nature, is subject to rapid changes, short, iterative life cycles and small/medium size agile teams.

Developer comfort is not the focus; it is simply a by-product.

Nice summary by Ashish Paliwal

Its a real nice roundup of the EJB 3.1 :-)

I am very curious to see the implementation of Singleton within the Container meaning how containers shall handle Singleton's. Its a big ease for developers, but a posses a huge challenge for Containers devs on optimization front in clustered environment.

Re: Great Article :) by Razib Shahriar

Thanks Charles! The links are very informative, but a usecase based coverage of CDI would be of great help, e.g. How would use the @ConversationScoped to manage conversations and persistence contexts? So far I have seen articles describing this scope, but not a working example that addresses things like detached objects?

Bravo! by Reza Rahman

Josh,

As usual, thoughtful and balanced technical coverage of EJB 3.1. Noting short of what I would expect from someone that I have so much respect for, of course.

While I definitely do believe EJB 3.1+CDI is very compelling, for Resin 4 we are taking things to the next logical step and allowing the use of all EJB annotations (and hence services) outside of EJBs into managed beans handled via CDI (we of course do still support the EJB 3.1 component model as is). I think this is really the natural step in evolution of EJB and Java EE going forward. We are hoping that developers give us positive feedback on this "experimental" model that we can then look to gaining broader consensus on via Java EE 7. There is definitely interest in such an evolution, which is one of the reasons EJBs were redefined to be managed beans with additional service contracts this time around (I see that you did not mention that in the article; it is a nuance easy to miss).

Cheers,
Reza
======================================
Resin EJB 3.1 Lite Container Developer
Expert Group Member, EJB 3.1 and Java EE 6
Author, EJB 3 in Action

Re: Great Article :) by Thomas Anderson

Do we still need ejb in 2010? It just refuses to die.

Re: Great Article :) by Reza Rahman

It just refuses to die.


Indeed. As a matter fact, from my perspective I see more adoption now than I have ever seen in my career and more people acknowledging the innovation that can be traced to the EJB spec - annotations in a major middleware technology being just one example. Albeit, this is largely thanks to Seam, much of which is standardized in CDI.

Cheers,
Reza

Re: Great Article :) by Francisco Jose Peredo Noguez

Certainly Seam contributed, but if were to look for the major influencers in the transformation from EJB2 to EJB3.x those would be Hibernate and Spring. They showed the world that the complexity of EJB2 was totally unnecessary... and then came EJB3, and then came Seam (and then, now comes EJB 3.1)

Re: It's an improvement but by Francisco Jose Peredo Noguez

Simple conventions help whom? The developer.
The customer always wants rapid changes, and grails, jruby on rails or lift-web make that possible by giving comfort to whom? The developers.

Re: It's an improvement but by Francisco Jose Peredo Noguez


A more valid comparison would have been EJB 3.1 vs, say, Spring Framework.


Actually, that is not correct, a valid comparison would be Weld vs Spring. EBJ 3.1 has not exact match because it is composed of very different technologies, you would have to compare each one of them.

Re: Great Article :) by Bill Burke

Certainly Seam contributed, but if were to look for the major influencers in the transformation from EJB2 to EJB3.x those would be Hibernate and Spring. They showed the world that the complexity of EJB2 was totally unnecessary... and then came EJB3, and then came Seam (and then, now comes EJB 3.1)


Exactly Francisco! Specifications should be a place where innovations are consolidated. This shows, IMO, that EE is working. It is pulling in the good ideas and adopting key innovations over time.

Re: Great Article :) by Reza Rahman

Francisco,

Certainly Seam contributed, but if were to look for the major influencers in the transformation from EJB2 to EJB3.x those would be Hibernate and Spring.


That depends of course on what one really views as a "major influencer". Hibernate and TopLink both have obviously influenced JPA. As to Spring, I think CDI is more of a parallel there than it has been for EJB 3.x (indeed I would argue that the other way round is true in terms of Spring's continued development of enterprise services based on AOP/DI as well as it's continuing adoption of annotations/convention-over-configuration). As an XDoclet user back in the "bad old" EJB 2.x days, I would say I see greater parallels with XDoclet than Spring for EJB 3.0.

All in all, I'm not sure who influenced what matters that much any more other than perhaps for historical interest, especially in the world of open source and standardization instead of proprietary solutions bound by chains of "intellectual property".

The point is that EJB 3.1 is here today and it is a compelling middleware solution, especially with CDI. And we will be doing more to make the Java EE component model ready for a next generation of developers hopefully with the help of the community.

Cheers,
Reza

Re: Great Article :) by Arbi Sookazian

Productivity is a concern and has been for many years since the inception of Java EE platform. When is this going to be addressed? Tools/frmwks in the Java space have too high learning curves (e.g. Maven, Seam, EJB 3.0, Weld, etc.)

Hot reloading of EJB components is now a reality with JRebel 3. This is great news. Why can't this be a JSR? Why can't a build system like Ant or Maven be a JSR?

Anyways, I wish the very best for Java EE 6 and its users...

Re: It's an improvement but by Luis Espinal

Simple conventions help whom? The developer.
The customer always wants rapid changes, and grails, jruby on rails or lift-web make that possible by giving comfort to whom? The developers.


Exactly. Cause -> Effect. Simple conventions that help rapid changes is the goal. Developer's comfort is just a by-product of it, not the goal as previously stated. Some might think that this is just playing semantics, but there is an important thinking process going on here on why things that are successful *for solving something* get implemented *and grow* in the first place.

Re: It's an improvement but by Luis Espinal


A more valid comparison would have been EJB 3.1 vs, say, Spring Framework.


Actually, that is not correct, a valid comparison would be Weld vs Spring. EBJ 3.1 has not exact match because it is composed of very different technologies, you would have to compare each one of them.


Yes, it does not have an exact match, but there is a particular usage for it, for building a specific class of applications. Spring might not be a vis-a-vis equal to EJB 3.x, but one of its successful usages has been the building of similar classes of applications.

That comparison, from a functional/usage perspective, does not hold when compared against web frameworks. The comparison I'm suggesting is not based on which has what, but on the commonality of the classes of applications built by both.

Re: Great Article :) by Reza Rahman

Arbi,

Productivity is a concern and has been for many years since the inception of Java EE platform.


I agree wholeheartedly. That's certainly something we've kept a keen eye on for both EJB 3.x and CDI. If you have specific areas of concern still, I would love to hear it and get it addressed in Resin 4 now and Java EE 7 later. As to dynamic class reloading, we've supported that in Resin for ages (as have a majority of other "sane" application servers). The Java module system (in the works via Java SE and then Java EE) will address this issue (among many others related to modularity).

Hope it helps,
Reza

Re: Great Article :) by Roman Pichlik

"The point is that EJB 3.1 is here today and it is a compelling middleware solution, especially with CDI."

Are the major application servers certified for EJB 3.1? I mean Weblogic and Oracle. How long it takes while these servers will be there? One year, two years from now? We have nothing in these days. I cannot imagine that i will start my next project based on top of EJB 3.1. Why i should care especially when i have Spring framework with all of this functionality at least three or four years ago. As you probably know every Java EE specification suffers more or less e.g. JPA, JSF. Is EJB 3.1 the special one? I guess no, maybe EJB 3.2 or EJB 3.3 that will fix all children's ailment of 3.1. I see EJB 3.1 as an attempt to get closer to Spring and actually it seems very promising, but what else? Nothing more, no inovation.

Re: Great Article :) by Reza Rahman

Roman,

As far as I can tell, WLS will be Java EE 6 certified by this year. I don't know about Oracle AS, I am also not sure about Geronimo/WebSphere CE. JBoss AS, Resin and GlassFish will be there far before that (GlassFish is already there). I agree if you are stuck with WebSphere "classic" you are our of luck, but could still use Weld/Seam 3 that's pretty close to the Java EE 6 model.

As to what innovation is in Java EE 6, that's for you to find out and do your own leg work on :-). I'd suggest staring with Servlet 3, CDI and EJB 3.1 and ending with the CDI portable extensions for Seam 3, CanDI and OpenWebBeans. As such, there are no practical technical issues with EJB 3.1, maybe just some political ones :-). If you see any, I'd sure like to hear about them :-).

Cheers,
Reza

Re: Great Article :) by Razib Shahriar

Agree with Reza. JavaEE 6 has a lot of innovations under the hood, it wont be long before the merits get surfaced into the wider development community as a compelling platform for enterprise development. I won't expect Weblogic/Websphere to take too long to get EE6 certified, as it might be a mistake considering the growing popularity of the platform. I work for a financial/payment processing institution which has myriad of different frameworks and platforms for delivering web applications, but with the release of JavaEE6, it just made sense us to unify everything under a scalable, standardized, robust and modern platform - which happens to be javaEE6.

Re: Great Article :) by adrian collheart

As far as I can tell, WLS will be Java EE 6 certified by this year. I don't know about Oracle AS, I am also not sure about Geronimo/WebSphere CE. JBoss AS, Resin and GlassFish will be there far before that (GlassFish is already there).


JBoss has in fact just released their 2nd Java EE 6 milestone the other week and it seems they're well on schedule to delivering the GA later this year.

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

24 Discuss

Educational Content

General Feedback
Bugs
Advertising
Editorial
InfoQ.com and all content copyright © 2006-2013 C4Media Inc. InfoQ.com hosted at Contegix, the best ISP we've ever worked with.
Privacy policy
BT