Level: Intermediate Michael Galpin (mike.sr@gmail.com), Software Engineer, eBay
26 Jun 2007 The Java™ 2 Platform, Enterprise Edition (J2EE) specification made Java technology the
premier technology for enterprise application development. It has evolved over the
years to maintain that position, especially with the Java Platform, Enterprise Edition 5 (Java
EE 5) specification. OpenEJB has been an integral part of Geronimo since its
inception. Its 3.0 release is a key part of Geronimo's implementation of the Java EE
5 specification. In this installment, the renegade uncovers the driving forces
behind Enterprise JavaBeans (EJB) 3 and how OpenEJB has stepped up to provide bold new features to Geronimo.
History of EJB
The IBM® original EJB specification in 1997 is arguably one of the most important
developments in the world of Java technology. EJBs and the J2EE application
servers that contained them were rapidly adopted by the enterprise development
world. However, the criticisms of EJBs came just as quickly as the adoption of
J2EE. Chief among these criticisms was that EJBs were difficult to understand and
tedious to develop.
The EJB specification was designed to solve complex problems, such as distributed
computing, transaction management, and data persistence. Complex problems often
lead to complex solutions. The original EJB specifications reflect the complex
problems they were designed to solve. As a result, developers experienced a lot of
pain when working with EJBs. When you understood EJBs, you could use sophisticated
tools to make your development easier. There was still a significant learning
curve for EJB newcomers.
The EJB 1.0 and 1.1 specifications were developed and released by Sun
Microsystems. All subsequent new specifications have been created using Java
Specification Requests (JSRs) and approved using the Java Community Process (JCP).
The involvement of the community is the key to the evolution of Java technology.
The pain felt by EJB developers found a voice in the JCP. The result was the EJB
3.0 specification, finalized in May 2006.
EJBs were no longer just about solving complex problems, they were about solving
these problems through easy and straightforward development. The focus of EJB 3.0
is on making initial development easier and applications more maintainable. Here
you find out how much simpler a 3.0 EJB is compared to a 2.1 EJB. First,
let's take a look at OpenEJB, an EJB implementation and one of the foundations of
Geronimo.
OpenEJB -- EJB 1.1
OpenEJB has been around since 2000. It was founded by David Blevins and Richard
Monson-Haefel. Blevins was also one of the founders of Geronimo, as OpenEJB was a
natural choice for the EJB implementation in Geronimo. OpenEJB was one of the
first open source implementations of the EJB 1.1 specification. It provided an
implementation of remote session beans directly and used Castor for its
implementation of container-managed persistence (CMP) entity beans. From the very beginning, OpenEJB focused on
making the lives of developers simpler. For example, OpenEJB allowed for an
embedded container (and even an embedded database) to make it easy to write unit
tests for your EJBs. Most EJB implementations made it so hard to unit test EJBs
that complex frameworks were developed to tackle the problem (JUnitEE is the most
notable example). OpenEJB was a terrific implementation of EJB 1.1 -- it was fast
and user friendly. However, it had to do some evolution of its own to fit the
needs of Geronimo.
OpenEJB and Geronimo -- EJB 2.1
Geronimo was designed to be an open source implementation of the J2EE 1.4
specification. This specification included the EJB 2.1 specification. OpenEJB was
an EJB 1.1 implementation. There had been a lot of additions to the EJB spec
between 1.1 and 2.1. These included local interfaces for session beans and
message-driven beans (MDBs), a query language for entity bean finder methods, and support
for exposing session beans as Web services.
Luckily, the Geronimo team (which at that point included many of the OpenEJB contributors)
was a talented group working to implement all of the EJB 2.1 features to
OpenEJB and thus pave the way for Geronimo as a J2EE 1.4 implementation. Along
the way, OpenEJB picked up some of the abundant complexity of the EJB
specification. For example, the embeddable container so useful for unit testing
was collateral damage in the quest for EJB 2.1 compliance. Luckily for Java
developers everywhere, EJB 3 was on the horizon.
EJB 3.0
So what's so great about EJB 3.0? The easiest way to understand EJB 3.0 is to
compare it to EJB 2.1. Let's build a simple EJB using both. In the following
sections, you'll build a
simple stateless session bean that gives you the current time. First, here's how
to do it with EJB 2.1.
The Time EJB -- circa EJB 2.1
It's best to look at some of the complexities in EJBs that caused pain, both for
experienced developers and for developers trying to learn EJBs. Your hypothetical
EJB can be described with a simple interface shown in Listing 1.
Listing 1. Simple Time interface
package org.developerworks.time;
import java.util.Date;
public interface Time {
public Date currentTime();
}
|
Now make this into an EJB. You need to redefine your interface first, as
shown in Listing 2.
Listing 2. Time EJB interface
package org.developerworks.time;
import java.rmi.RemoteException;
import java.util.Date;
import javax.ejb.EJBObject;
public interface Time extends EJBObject{
public Date currentTime() throws RemoteException;
}
|
Pretty similar, but it's still disconcerting that you had to alter your interface
at all. Having to extend EJBObject doesn't seem so bad,
because
that's just a typical marker interface. The worst offense is that you have to
change the method signature to declare that it throws a
RemoteException. EJB 2.0 solved this problem by adding
an optional local interface, as seen in Listing 3.
Listing 3. Local interface for Time
package org.developerworks.time;
import java.util.Date;
import javax.ejb.EJBLocalObject;
public interface TimeLocal extends EJBLocalObject{
public Date currentTime();
}
|
OK, so no RemoteException now. Of course you've still
created two interfaces to describe the same service. You can't have the remote
interface extend the local one (which might seem logical), because its
currentTime method throws a
RemoteException and the local's does not, and so on.
The interface declaration seems obtrusive, but the intrusion is light compared to
what you'll see in the implementation.
You can imagine a simple implementation to your original interface, as shown in
Listing 4.
Listing 4. Implementation of the original interface
package org.developerworks.time;
import java.util.Date;
public class TimeBean implements Time {
public Date currentTime() {
return new Date();
}
public TimeBean() {
}
}
|
That's far too simple for EJB 2.1. Here's its version of the same thing in
Listing 5.
Listing 5. TimeBean EJB Implementation
package org.developerworks.time;
import java.rmi.RemoteException;
import java.util.Date;
import javax.ejb.EJBException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
public class TimeBean implements SessionBean {
public void ejbCreate() {
}
public Date currentTime() {
return new Date();
}
public void ejbActivate() throws EJBException, RemoteException {
}
public void ejbPassivate() throws EJBException, RemoteException {
}
public void ejbRemove() throws EJBException, RemoteException {
}
public void setSessionContext(SessionContext sessionContext) throws EJBException,
RemoteException {
}
public TimeBean() {
}
}
|
Where did all these ejbXYZ methods come from? They're
all mandated by the SessionBean interface. They are
lifecycle callback methods. They make a lot of sense in complex scenarios where a
lot of processing and bookkeeping is needed for the life cycle of complex session
beans. However, it's a classic case of programming to the corner case (or the
worst-case scenario).
With EJB 2.1, you're still not done. You need to create Home and LocalHome
interfaces. These are used by the container, yet must be supplied by the
developer. For example, Listing 6 shows a Home
interface.
Listing 6. Time Home interface
package org.developerworks.time;
import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.EJBHome;
public interface TimeHome extends EJBHome{
public static final String COMP_NAME="java:comp/env/ejb/Time";
public static final String JNDI_NAME="Time";
public Time create() throws CreateException,RemoteException;
}
|
The LocalHome interface is almost identical. It extends
EJBLocalHome instead of
EJBHome, and its Create method doesn't throw a
RemoteException.
As if all that wasn't bad enough, you still need to write a deployment
descriptor for your EJB. The deployment descriptor ties everything together and
provides further instruction to the container on how to manage the EJB. Listing 7
shows a possible deployment descriptor for your bean.
Listing 7. Deployment descriptor
<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar id="ejb-jar_1" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/
j2ee/ejb-jar_2_1.xsd" version="2.1">
<display-name>Time</display-name>
<enterprise-beans>
<!-- Session Beans -->
<session id="Session_Time">
<display-name>Time</display-name>
<ejb-name>Time</ejb-name>
<home>org.developerworks.time.TimeHome</home>
<remote>org.developerworks.time.Time</remote>
<local-home>org.developerworks.time.TimeLocalHome</local-home>
<local>org.developerworks.time.TimeLocal</local>
<ejb-class>org.developerworks.time.TimeSession</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
</session>
</ejb-jar>
|
Hopefully you now have a good understanding of the pain induced by EJBs. How does
EJB 3.0
address all of this? Take a look.
The Time EJB
-- circa EJB 3.0
Let's rewrite the Time EJB using EJB 3.0. You start
with an interface describing the service just as you did before. Only this time
there's not as much to do to the interface to make it an EJB
interface. Take a look at Listing 8.
Listing 8. TimeBean interface
package org.developerworks.time;
import java.util.Date;
import javax.ejb.Remote;
@Remote
public interface Time {
public Date currentTime();
}
|
Notice how much this looks like Listing 1. All you've added
is an annotation declaring this to be a remote interface. You didn't have to
extend an interface or throw a RemoteException. The EJB
3.0 specification allows you to omit the annotation altogether as long as your
implementation class is properly annotated and only implements one interface. It's
still good practice to put the annotation in there; it makes the code more
maintainable. Now you can move on to the implementation, which is shown in Listing 9.
Listing 9. TimeBean EJB implementation
package org.developerworks.time;
import java.util.Date;
import javax.ejb.Stateless;
@Stateless
public class TimeBean implements Time{
public Date currentTime(){
return new Date();
}
}
|
EJBs like these are often referred to as plain old Java objects (POJOs).
That's because the only evidence that this is an EJB is the
@Stateless annotation. There are no more callbacks to
implement as part of an interface. If you need to implement one of those
callbacks, you can simply add a method and annotate it to declare that it's a
callback. You can call the method anything you want, because you aren't implementing
an interface.
Now for the deployment descriptor. Oh wait, there's not one! If you
didn't understand the importance of EJB 3.0 (and thus Java EE 5), hopefully it's
clear now. It's a quantum leap forward in terms of ease of development. Of
course, it's just a spec. You need an implementation to make use of these great
ideas. That's where Geronimo 2.0 and OpenEJB 3.0 come in.
Geronimo 2 -- Java EE 5
You've only scratched the surface, but you can probably tell that Java EE 5 is a
huge departure from J2EE 1.4. It shares many of the same concepts. The
application server provides all the same services it used to, such as distributed
computing, transaction management, and persistence. However, the APIs for these
services are fundamentally different. EJBs are much simpler to develop, but that
implies that Java EE 5 application servers have to provide more functionality than
ever before. Thus, the Geronimo developers had a lot on their plates when it came
time to implement the Java EE 5 specification. This was especially true for
OpenEJB, because once again it was counted on to be a foundation for Geronimo, and
it
implements this bold new EJB 3.0 specification.
As of this writing, Apache Geronimo has passed Java EE 5.0 TCK.
Developers get to have their cake and eat it too -- they get the pleasure of
using the new EJB 3 API and deploy their cleaner, simpler code on Geronimo.
Incubator status
One other interesting thing to note is that the OpenEJB project is now an Apache
Incubator project. The Apache Geronimo team contributed a lot to OpenEJB's EJB 2.1
implementation, because it was key to Geronimo's J2EE 1.4 implementation. However,
OpenEJB wasn't quite ready to join Apache yet. It was mostly just a matter of
paperwork, and now OpenEJB is part of the Incubator. The EJB 3.0 implementation is
being done as an Apache project, and its successful completion will go a long ways
toward helping OpenEJB graduate to a top-level Apache project.
Summary
This article covered a lot about the evolution of the J2EE and EJB specifications over
the years. You've seen how powerful the specification is but also how
this leads to a complicated programming model that causes a lot of frustration and
confusion for Java developers. You've got a taste of how the Java EE 5 and EJB 3.0
specifications are designed to address these pain points and greatly increase the
productivity of Java developers
everywhere. It's a much simpler programming model that not
only increases immediate productivity but should also lead to an application that
is significantly easier to maintain over time.
The first release of Geronimo implemented the J2EE 1.4 specification. OpenEJB
provided the EJB 2.1 implementation as part of this. Now Geronimo is implementing
the Java EE 5 specification, and it's up to OpenEJB to implement the EJB 3.0
specification. A lot of progress has already been made; I encourage you to
download the latest milestone release of Geronimo and start enjoying the benefits
of Java EE 5 and EJB 3.0. Next time you take a POJO and slap on an annotation to
turn it into an EJB, you can give a little thanks to the OpenEJB team.
Resources Learn
- Read
Sun's official Java EE 5 tutorial
to learn many of the benefits of EJB 3.
- Learn about OpenEJB's role within Geronimo
in
"The Geronimo Renegade: OpenEJB and Apache Geronimo's EJB Implementation"
(developerWorks, May 2006).
- Learn about using Geronimo to create EJB-driven
Web applications in
"Dive into EJB Web application with Geronimo"
(developerWorks, July 2005).
- Learn about deploying EJB projects and the role
of OpenEJB-specific deployment descriptors in
"Deploy J2EE applications on Apache Geronimo"
(developerWorks, January 2006).
- Explore session beans like the ones described
in the tutorial
"The Apache Geronimo machine shop sampler, Part 4: EJBs: Session beans and message-driven beans"
(developerWorks, April 2006).
- Read the latest Geronimo documentation and the
latest news about its Java EE 5 status on the
Geronimo wiki.
- Get the latest OpenEJB news, documentation, and
EJB 3 examples from the
OpenEJB site.
- Get involved in the
Geronimo project.
- Tom McQueeney's site,
Geronimo Live, is
packed with information and resources on Geronimo.
- Read Applying the Apache License, Version
2.0 for guidance, both
inside and outside the Apache projects, about
applying the Apache License, Version 2.0.
- Check out the developerWorks Apache Geronimo project area for articles, tutorials, and other resources to help you get started developing with Geronimo today.
- Find helpful resources for beginners and experienced users at the Get started now with Apache Geronimo section of developerWorks.
- Check out the IBM Support for Apache Geronimo offering, which lets you develop Geronimo applications backed by world-class IBM support.
- Visit the developerWorks Open source zone for extensive how-to information, tools, and project updates to help you develop with open source technologies and use them with IBM's products.
- Stay current with developerWorks technical events and webcasts.
- Browse all the Apache articles and free Apache tutorials available in the developerWorks Open source zone.
- Browse for books on these and other technical topics at the Safari bookstore.
- Get an RSS feed for this series. (Find out more about RSS.)
Get products and technologies
Discuss
About the author  | |  | Michael Galpin has been developing Web applications
professionally since 1998. He is a software engineer at eBay in San
Jose, CA. He holds a degree in mathematics from the California Institute
of Technology. |
Rate this page
|