discussion - klevas.mif.vu.ltklevas.mif.vu.lt/~vaidasj/tp/medziaga/newfeaturesinejb31.pdf ·...

26
January 2008 Discussion This series of articles is a preview of the changes the EJB 3.1 expert group is working on for the next version of the Java EE specification. The idea is to give you a head's up on the changes as well as gather your feedback early so the expert group has the best chance of getting it right. EJB 3.0 brought simplicity to Java EE 5 by moving away from a heavyweight programming model. EJB 3.1 aims to build on those successes by moving further down the path of simplicity as well as adding a handful of much-needed features. In each article in this series, I will let you know about the progress made by the expert group over the next few months. In this first article, I'll cover the two features that have been discussed in detail so far--making interfaces optional for EJBs and Singleton Beans. I'll also give you a look-ahead into the possible features yet to be discussed. Remember, none of this has been finalized yet; all of this is really just a peek into the inner workings of the JCP so that you have a chance provide early feedback. EJB Interfaces are Optional The very first change the expert group covered was removing the last remaining obstacle to making EJBs look just like POJOs in their simplest form by making Session Bean business interfaces optional. Interface-based programming is clearly a useful technique in writing loosely-coupled, unit-testable applications. That is precisely why both EJB 2.1 and Spring promote the idea of component interfaces. In fact, at least one interface is required even for EJB 3.0 Session Beans (this is not a requirement for EJB 3.0 Message Driven Beans). The trouble is that component interfaces are just a needless abstraction in a lot of circumstances. I can't remember the times I silently cursed under my breath as I carried out the mechanical task of writing interfaces just because the framework needed it or the architect sitting in some ivory tower mandated it. A lot of times, just a regular Java object is really all you need for your foreseeable needs, especially if you don't really do much unit testing and loose-coupling is just not enough of a concern for the application. EJB 3.1 allows you to do just that. Now you do not need any interfaces for Session Beans, just like JPA Entities and Message Driven Beans. All you have to do is annotate a POJO with the @Stateless or @Stateful to get a fully functional EJB. Take a look at the example below modified from the Session Bean chapter in EJB 3 in Action: @Stateless public class PlaceBidBean { @PersistenceContext private EntityManager entityManager; public void placeBid (Bid bid) { entityManager.persist(bid); } }

Upload: doanthuy

Post on 15-Feb-2019

216 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Discussion - klevas.mif.vu.ltklevas.mif.vu.lt/~vaidasj/tp/medziaga/NewFeaturesInEJB31.pdf · private EntityManager entityManager; @WebMethod public void placeBid (Bid bid) {entityManager.persist(bid);}}

January 2008

Discussion

This series of articles is a preview of the changes the EJB 3.1 expert group is working on for the nextversion of the Java EE specification. The idea is to give you a head's up on the changes as well as gatheryour feedback early so the expert group has the best chance of getting it right. EJB 3.0 brought simplicityto Java EE 5 by moving away from a heavyweight programming model. EJB 3.1 aims to build on thosesuccesses by moving further down the path of simplicity as well as adding a handful of much-neededfeatures. In each article in this series, I will let you know about the progress made by the expert groupover the next few months.

In this first article, I'll cover the two features that have been discussed in detail so far--making interfacesoptional for EJBs and Singleton Beans. I'll also give you a look-ahead into the possible features yet to bediscussed. Remember, none of this has been finalized yet; all of this is really just a peek into the innerworkings of the JCP so that you have a chance provide early feedback.

EJB Interfaces are Optional

The very first change the expert group covered was removing the last remaining obstacle to making EJBslook just like POJOs in their simplest form by making Session Bean business interfaces optional.

Interface-based programming is clearly a useful technique in writing loosely-coupled, unit-testableapplications. That is precisely why both EJB 2.1 and Spring promote the idea of component interfaces. Infact, at least one interface is required even for EJB 3.0 Session Beans (this is not a requirement for EJB3.0 Message Driven Beans).

The trouble is that component interfaces are just a needless abstraction in a lot of circumstances. I can'tremember the times I silently cursed under my breath as I carried out the mechanical task of writinginterfaces just because the framework needed it or the architect sitting in some ivory tower mandated it. Alot of times, just a regular Java object is really all you need for your foreseeable needs, especially if youdon't really do much unit testing and loose-coupling is just not enough of a concern for the application.

EJB 3.1 allows you to do just that. Now you do not need any interfaces for Session Beans, just like JPAEntities and Message Driven Beans. All you have to do is annotate a POJO with the @Stateless or@Stateful to get a fully functional EJB. Take a look at the example below modified from the Session Beanchapter in EJB 3 in Action:

@Stateless public class PlaceBidBean {@PersistenceContext

private EntityManager entityManager;public void placeBid (Bid bid) {entityManager.persist(bid);}

}

Page 2: Discussion - klevas.mif.vu.ltklevas.mif.vu.lt/~vaidasj/tp/medziaga/NewFeaturesInEJB31.pdf · private EntityManager entityManager; @WebMethod public void placeBid (Bid bid) {entityManager.persist(bid);}}

To keep things interesting, let's add a few more features to this bargain-basement bean:

@Stateless @WebServicepublic class PlaceBidBean {

@PersistenceContext private EntityManager entityManager; @WebMethod public void placeBid (Bid bid) { entityManager.persist(bid); }}

In the above example, we are using JAX-WS 2.0 to expose the simple little placeBid method as a webservice. We're also using JPA to persist a Bid entity. PlaceBidBean has the full range of Stateless SessionBean functionality available behind-the-scenes including pooling, thread-safety, component life-cycle,interceptors, security and declarative transactions. For example, as you might have guessed if you arefamiliar with EJB 3.0, the placeBid method is wrapped in a container-managed JTA transaction bydefault. RMI-based remoting will also be supported for these beans, although the exact semantics hasn'tbeen solidified yet.

Besides making it easy to get going with simple bean classes, dropping the interface requirements alsomakes using EJB 3.1 beans in WebBeans easy. Gavin King is leading the WebBeans JSR (JSR 299),largely inspired by the lessons in JBoss Seam. WebBeans is expected to make JSF, JPA and EJB 3.1virtually seamless (no pun intended) and make Java EE 6 truly feel like a fully integrated stack.

The Singleton Beans are Here

EJB 3.1 Singleton Beans are the middleware equivalent of the GOF Singleton pattern. In the Java EEcontext, they are primarily used to store application-wide shared data.Think about all the times you needed to cache some data in memory so you didn't have to do the same olddatabase lookups over and over again from different parts of the application. Neither Stateless SessionBeans nor Stateful Session Beans meet this need. While Stateful Session Beans can maintain a sessioncache, it can't really be shared amongst the application tier components very easily.

There are various ways of solving this problem now. The simplest way is to use static fields or GOFSingleton pattern POJOs. More complex strategies that can work across an application cluster includeusing the Servlet container's application scope, JBoss Cache, OSCache, JCS and SwarmCache.Commercial solutions include Tangosol Coherence and Terracotta. While these solutions do work amajority of the time, they have a lot of weaknesses. Some are not thread-safe out of the box (static fields,Singleton POJOs), some are not transactional (Singleton POJOs, the Servlet application scope, OSCache,JCS, SwarmCache), none are remoteable and none have any security mechanisms. Other than the simplestsolutions, all of them require the use of non-standard, third-party code. Enter EJB 3.1 Singletons.

The container is guaranteed to maintain a single shared instance of an EJB 3.1 Singleton. This means thatSingletons can cache state across the application tier. Because it is an EJB, Singletons have all themiddleware services you might expect--declarative transaction management, security, remoting,concurrency management, dependency injection, component life-cycle callbacks, interceptors and so on.Like all other EJBs, Singletons are simply annotated POJOs. Here is a simple example:

@Singletonpublic class DiscountRateBean {

@PersistenceContextprivate EntityManager entityManager;private Rate rate;@PostConstructprivate void init() {rate = entityManager.find(Rate.class, 1);}@PreDestroyprivate void destroy() {

Page 3: Discussion - klevas.mif.vu.ltklevas.mif.vu.lt/~vaidasj/tp/medziaga/NewFeaturesInEJB31.pdf · private EntityManager entityManager; @WebMethod public void placeBid (Bid bid) {entityManager.persist(bid);}}

entityManager.merge(rate);}public void setRate(Rate rate) {this.rate = rate;}public Rate getRate() {return rate;}

}

The example is using JPA and bean life-cycle callbacks to load data on startup and save the data when thebean is destroyed (usually when the application is being shut-down). Any bean calling getRate and setRateis guaranteed access to the shared data stored in a single instance of DiscountRateBean. You'll notice aninteresting problem--any updates will be lost if the container does not get a chance to call the pre-destroycallback. We'll see how to minimize this problem using cron-like timers in a future article.

By default, all Singleton methods are made thread-safe and transactional. This means that allmultithreaded access to the bean is serialized and all methods are assumed to have a REQUIREDtransaction attribute (do you think that these are sensible defaults? If not, why?). You can changetransactional behavior using the @TransactionManagement and @TransactionAttribute annotations justlike you would do for a Stateful or Stateless Session Bean. If you've ever done this sort of thing for arelatively large scale application, you know having both the getRate and setRate methods serialized can bea serious performance bottleneck. In reality, you simply need a read-lock on the getRate method while aread-write lock should be placed on the setRate method. You can do this by using the@ConcurrencyAttribute like so:

@Singletonpublic class DiscountRateBean {

@PersistenceContextprivate EntityManager entityManager;private Rate rate;@PostConstructprivate void init() {rate = entityManager.find(Rate.class, 1);}@PreDestroyprivate void destroy() {entityManager.merge(rate);}@ConcurrencyAttribute(READ_WRITE_LOCK)public void setRate(Rate rate) {this.rate = rate;}@ConcurrencyAttribute(READ_LOCK)public Rate getRate() {return rate;}

}

For those who are familiar with Doug Lea's work, the READ_LOCK and READ_WRITE_LOCKterminology comes from java.util.concurrent. There are some application shared data that are justread-only. Any locking is really unnecessary in such cases. In such a case, you can create anunsynchronized Singleton like this:

@Singleton@ConcurrencyAttribute(NO_LOCK) // READ_LOCK would also work...public class DiscountRateBean {

@PersistenceContextprivate EntityManager entityManager;private Rate rate;@PostConstructprivate void init() {rate = entityManager.find(Rate.class, 1);}

Page 4: Discussion - klevas.mif.vu.ltklevas.mif.vu.lt/~vaidasj/tp/medziaga/NewFeaturesInEJB31.pdf · private EntityManager entityManager; @WebMethod public void placeBid (Bid bid) {entityManager.persist(bid);}}

public Rate getRate() {return rate;}

}

One alternative to @ConcurrencyAttribute(READ_LOCK),@ConcurrencyAttribute(READ_WRITE_LOCK) and @ConcurrencyAttribute(NO_LOCK) beingforwarded is @ConcurrencyReadLock, @ConcurrencyReadWriteLock and @ConcurrencyNoLock. Tokeep consistency with these low-level annotations, @TransactionAttribute would be broken up into@TransactionRequired, @RequiresNewTranscation, @TransactionNotSupported and so on. Some folkshave pointed out that this mode of thinking begins to get into "annotation bloat" and adds a new source ofcomplexity. This annotation granularity is also not consistent with Spring and C#.NET declarativetransactions. Supporters of this model point out that it is easier to type than@ConcurrencyAttribute(READ_WRITE_LOCK), etc. What do you think?

It may also be entirely possible that you want to manage Singleton concurrency yourself and want thecontainer to be uninvolved other than providing middleware services. This is supported through what isbeing called bean managed concurrency (a similar idea to bean managed transactions). Here is anexample:

@Singleton@ConcurrencyManagement(BEAN)public class DiscountRateBean {

@PersistenceContextprivate EntityManager entityManager;private Rate rate;@PostConstructprivate void init() {rate = entityManager.find(Rate.class, 1);}@PreDestroyprivate void destroy() {entityManager.merge(rate);}public synchronized void setRate(Rate rate) {this.rate = rate;}public synchronized Rate getRate() {return rate;}

}

Notice this time we are managing concurrency ourselves using the synchronized keyword. Since thecontainer will not interfere, you are free to use whatever concurrency management mechanism you like,including but not limited to using the full power of the java.util.concurrent package. For now, the newconcurrency management features are limited to EJB 3.1 Singletons, but they could be expanded to coverother bean types.

Singletons will also give you control over lazy/eager loading as well as explicit Singleton dependencymanagement to address load ordering. We won't discuss those features here although you are welcome tocomment on that too. Although the specification does not cover clustering support, it is very likely thatmost vendors will make Singletons cluster-safe (just like Stateful Session Beans).

More EJB 3.1 Features

The two features discussed here are just the tip of the iceberg. There are a number of other veryinteresting features listed on the JSR agenda. Here are some of the most interesting ones:

Support for direct use of EJBs in the servlet container, including simplified packaging options. Thecurrent thought is to allow EJBs in the WEB-INF/classes directory while allowing ejb-jar.xml to

1.

Page 5: Discussion - klevas.mif.vu.ltklevas.mif.vu.lt/~vaidasj/tp/medziaga/NewFeaturesInEJB31.pdf · private EntityManager entityManager; @WebMethod public void placeBid (Bid bid) {entityManager.persist(bid);}}

reside in the WEB-INF directory, just like the web.xml file. In a similar vein, you would be able toplace an EJB jar into the WEB-INF/lib directory.EJB Timer Service enhancements to support cron-like scheduling, deployment-time timer creation,and Stateful Session Bean timed objects.

2.

Support for stateful web services via Stateful Session Bean web service endpoints.3.

In addition to these, there are a handful of features that are currently not on the JSR agenda but could bereally great:

Further simplification of JMS, JavaMail and database injected resources. For example, you shouldbe able to inject MessageSenders, not just Queues and ConnectionFactory references. Gavin King isa major proponent of this enhancement.

1.

A Service Provider Interface (SPI) for EJB. This will make a number of innovative third-partyintegrations possible such as iBATIS, Spring, Acegi, Quartz or even Groovy Beans. Bill Burke,Mike Keith and I strongly support this feature.

2.

The ability to add EJB support to a lightweight servlet container like Tomcat. This would be similarto what is already available in the open source world in the form of Embedded JBoss, OpenEJB andEasyBeans. I haven't brought this feature up to the group yet, but will if you think it is good.

3.

The ability to use local transactions in addition to JTA in EJB. I think this would be very useful forsmaller web applications that really don't need JTA.

4.

A feature forwarded by Adam Bien, the standardization of JNDI mapping, is also particularly interestingas it will go a long way to enhancing portability across containers. What are your thoughts on this last list?Are the features useful? Should they be pushed harder? Are they more useful than what is on the currentagenda?

Your Help is Needed

As you might be able to see, the expert group is trying hard to add useful features to EJB 3.1. We can onlygo so far on our own though... we need your feedback to tell us if we are on the right track or if we shouldbe pursuing other paths. You can send your feedback directly to the JCP at [email protected] free to CC me at [email protected] so I am in the loop. In the coming months, I'll try topresent more features to you as we discuss them on the expert group. Until then, wish us good luck!

References

JSR 318: Enterprise JavaBeans 3.11.JSR 299: Web Beans2.JSR 316: Java EE 63.

PRINTER FRIENDLY VERSION

Page 6: Discussion - klevas.mif.vu.ltklevas.mif.vu.lt/~vaidasj/tp/medziaga/NewFeaturesInEJB31.pdf · private EntityManager entityManager; @WebMethod public void placeBid (Bid bid) {entityManager.persist(bid);}}

March 2008

Discussion

This series of articles is a preview of the changes the EJB 3.1 expert group is working on for the nextversion of the Java EE specification. The idea is to give you a head's up on the changes as well as gatheryour feedback early so the expert group has the best chance of getting it right. EJB 3.0 brought simplicityto Java EE 5 by moving away from a heavyweight programming model. EJB 3.1 aims to build on thosesuccesses by moving further down the path of simplicity as well as adding a handful of much-neededfeatures. In each article in this series, I will let you know about the progress made by the expert group.

In the first article of this series, I covered two of the earliest discussed features – optional interfaces forSession beans and Singleton beans. I also provided an overview of the rest of the features being discussed.In this second article, I'll cover two more features that have been discussed in detail—EJB Timer Serviceenhancements and simplified packaging. Remember, none of this has been finalized yet, although a draftof the specification will be released for review soon. All of this is really just a peek into the inner workingsof the JCP so that you have a chance provide feedback.

Thank You!

In the first article, I urged you to provide feedback directly to the JCP at [email protected] aswell as CCing me at [email protected]. Before going farther, I would like to thank everyone whotook the time to send in comments! I hope you will continue to send in your thoughts as I write morearticles in this series. I am also very grateful for all of the encouraging comments on the series itself.

It's Time for Timer Service Features

Scheduling is an important part of many applications for tasks such as report generation, databasemaintenance, generating OLAP summaries or data synchronization. If you have used the EJB TimerService in its current form, you know that it is useful, but pretty limited. The biggest limitations of thecurrent EJB Timer Service are that it is not all that flexible and scheduled jobs can only be createdprogrammatically, not declaratively. Some of these weaknesses were outlined by Richard Monson-Haefelin the EJB 2.x time-frame. This TheServerSide article outlines Richard's views:http://www.theserverside.com/tt/articles/article.tss?l=MonsonHaefel-Column4.

Let's take a super-quick look at the Timer Service as supported in EJB 3.0. Here is an example from EJB 3in Action:

@Statelesspublic class PlaceBidBean implements PlaceBid { @Resource TimerService timerService;

public void addBid(Bid bid) { ... Code to add the bid goes here... timerService.createTimer(15*60*1000, 15*60*1000, bid); }

Page 7: Discussion - klevas.mif.vu.ltklevas.mif.vu.lt/~vaidasj/tp/medziaga/NewFeaturesInEJB31.pdf · private EntityManager entityManager; @WebMethod public void placeBid (Bid bid) {entityManager.persist(bid);}}

@Timeout public void monitorBid(Timer timer) { Bid bid = (Bid) timer.getInfo(); ... Code to monitor the bid goes here... }}

The Stateless Session bean above creates a timer that is triggered every fifteen minutes, starting with afifteen minute delay when a bid is created in the addBid method. Every time the trigger fires, themonitorBid method annotated with the @Timeout annotation is invoked to see if the bidder was outbid.

While this functionality is fine for what PlaceBidBean does, imagine a slightly different scenario–abeginning-of-the-month newsletter mailing for all ActionBazaar customers. Implementing this in terms ofmillisecond intervals through the current programmatic TimerService interface would be a hazard at best.You'll also have to write some pretty awkward code so that the timer is created when the application startsup. There are several existing mechanisms in place today to achieve this kind of flexible declarativeschedules in Java EE. You can use a popular Open Source scheduler like Quartz, you can use acommercial tool like Flux or you can use scheduling services specific to your application server such asthe ones available for WebLogic or Sybase EAServer. The problem with these solutions is that they tendto be pretty cumbersome if all you really need is a declarative equivalent of UNIX cron in Java EE. Allthese solutions are also vendor-specific. Enter the Timer Service enhancements in EJB 3.1.

The most important one in this set of enhancements is the ability to declaratively create cron-likeschedules to trigger EJB methods (there are more advanced features; feel free to check them out when thespec draft comes out). For example, all you would have to do is annotate an EJB method with the@Schedule annotation to implement the beginning-of-the-month ActionBazaar newsletter like so:

@Statelesspublic class NewsLetterGeneratorBean implements NewsLetterGenerator {

@Schedule(second="0", minute="0", hour="0", dayOfMonth="1", month="*", year="*") public void generateMonthlyNewsLetter() { ... Code to generate the monthly news letter goes here... }}

The following table describes the attributes of the @Schedule annotation as well as default values:

Attribute Allowable Values Default

Second [0,59] 0

Minute [0,59] 0

Hour [0,23] 0

dayOfMonth [1,31] *

Month [1,12] or {"Jan", "Feb", "Mar", "Apr", "May", "Jun","Jul", "Aug", "Sep",

"Oct", "Nov", Dec"}

*

dayOfWeek [0,7] or {"Sun", "Mon", "Tue",

"Wed", "Thu", "Fri", "Sat"}

*

Year A four-digit calendar year *

Note any of the attributes support the cron-style "*" wildcard to represent all values, a comma separated

Page 8: Discussion - klevas.mif.vu.ltklevas.mif.vu.lt/~vaidasj/tp/medziaga/NewFeaturesInEJB31.pdf · private EntityManager entityManager; @WebMethod public void placeBid (Bid bid) {entityManager.persist(bid);}}

list (such as "Jan, Feb, Mar" for the month attribute) or a dash-separated range (such as "Mon-Fri" for theday of week attribute). Should the expression syntax support the "/" operator as well? How aboutsupporting fully expanded abbreviations such as "January" instead of "Jan"? Also, should a compact, fullcron-expression format be supported as well? Our little example could be expressed as:

@Schedule(expression="0 0 0 1 * * *")

Some folks argue that this "pure cron style expression" is way too cryptic, while others point out that a lotof developers are so used to it that it should be supported in EJB. New methods were added to theTimerService interface to support the programmatic version of cron-like scheduling. The programmaticversion supports defining the activation and deactivation dates for a given schedule. For example, ournewsletter could become active at a predetermined time in the future instead of being active as soon as thetimer is created. Should similar support be added to the @Schedule annotation? How about supportingdefining a finite number of occurrences a cron-based trigger will fire? Can you think of any otherfeatures?

Stripped Down EJB Packaging

Making XML deployment descriptors optional in EJB 3.0 has significantly simplified packaging anddeployment of Java EE applications. However, Java EE packaging is still clearly oriented towards strictmodularization. Namely, you must create separate jar files for web and EJB modules. In a typical Java EEdeployment scenario, an EAR file will contain a war archive and a separate EJB jar. Figure 1 depicts thecurrent Java EE packaging scheme. Roughly, the idea is that the EJB jar represents "modularized"business services that are consumed by the "client" web module. While modularization is very important,the problem is that it is overkill for simple web applications where business services are unlikely to beshared across clients in multiple other Java EE modules.

Figure 1: Current Java EE packaging.

Simplified EJB packaging for web applications is aimed at addressing this issue. In the new scheme, thereis no need to create a separate EJB jar module. Rather, EJBs (especially in the form of annotated POJOs)can be directly dropped into the WEB-INF/classes directory and deployed as part of the WAR. In asimilar vein, the ejb-jar.xml deployment descriptor, if you happen to be using one, can be placed into theWEB-INF directory along with the web.xml file. It may also be possible to place an EJB jar into theWEB-INF/lib directory (do you think this is important?). The new packaging scheme is depicted in Figure

Page 9: Discussion - klevas.mif.vu.ltklevas.mif.vu.lt/~vaidasj/tp/medziaga/NewFeaturesInEJB31.pdf · private EntityManager entityManager; @WebMethod public void placeBid (Bid bid) {entityManager.persist(bid);}}

2.

Figure 2: Simplified EJB packaging for web applications.

For me, a very interesting implication of this is that the simplified packaging scheme makes EJBs muchmore agnostic of the rigidly defined structure of Java EE EAR files. There is another really niceside-effect for those of us that still live in the land of occasional XML configuration and JNDI look-upsinstead of 100% annotations and DI. All EJB references, resource references or environment entriesdefined anywhere in the WAR can now be shared. This is because the entire WAR file has only one localcomponent environment (bound to the JNDI java:comp/env namespace). Let's say you define a datasource reference in the web.xml file like so:

<resource-ref> <description>My data source</description> <res-ref-name>jdbc/mydb</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth></resource-ref>

You can now do a lookup like the following not only in web container components like Servlets but alsoinside EJBs packaged inside the WAR:

// Looking up my data source.DataSource ds = (DataSource) envCtx.lookup("java:comp/env/jdbc/mydb");

What are your thoughts on this? There is one more reason I really like the simplified packagingenhancement—it goes hand-in-hand with EJB Lite. EJB Lite is a very minimal sub-set of EJB featuresdesigned for use in stripped-down applications. I'll talk more about EJB Lite in a later article in the series.One interesting possibility is that many vendors will likely start implementing EJB Lite on top of Servletcontainers like Tomcat or Jetty, with EJBs directly deployable to WAR files, completely by-passing JavaEE EARs. I see JBoss AS Express, GlassFish Express or Tomcat+OpenEJB as possibilities that aredifficult to ignore, especially given Java EE 6 Profiles. What do you think of these possibilities?

More to Come

Believe it or not, the features discussed in the first and second parts of this series are still just the tip of theiceberg. Here are some of the more interesting ones I'll cover in this series:

EJB support in minimal containers in the form of EJB Lite. This would be similar to what is alreadyavailable in the Open Source world in the form of Embedded JBoss, OpenEJB and EasyBeansplugging in on top of Tomcat.

1.

Support for asynchronous Session Bean invocation.2.Support for stateful web services via Stateful Session Bean web service endpoints.3.The standardization of JNDI mapping instead of keeping it for vendors to decide is beingpreliminarily discussed.

4.

Something else I am intending to discuss in the series is using EJB through Web Beans. As you might

Page 10: Discussion - klevas.mif.vu.ltklevas.mif.vu.lt/~vaidasj/tp/medziaga/NewFeaturesInEJB31.pdf · private EntityManager entityManager; @WebMethod public void placeBid (Bid bid) {entityManager.persist(bid);}}

already know, Web Beans is a very powerful integration framework that makes it possible to use somevery interesting DI features with EJB, an area Java EE has been criticized by a number of folks. The WebBeans specification is being led by Gavin King and incorporates ideas from JBoss Seam and Google Guice("Crazy" Bob Lee of Guice fame is working on WebBeans too). Until then, wish the expert group luckand keep the feedback rolling!

References

JSR 318: Enterprise JavaBeans 3.1, http://jcp.org/en/jsr/detail?id=318.1.JSR 299: Web Beans, http://jcp.org/en/jsr/detail?id=299.2.

As per Linux conventions, either 0 or 7 can be used to represent Sunday.

PRINTER FRIENDLY VERSION

Page 11: Discussion - klevas.mif.vu.ltklevas.mif.vu.lt/~vaidasj/tp/medziaga/NewFeaturesInEJB31.pdf · private EntityManager entityManager; @WebMethod public void placeBid (Bid bid) {entityManager.persist(bid);}}

April 2008

Discussion

This series of articles is a preview of the changes the EJB 3.1 expert group is working on for the nextversion of the Java EE specification. The idea is to give you a head's up on the changes as well as gatheryour feedback early so the expert group has the best chance of getting it right. EJB 3.0 brought simplicityto Java EE 5 by moving away from a heavyweight programming model. EJB 3.1 aims to build on thosesuccesses by moving further down the path of simplicity as well as adding a handful of much-neededfeatures. In each article in this series, I will let you know about the progress made by the expert group.

In the first two articles of this series, I covered a few of the earliest discussed features - optional interfacesfor Session beans, Singleton beans, EJB Timer Service enhancements and simplified packaging. In thisthird article, I'll cover two more features that have been discussed in detail--asynchronous Session Beaninvocation and EJB Lite. Remember, none of this has been finalized yet. All of this is really just a peekinto the inner workings of the JCP so that you have a chance to provide feedback.

The Early Draft is Out

An early draft of the spec has been released a few weeks ago. You can take a look at the draft yourself athttp://jcp.org/aboutJava/communityprocess/edr/jsr318/index.html. As you might already know, the draftcovers the entire spec and not just the new features. However, it's not too hard to skip over the parts thatare unchanged from EJB 3.0. Keep in mind that changes still being discussed are not yet reflected in thedraft. Please also keep in mind that the spec needs to be written for completeness and serves as a contractof sorts for vendor implementations, so it is often difficult if not impossible to focus on readability from adeveloper's perspective.

Do continue to send in your thoughtful comments on EJB 3.1 to [email protected]. Feel free toCC me at [email protected] too.

Asynchronous Invocation of Session Beans

Asynchronous processing is a surprisingly common requirement for many enterprise applications. Some ofthe most obvious use cases are triggering fire-and-forget background processes, handling long-runningtasks while keeping the user interface receptive or simply increasing application throughput by utilizingthe benefits of parallel processing. The easiest way of implementing asynchronous processing in Java EEapplications today is using Message Driven Beans. In fact, the first Message Driven Bean example in EJB3 in Action is used to implement asynchronous order billing. More precisely, a Message Driven Bean (OrderBillingMDB) asynchronously bills the customer after the order is confirmed and updates the orderinformation with the results of the billing attempt once it is completed. Figure 1 shows this scenario:

Page 12: Discussion - klevas.mif.vu.ltklevas.mif.vu.lt/~vaidasj/tp/medziaga/NewFeaturesInEJB31.pdf · private EntityManager entityManager; @WebMethod public void placeBid (Bid bid) {entityManager.persist(bid);}}

Figure 1: Asynchronous order billing

While using Message Driven Beans for asynchronous processing certainly works, it also forces you to dealwith messaging and JMS, even for relatively lightweight functionality. This is precisely the problemasynchronous session bean invocation is designed to solve. With this enhancement, you can doasynchronous processing simply by annotating a session bean method with the @Asynchronousannotation. Let's take a look at the re-factored EJB 3 in Action example for asynchronous billing using thefeature:

@Statelesspublic class OrderBillingServiceBean implements OrderBillingService { ...

@Asynchronous public void billOrder(Order order) { try { // Attempt to charge the order. bill(order); // Send email notification of billing success. notifyBillingSuccess(order); order.setStatus(OrderStatus.COMPLETE); } catch (BillingException be) { // Send email notification of billing failure. notifyBillingFailure(be, order); order.setStatus(OrderStatus.BILLING_FAILED); } finally { update(order); } }

...}

Because of the @Asynchronous annotation, when the client invokes the OrderBillingService.billOrdermethod, the call will return immediately instead of blocking until the billOrder method finishes executing.The EJB container will make sure the method gets executed asynchronously (probably using messagingunder the hood). As you can see, the return type of the asynchronous method is void. This will probablybe the case for a vast majority of asynchronous Session bean methods. However, EJB 3.1 can also supporta return type of java.util.concurrent.Future<V>, where V represents the resultant value of anasynchronous invocation. In case you are unfamiliar with it, the Future<V> interface allows you to dothings like cancelling an asynchronous invocation, checking if an invocation is complete, check forexceptions and getting the results of an asynchronous invocation. Check out the documentation for theFuture<V> interface here: http://java.sun.com/javase/6/docs/api/java/util/concurrent/Future.html. Let'stake a quick look at an example using the Future<V> return type. In the billOrder method in the previousexample, we set the status of the order according to the outcome of the billing attempt and updated theorder. Let's assume that the invoker updates the order themselves and wants to know what the status ofthe billing attempt was. We could do this by refactoring the billOrder method as follows:

@Statelesspublic class OrderBillingServiceBean implements OrderBillingService { ...

@Asynchronous public Future<OrderStatus> billOrder(Order order) {

Page 13: Discussion - klevas.mif.vu.ltklevas.mif.vu.lt/~vaidasj/tp/medziaga/NewFeaturesInEJB31.pdf · private EntityManager entityManager; @WebMethod public void placeBid (Bid bid) {entityManager.persist(bid);}}

try { // Attempt to charge the order. bill(order); // Send email notification of billing success. notifyBillingSuccess(order); return new AsyncResult<OrderStatus>(OrderStatus.COMPLETE); } catch (BillingException be) { // Send email notification of billing failure. notifyBillingFailure(be, order); return new AsyncResult<OrderStatus> (OrderStatus.BILLING_FAILED); } }

...}

The javax.ejb.AsyncResult<V> object is a convenience implementation of the Future<V> interface. Ittakes the result of the asynchronous invocation as a constructor argument. There's nothing stopping youfrom using your own implementation of Future<V> however. Asynchronous invocation supports a fewother neat features like delivery guarantees and transacted send semantics. For details, check out the specdraft.

What do you think of the asynchronous Session bean invocation feature? I personally think it's pretty cool.Can you think of any other features that could be added?

EJB Lite is Here

One of the major complaints many people have had of EJB and Java EE in general is that it is a kitchensink solution that tries to be everything to everyone at the same time. Although it's important to appreciatethe fact that Java EE is a standard and must aim to be comprehensive, this criticism is justified. Java EE 6Profiles are a reflection of this fact. Roberto Chinnici, the co-spec lead for the Java EE 6 spec has bloggedabout Java EE 6 Profiles here: http://weblogs.java.net/blog/robc/archive/2008/02/profiles_in_the_1.html.In short, Profiles define subsets of Java EE suited to a particular purpose. For example, the minimal WebProfile is geared towards very simple web applications.

Focusing on EJB in particular, the typical web project is probably very unlikely to use remoting, the EJBTimer service or Message Driven beans. In fact, a vast majority of EJB applications probably simplyutilize injection, persistence management, stateless session beans and declarative transactions. EJB Lite isan attempt to follow this observation and pare down EJB features as much as possible. On one hand, thisallows for very simple, lightweight implementations. On the other hand, this means learning EJB Litecould consist of leaning just a small handful of annotations and almost no configuration. The nextgeneration of lightweight Java EE application servers will probably implement EJB Lite instead of theentire EJB 3.1 specification. For example, a very tantalizing possibility this opens up is creating animplementation of EJB Lite on top of Spring going a step further down the lines of the Pitchfork project.

The following is the current list of features proposed for EJB Lite:

Stateless, Stateful, and Singleton session beansOnly local EJB interfaces or no interfacesNo support for asynchronous invocation (should this be included?)InterceptorsDeclarative securityDeclarative and programmatic transactions

What are your thoughts on this list? Should it be pared down further? Should it be expanded? What do youthink is important for your application? For reference, here is a table comparing major EJB and EJB Litefeatures:

Page 14: Discussion - klevas.mif.vu.ltklevas.mif.vu.lt/~vaidasj/tp/medziaga/NewFeaturesInEJB31.pdf · private EntityManager entityManager; @WebMethod public void placeBid (Bid bid) {entityManager.persist(bid);}}

Feature EJB Lite EJBStateless beansStateful beansSingleton beansMessage driven beans No interfacesLocal interfacesRemote interfaces Web service interfaces Asynchronous invocation InterceptorsDeclarative securityDeclarative transactionsProgrammatic transactionsTimer service EJB 2.x support CORBA interoperability

Table 1: EJB and EJB Lite Feature Comparison

Features Still on the Table

In this series so far, I've covered Singleton beans, optional interfaces for Session beans, Timer servicefeatures, simplified EJB packaging, Session bean asynchronous invocation and EJB Lite. There are still anumber of features that are being discussed by the group and are in various stages of incompleteness:

Support for stateful web services via Stateful Session Bean web service endpoints.1.The standardization of JNDI mapping instead of keeping it for vendors to decide.2.Support for using EJB 3.1 in Java SE environments. This is primarily geared towards unit testing.3.

What are your thoughts on these features? If you think they are important, voice your opinion by emailingthe expert group. Are there any other features you would like to see? As the state of these featuresbecome clearer, I'll write about them in this series. As many folks have requested, I'll also cover EJB andWebBeans integration as well as some of the enhanced DI features offered by WebBeans. Until then,adios amigos!

References

New Features in EJB 3.1, http://www.theserverside.com/tt/articles/article.tss?l=NewFeaturesinEJB3-1.

1.

New Features in EJB 3.1 - Part 2, http://www.theserverside.com/tt/articles/article.tss?l=NewFeaturesEJB31.

2.

JSR 316: Java EE 6, http://jcp.org/en/jsr/detail?id=316.3.JSR 318: Enterprise JavaBeans 3.1, http://jcp.org/en/jsr/detail?id=318.4.JSR 299: Web Beans, http://jcp.org/en/jsr/detail?id=299.5.Spring Pitchfork Project, http://static.interface21.com/projects/pitchfork/files/m4/docs/reference/html_single/.

6.

PRINTER FRIENDLY VERSION

Page 15: Discussion - klevas.mif.vu.ltklevas.mif.vu.lt/~vaidasj/tp/medziaga/NewFeaturesInEJB31.pdf · private EntityManager entityManager; @WebMethod public void placeBid (Bid bid) {entityManager.persist(bid);}}
Page 16: Discussion - klevas.mif.vu.ltklevas.mif.vu.lt/~vaidasj/tp/medziaga/NewFeaturesInEJB31.pdf · private EntityManager entityManager; @WebMethod public void placeBid (Bid bid) {entityManager.persist(bid);}}

June 2008

Discussion

This series of articles is a preview of the changes the EJB 3.1 expert group is working on for the nextversion of the Java EE specification. The idea is to give you a head’s up on the changes as well as gatheryour feedback early so the expert group has the best chance of getting it right. EJB 3.0 brought simplicityto Java EE 5 by moving away from a heavyweight programming model. EJB 3.1 aims to build on thosesuccesses by moving further down the path of simplicity as well as adding a handful of much-neededfeatures. In each article in this series, I will let you know about the progress made by the expert group.

In the first three articles of this series, I covered optional interfaces for Session beans, Singleton beans,EJB Timer Service enhancements, simplified packaging, asynchronous Session bean invocation and EJBLite. By popular demand, in this article I will cover WebBeans/EJB 3.1 integration. Remember, none ofthis has been finalized yet. All of this is really just a peek into the inner workings of the JCP so that youhave a chance to provide feedback.

WebBeans and EJB: Together Forever

WebBeans is one of the most exciting JSRs being developed in the Java EE 6 timeframe. The basic valueproposition of WebBeans is actually pretty intuitive. If you have developed an application or two usingJSF and EJB 3.0, you may have noticed that the JSF backing bean layer is usually pretty thin. In fact, eventhough you can easily inject EJBs into backing beans using the @EJB annotation, it’s not too far off toclassify backing beans as glue-code. WebBeans eliminates this glue-code by allowing you to directly useEJBs as JSF backing beans. We’ll see how great this actually looks in a second.

In addition to effectively integrating the JSF and EJB programming models, WebBeans also adds anumber of very cool features including robust annotation-driven DI, further ease-of-use for using the JavaEE interceptor model as well as sensible component context management for web applications. This lastfeature I won’t talk about in great detail since it is requires more of a JSF focus than an EJB focus, but I’llcover the rest.

WebBeans is largely inspired by JBoss Seam as well as Google Guice. The JSR is being led by Gavin Kingand Bob Lee is part of the expert group. My guess is that the core Seam code is going to be the basis forthe major WebBeans pluggable implementation although it looks like many application servers likeCaucho Resin will provide their own implementation as well.

EJBs as JSF Backing Beans

Let’s see what WebBeans is all about by re-factoring an example from EJB 3 in Action. The firstsubstantial Session bean example in EJB 3 in Action is used for adding a bid. The session bean uses JPA tosave a Bid entity into the database. Here is how the session bean and the entity would look like in aWebBeans environment:

Page 17: Discussion - klevas.mif.vu.ltklevas.mif.vu.lt/~vaidasj/tp/medziaga/NewFeaturesInEJB31.pdf · private EntityManager entityManager; @WebMethod public void placeBid (Bid bid) {entityManager.persist(bid);}}

@Component@Stateless@Named("placeBid")public class PlaceBidBean {

@PersistenceContextprivate EntityManager entityManager;

@In private Bid bid;

public void addBid() { entityManager.persist(bid);}

}

@Component@Entity@Named("bid")public class Bid { private Long bidId; private String bidder; private String item; private Double bidPrice;

@Id @GeneratedValue public Long getBidId() { return bidId; }

public void setBidId(Long bidId) { this.bidId = bidId; }

public String getBidder() { return bidder; }

public void setBidder(String bidder) { this.bidder = bidder; }

public String getItem() { return item; }

public void setItem(String item) { this.item = item; }

public Double getBidPrice() { return bidPrice; }

public void setBidPrice(Double bidPrice) { this.bidPrice = bidPrice; }}

The @Component annotation on both the PlaceBidBean stateless session bean and the Bid JPA entityregisters these components with the WebBeans container. @Named annotation assigns names to thecomponents that the WebBeans container knows them by. These names are then used in JSF pages torefer to the components. The @In annotation on the bid instance variable injects a Bid entity into thesession bean. It’ll be clearer how this works when you look at the JSP code below that uses the WebBeanscomponents. Figure 1 depicts how the page actually looks like to the bidder adding the bid.

<html>

Page 18: Discussion - klevas.mif.vu.ltklevas.mif.vu.lt/~vaidasj/tp/medziaga/NewFeaturesInEJB31.pdf · private EntityManager entityManager; @WebMethod public void placeBid (Bid bid) {entityManager.persist(bid);}}

... <body> <f:view> ... <h:form> <table> <tr> <td>Bidder</td> <td><h:inputText value="#{bid.bidder}"/></td> </tr> <tr> <td>Item</td> <td><h:inputText value="#{bid.item}"/></td> </tr> <tr> <td>Bid Amount</td> <td><h:inputText value="#{bid.bidPrice}"/></td> </tr> </table> ... <h:commandButton type="submit" value="Add Bid" action="#{placeBid.addBid}"/> ... </h:form> ... </f:view> </body></html>

Figure 1: Add Bid Page

As you can see, the bidder, item and bid amount fields in the JSP are bound to the correspondingproperties of the Bid entity through EL. The names “bid" and “placeBid" in the EL match the values ofthe @Named annotation placed on the components. When WebBeans first encounters the bean namecorresponding to the Bid entity, it creates a new instance of the entity behind the scenes and places it inthe underlying page request context. Notice also that the PlaceBidBean.addBid method is bound as theaction listener for the button to add the bid. When the button is clicked and the underlying form issubmitted, WebBeans binds the values of the form fields to the Bid entity properties. It then injects thepopulated entity into the bid instance variable of the PlaceBidBean session bean because of the @Inannotation. Unlike the Bid entity, the EJB is looked up from JNDI and placed into the request context.When the addBid method is invoked to handle the button click, the EJB uses the JPA entity manager tosave the injected entity. Other than the request context, WebBeans also understands the application,session and very innovative “conversation" contexts. For details of these contexts, check out theWebBeans draft specification.

The appeal of the WebBeans programming model in the code above really cannot be understated.WebBeans unifies JSF, EJB and JPA in a way that makes Java EE really feel like one seamlesslyintegrated platform that just works out of the box and minimizes boilerplate code, much like what youmight be used to while working with frameworks like Ruby on Rails. What do you think? Do you thinkthis is compelling? Can you see any pitfalls to this model?

Page 19: Discussion - klevas.mif.vu.ltklevas.mif.vu.lt/~vaidasj/tp/medziaga/NewFeaturesInEJB31.pdf · private EntityManager entityManager; @WebMethod public void placeBid (Bid bid) {entityManager.persist(bid);}}

WebBeans Dependency Injection

A large majority of enterprise application components are either service components, DAOs or domainmodel components. While JPA is ideal for implementing domain model components, service and DAOcomponents are good candidates for EJB. This is because EJBs are transactional and thread-safe bydefault (a lot of people seem to have the misconception that EJBs are remote-enabled by default as well;this is not true). EJB is even more of an obvious component model if you might use declarative servicesfor security, remoting, web services, messaging, scheduling or asynchronous processing. These servicesare at our fingertips in the form of decorating an EJB with an annotation or two as needed.

However, there are some components in an application that simply don’t need declarative services, don’tneed to be transaction-aware and don’t need implicit thread-safety guarantees. Good examples of suchcomponents are utilities or helper components. Because EJB 3.0 did not support dependency injection fornon-managed components, it was not possible to use DI for such components without making them EJBs.WebBeans dependency injection solves these problems because the @Component annotation can beapplied to any POJO, not just EJBs and JPA entities. Just as the @In annotation was used to inject the Bidentity into the PlaceBidBean stateless session bean, WebBeans can also inject plain components intoEJBs.

Let’s take a look at a quick example. Let’s assume that the bid amount entered by the user is rounded upto two decimal places using a utility class before the bid is saved. This can be done as follows:

@Componentpublic class MathUtil { ... public static double round(double value, int decimalPlaces) { BigDecimal converter = new BigDecimal(Double.toString(value)); converter = converter.setScale(decimalPlaces, BigDecimal.ROUND_HALF_UP); return converter.doubleValue(); } ...}

@Component@Stateless@Named("placeBid")public class PlaceBidBean {

@PersistenceContextprivate EntityManager entityManager;

@In private Bid bid;

@In private MathUtil mathUtil;

public void addBid() { bid.setBidPrice(mathUtil.round(bid.getBidPrice(), 2));

entityManager.persist(bid);}

}

In this case, a new instance of MathUtil will be created and injected into the EJB as needed. Althoughplain WebBeans components cannot directly use EJB declarative services, they can use DI themselves, aswell as life-cycle callbacks ( @PostConstruct/ @PreDestroy) and interceptors.

The @In and @Component annotations are really just the tip of the ice-berg. WebBeans brings a wholehost of other DI features into Java EE, including Guice style producer methods and binding annotations.Note that all EJB types including message driven beans can use WebBeans features.

Page 20: Discussion - klevas.mif.vu.ltklevas.mif.vu.lt/~vaidasj/tp/medziaga/NewFeaturesInEJB31.pdf · private EntityManager entityManager; @WebMethod public void placeBid (Bid bid) {entityManager.persist(bid);}}

WebBeans Interceptor Enhancements

Another major WebBeans feature very relevant to EJB is a very cool extension to the existing interceptormodel. You can currently apply interceptors to EJBs using the @Interceptor and @Interceptorsannotations. While this structure is both pretty easy to understand and intuitive, it is not very flexible.WebBeans introduces a little more flexibility to interceptors without making things more complex byintroducing an annotation-based indirection. The easiest way to understanding this is though code. Let’sassume that we want to apply an auditing interceptor to the PlaceBidBean EJB. This is how we could doit:

@InterceptorBindingType@Target({TYPE, METHOD})@Retention(RUNTIME)public @interface Audited {}

@Audited @Interceptorpublic class AuditInterceptor {

@AroundInvoke public Object audit(InvocationContext context) throws Exception { System.out.println("Entering: " + context.getMethod().getName()); System.out.println(" with args: " + context.getParameters()); return context.proceed(); }}

@Component@Stateless@Named("placeBid")public class PlaceBidBean {

@PersistenceContextprivate EntityManager entityManager;

@In private Bid bid;

@Auditedpublic void addBid() { entityManager.persist(bid);}

}

The @InterceptorBindingType annotation on the @Audited annotation is used to declare the fact that it isto be bound to an interceptor. Unlike the EJB 3.0 interceptor model, WebBeans uses the @Interceptorannotation to bind one or more annotations to a given interceptor. So the @Audited and @Interceptorannotations placed on AuditInterceptor means that the @Audited annotation placed on a component ormethod binds it to the interceptor. As a result, when the placeBid method is invoked, the AuditInterceptoris triggered and the audit method executes.

In addition to adding a level of indirection and flexibility, I think this extension really improves codereadability. What do you think? Should this extension be adopted into the EJB specification itself or beapplied to Java EE as a whole?

Still in the Works

Activity on the expert groups had understandably slowed down a bit due to JavaOne. However, things arepicking back up strongly again. There are still a number of very interesting topics that are being activelydiscussed:

Page 21: Discussion - klevas.mif.vu.ltklevas.mif.vu.lt/~vaidasj/tp/medziaga/NewFeaturesInEJB31.pdf · private EntityManager entityManager; @WebMethod public void placeBid (Bid bid) {entityManager.persist(bid);}}

The standardization of JNDI mappings is being simultaneously discussed in the Java EE 6 and EJB3.1 expert groups. Looks like some very neat things will happen very soon in this area.

1.

Support for using EJB 3.1 in Java SE environments (e.g. unit tests) is still in the works. The fact thatEmbedded GlassFish has followed the OpenEJB, EasyBeans and Embedded JBoss path is a strongindication to me that this is solidly on track.

2.

A great extensibility mechanism proposal is being discussed in the Java EE 6 expert group. Lookslike this might eventually end up in the EJB expert group as well. If this goes through, it will be abreeze to add non-standard third party declarative, annotation-based services to Java EE.

3.

What are your thoughts on these features? If you think they are important, voice your opinion by emailingthe expert groups. The EJB 3.1 expert group email address is [email protected] while theWebBeans expert group email address is [email protected]. Feel free to copy me [email protected]. In the meanwhile, I’ll keep you informed as things settle down on the remainingfeatures in the next and possibly last article in this series.

References

New Features in EJB 3.1, http://www.theserverside.com/tt/articles/article.tss?l=NewFeaturesinEJB3-1.

1.

New Features in EJB 3.1 - Part 2, http://www.theserverside.com/tt/articles/article.tss?l=NewFeaturesEJB31.

2.

New Features in EJB 3.1 - Part 3, http://www.theserverside.com/tt/articles/article.tss?l=NewFeaturesEJB31-3.

3.

JSR 316: Java EE 6, http://jcp.org/en/jsr/detail?id=316.4.JSR 318: Enterprise JavaBeans 3.1, http://jcp.org/en/jsr/detail?id=318.5.JSR 299: Web Beans, http://jcp.org/en/jsr/detail?id=299.6.Seam, http://www.seamframework.org.7.Google Guice, http://code.google.com/p/google-guice/.8.

PRINTER FRIENDLY VERSION

Page 22: Discussion - klevas.mif.vu.ltklevas.mif.vu.lt/~vaidasj/tp/medziaga/NewFeaturesInEJB31.pdf · private EntityManager entityManager; @WebMethod public void placeBid (Bid bid) {entityManager.persist(bid);}}

October 2008

Discussion

This series of articles is a preview of the changes the EJB 3.1 expert group is working on for the nextversion of the Java EE specification. The idea is to give you a heads up on the changes as well as gatheryour feedback early so the expert group has the best chance of getting it right. EJB 3.0 brought simplicityto Java EE 5 by moving away from a heavyweight programming model. EJB 3.1 aims to build on thosesuccesses by moving further down the path of simplicity as well as adding a handful of much-neededfeatures.

In the first four articles of this series, I covered optional interfaces for Session Beans, Singleton Beans,EJB Timer Service enhancements, simplified packaging, asynchronous Session Bean invocation, EJB Liteand WebBeans/EJB 3.1 integration. In this last article of the series, I will talk about standardized globalJNDI names for Session Beans and EJB 3.1 Embeddable Containers for Java SE environments.Remember, none of this has been finalized yet. All of this is really just a peek into the inner workings ofthe JCP so that you have a chance to provide feedback.

Standardized Global JNDI Names

As you might already know, all Session Beans are automatically registered with a JNDI context. Whetherthrough dependency injection or lookup, clients get references to beans from the JNDI context. The nameunder which a bean is registered with the container’s JNDI context is commonly referred to as the “globalJNDI name”. Historically application server vendors have had a great deal of latitude in what JNDI namethey automatically assign to a Session Bean.

This means that any code that depends on vendor assigned JNDI names is not portable. This is not an issuewhile using EJB 3.0 style dependency injection because the container is responsible for resolving thedependency metadata in a @EJB annotation to a JNDI name. The problem is that it is not always possibleto use dependency injection. For example, you must use direct JNDI context look-up in non-managedobjects such as JSPs and simple unit tests (a very interesting case I ran across recently is getting referenceto a Session Bean from a JPA Entity).

Let’s take a quick look at code to clarify the problem. Here is a Session Bean example from EJB 3 inAction:

@Remotepublic interface PlaceBid { void addBid(Bid bid);}

@Stateless(name="PlaceBid")public class PlaceBidBean implements PlaceBid { @PersistenceContext private EntityManager entityManager;

public void addBid(Bid bid) {

Page 23: Discussion - klevas.mif.vu.ltklevas.mif.vu.lt/~vaidasj/tp/medziaga/NewFeaturesInEJB31.pdf · private EntityManager entityManager; @WebMethod public void placeBid (Bid bid) {entityManager.persist(bid);}}

entityManager.persist(bid); }}

Let’s assume that the global JNDI name that the container assigns the PlaceBidBean is“chapter2/PlaceBid/remote". The “chapter2” part could be the Java EE application name; the “PlaceBid”part could be derived from the name attribute of the @Stateless annotation; while the “remote” part coulddenote the @Remote interface implemented by PlaceBidBean. Here is a Servlet using the Session Bean:

public class PlaceBidServlet extends HttpServlet { @EJB(beanName="PlaceBid") private PlaceBid placeBid;

public void doGet( HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException { ... placeBid.addBid(bid); ... }}

The container automatically resolves the @EJB annotation to the PlaceBidBean JNDI name using thebeanName attribute that matches the @Stateless name attribute as well as the PlaceBid remote interfaceclass annotated by @EJB and implemented by PlaceBidBean. While this is perfectly portable code usingDI, the following simple unit test is not because it depends on the vendor-specific global JNDI name:

public class PlaceBidClient { public static void main(String[] args) throws Exception { Context context = new InitialContext();

PlaceBid placeBid = (PlaceBid) context.lookup("chapter2/PlaceBid/remote"); // Non-portable

placeBid.addBid(new Bid("rrahman", 10059, 200.50)); }}

All code written to a vendor-specific JNDI name like the above will break as soon as we move from oneapplication server to another. This can be very troublesome if you use one application server fordevelopment and another for production like many of the Java EE development shops that use traditionalcommercial vendors. To make matters worse, most vendor global JNDI naming schemes vary wildly,making writing some kind of lookup utility to handle portability difficult. To illustrate, Table 1 shows thenames that various application servers would assign to PlaceBidBean if it was packaged in an EJB-JARnamed “action-bazaar-ejb” inside a Java EE application EAR named “action-bazaar” (lets assume thename attribute is not set on the @Stateless annotation since that’s what usually happens—in these cases,the bean name is defaulted to the bean class name).

JBoss global JNDI name action-bazaar/PlaceBidBean/remote

GlassFish global JNDI name PlaceBid

WebSphere Community Edition global JNDIname

action-bazaar-ejb/PlaceBidBean/PlaceBid

Oracle Application Server (OC4J) global JNDIname

PlaceBidBean

Table 1: Vendor-specific global JNDI names

Standardized global JNDI names solve this portability issue by specifying exactly how a JNDI nameshould be assigned by the container. The current thought is to make Session Bean JNDI names as explicitas possible so that it is unique across the application server. It incorporates the application name, module

Page 24: Discussion - klevas.mif.vu.ltklevas.mif.vu.lt/~vaidasj/tp/medziaga/NewFeaturesInEJB31.pdf · private EntityManager entityManager; @WebMethod public void placeBid (Bid bid) {entityManager.persist(bid);}}

name, bean name and bean interface in the following pattern:

java:global[/<application-name>]/<module-name>/<bean-name>#<interface-name>

As you can see, the application name is optional in case the EJB is not deployed as part of an EAR but issimply deployed as an EJB-JAR or as part of a WAR. The module name, on the other hand, would bederived from the EJB-JAR or WAR. In this scheme, the standardized global name for PlaceBidBeanwould be java:global/action-bazaar/action-bazaar-ejb/PlaceBidBean#PlaceBid. Of course, you may havealready noticed that the interface name is not actually needed to guarantee uniqueness in this case sincePlaceBidBean just has one remote interface! Since this is a very common scenario, a short “alias” inaddition to the “full name” for the bean is registered with JNDI. If the EJB has just one interface or nointerfaces at all, the interface name is omitted in this standardized short alias. So a short alias that will beassigned to PlaceBidBean would be java:global/action-bazaar/action-bazaar-ejb/PlaceBidBean.

Do you think this shortened alias is useful? Are there pitfalls to this? How about the idea of standardizingthe global JNDI names in general? Can you think of additional uses of the idea behind having centralizedglobal JNDI names?

EJB 3 Embeddable Containers on Java SE

Most people immediately associate EJB with full-scale Java EE application servers like WebLogic orWebSphere. This assumption is not necessarily true. There are a number of open source embeddable EJB3 containers that can run in non-Java EE environments such as in unit tests. The list of such embeddablecontainers includes OpenEJB (the EJB 3 container for Apache Geronimo and WebSphere CommunityEdition), EasyBeans (extracted from the JOnAS application server) and Embedded JBoss. Even GlassFishhas added embedded container support recently.

This enhancement will essentially standardize embeddable EJB 3 containers that can run in any Java SEenvironment. The enhancement is primarily geared towards unit testing, but embeddable containers couldjust as easily be used for “offline” batch processing, utilizing EJB 3.1 services such as distributedtransactions, messaging, scheduling or asynchronous processing in desktop applications or adding EJB 3.1support to Servlet containers like Tomcat. Figure 1 depicts the high-level concept behind embeddable EJB3.1 containers (note, Java SE includes the JNDI and RMI APIs that EJB 3.1 depends on).

Figure 1: EJB 3.1 Embeddable Containers Concept

From the developer’s point of view, the embeddable container is very transparent. Here is how code usingan EJB 3.1 embeddable container might look like:

public class PlaceBidClient { public static void main(String[] args) throws Exception { EJBContainer container = EJBContainerFactory.createEJBContainer(); Context context = container.getContext();

PlaceBid placeBid = (PlaceBid) context.lookup("java:global/action-bazaar/PlaceBid");

Page 25: Discussion - klevas.mif.vu.ltklevas.mif.vu.lt/~vaidasj/tp/medziaga/NewFeaturesInEJB31.pdf · private EntityManager entityManager; @WebMethod public void placeBid (Bid bid) {entityManager.persist(bid);}}

placeBid.addBid(new Bid("rrahman", 10059, 200.50));

container.close(); }}

This code will start an embeddable EJB 3 container in the same JVM process as the command-lineapplication. The EJBContainer.getContext() method provides a handle to the JNDI context of theembeddable container. Note the EJBContainer.close() method call is not strictly necessary but it is a goodidea anyway. Currently, embeddable containers are only required to support EJB Lite, although mostembeddable containers will likely support all EJB features (the existing non-standard ones certainly do).

What do you think about the embeddable container support enhancement? Can you think of any otheruse-cases besides the mentioned here? One possible feature that is closely related to embeddablecontainers is support for injecting EJBs into non-managed unit test classes. However, this enhancementwill need to be specified at the Java EE 6 level and is difficult to achieve solely in the EJB 3.1 expertgroup. Do you think that would be valuable? It could make unit test code like the following possible:

@RunWith(EmbeddableEJB3Runner.class)public class PlaceBidTest { @EJB private PlaceBid placeBid;

@Test public void testAddBid() { placeBid.addBid(new Bid("rrahman", 10059, 200.50)); }}

Some Food for Thought

Casey Stengel said “Never make predictions, especially about the future.” As futile as attempts atpredicting the future are, they are useful as thought experiments—so here goes. There are a number ofthings that I think are on the horizon for EJB as a technology beyond the EJB 3.1/Java EE 6 time-frame.I’ll briefly mention some of them here as food for thought (in fact, folks have already asked me questionson some of these):

EJB 3 and Spring Integration: I believe there is tremendous potential for EJB 3 and Springintegration, just as there is tremendous potential for WebBeans/EJB 3 or Seam/EJB 3 integration.This is already possible with EJB 3.0 and Spring 2.5, particularly through EJB 3 embeddablecontainers. However, this type of integration can be taken to the next level by adding native EJB 3support on top of the Spring framework/application platform itself, along the lines of the Pitchforkproject initiated by BEA.

1.

JAX-RS Integration: As you might already know, JAX-RS is the new Java EE API forREST-based web services. Just as EJB has excellent support for JAX-WS (the SOAP counter-partof JAX-RS), I believe EJB should have excellent support for JAX-RS as well. Indeed, there is achance that this might happen in the EJB 3.1 time-frame since the JBoss JAX-RS implementation,RESTeasy, already supports this and the JAX-RS reference implementation, Jersey, is in the processof building such as integration point.

2.

OSGi Interoperability: OSGi interoperability is on the horizon for EJB and Java EE. As such, Ithink the interoperability points are relatively clear for Java EE, in terms of treating deployableartifacts as OSGi bundles. It looks like vendors such as Sun, IBM and JBoss will pave the waythrough their application servers before this is finalized through the standards.

3.

EJB 3 and RIA: Unlike many other server-side component development models, EJB is agnostic ofHTTP. This fact is perhaps most apparent with Stateful Session Beans as they are capable ofmanaging state on the server-side without any reliance on client HTTP sessions. It also has along-standing strength in supporting robust remoting, including support for transparent remotepropagation of client security and transaction contexts. These attributes make EJB a great choice

4.

Page 26: Discussion - klevas.mif.vu.ltklevas.mif.vu.lt/~vaidasj/tp/medziaga/NewFeaturesInEJB31.pdf · private EntityManager entityManager; @WebMethod public void placeBid (Bid bid) {entityManager.persist(bid);}}

for RIA applications that closely resemble pure client-server architectures. Such a technologycombination can be materialized very effectively though either robust EJB/RMI binding support onthe RIA client or extending EJB remoting capabilities to add a highly efficient binary protocolutilizing HTTP port tunneling that is specifically designed for RIA clients. I hope to see such ascenario supported by emerging RIA technologies like JavaFX.

What are your thoughts on the above? In particular, I’d love to hear some feedback on an initiative to addnative EJB 3.1 support in the Spring framework/application platform.

Your Help is Needed!

First of all, many thanks to all the folks that sent in comment and suggestions in response to this series. Itis truly encouraging and I hope you will continue to be actively engaged! You can send your feedbackdirectly to the expert group at [email protected]. Do feel free to copy me [email protected].

I also urge you to look at the EJB 3.1 public draft. Some parts of the specification can be a little dry sinceit is primarily geared towards folks implementing EJB 3.1. However, there is also a wealth of interestingmaterial there that you might not find elsewhere. There may also be some features that are added which Icould not cover in this series, since there are still a few months left until the specification is finalized.

Even after the specification is finalized, a great way to be heard is through feedback mechanisms likepublic issue trackers that many open source Java EE vendors support. As is often said in softwaredevelopment, the best ideas come from users!

Finally, wish all of us in the expert group good luck in producing a successful next version of the EJBspecification.

That’s all folks!

References

New Features in EJB 3.1, http://www.theserverside.com/tt/articles/article.tss?l=NewFeaturesinEJB3-1.

1.

New Features in EJB 3.1 - Part 2, http://www.theserverside.com/tt/articles/article.tss?l=NewFeaturesEJB31.

2.

New Features in EJB 3.1 - Part 3, http://www.theserverside.com/tt/articles/article.tss?l=NewFeaturesEJB31-3.

3.

New Features in EJB 3.1 – Part 4, http://www.theserverside.com/tt/articles/article.tss?l=NewFeaturesinEJB3-Part4.

4.

JSR 316: Java EE 6, http://jcp.org/en/jsr/detail?id=316.5.JSR 318: Enterprise JavaBeans 3.1, http://jcp.org/en/jsr/detail?id=318.6.EJB 3.1 Public Draft, http://jcp.org/aboutJava/communityprocess/pr/jsr318/index.html.7.OpenEJB, http://openejb.apache.org.8.EasyBeans, http://www.easybeans.net.9.Embedded JBoss, http://wiki.jboss.org/wiki/EmbeddedJBoss.10.Embedded GlassFish, https://embedded-glassfish.dev.java.net.11.Spring Pitchfork, http://www.springsource.com/pitchfork.12.JBoss RESTeasy EJB integration, http://wiki.jboss.org/wiki/RESTeasyEJBIntegration.13.

PRINTER FRIENDLY VERSION