I'm going to be brutally honest. EJBs are not easy to use, in my opinion. They require a great deal more thought than many developers put into their applications; they're based on interfaces that force you to implement a lot of functionality you may not even need; and because you need to run them in a container, it can be tricky to test them along with the rest of your application using, say, JUnit.
And yet, they may very well be the cornerstone of J2EE development.
So when The Powers That Be asked me to do this installment of The Geronimo renegade on the choice of OpenEJB as the EJB implementation for Apache Geronimo, I was intrigued. Maybe I could finally figure out what the big deal was.
I got on the phone with David Blevins who, with Richard Monson-Haefel, cofounded OpenEJB six years ago and who was also in on the founding of Geronimo. I wanted to know what OpenEJB provides for Geronimo and what EJB itself provides for developers.
I started by asking him about the process by which something like OpenEJB winds up in a larger project like Geronimo. David explained that he had been in on the Geronimo project back when it was just a rumor, before it was officially launched. "So I was definitely part of the conspiracy that is Geronimo," he joked.
Ah, the conspiracy again. I asked him why he thought it was so often referred to that way. "Oh, it makes really good FUD" -- Fear, Uncertainty, and Doubt -- "for other people to label us that way." He explained that initially the goal of Geronimo's founders was to focus on bringing together the right people and to worry about the right components later. "Everybody who is involved in the founding of Geronimo had to basically put their ego and their code aside and decide to put themselves into the project first," David told me. Essentially, they were trying to create a project starting with a clean slate.
So how did OpenEJB get to be part of that slate? "Well, I guess it's all who you know," David said. But he's not entirely serious. True, it was Dain Sundstrom, one of the original Geronimo founders, who invited him to be part of the project from the beginning. Dain had actually been trying to recruit David for a similar open source project about a year earlier: "For a while he was attending every social gathering of the Twin Cities Java Users Group (TCJUG) and pestering me about it continuously."
When they did get together it must have seemed almost like fate. Although both of them are from Minnesota, at the time the Geronimo project was being formed David was teaching in San Francisco. "I said, 'Well, I'm in San Francisco right now, so you'll have to wait until I get back to Minnesota.' And of course he said, 'Well, I'm in San Francisco as well,' having just returned from a conference. So we got together that day right there in San Francisco to talk, and he was expecting to keep getting the continuous no's that I'd been giving him. But when the pitch went from working on this other project to an Apache J2EE implementation, the answer was immediately yes."
And, being OpenEJB's leader (since Monson-Haefel's departure several years early), David rallied that community around the Geronimo effort. "We just knew it was the right thing to do," he said.
More than that, the two groups, OpenEJB and Geronimo, found a synergy rarely seen in large-scale projects. OpenEJB's Alan Cabrera wrote Geronimo's security system, and Aaron Mulder, the author of a freely downloadable book about Geronimo, significantly overhauled the console donated by IBM®. Geronimo's Dain Sundstrom and David Jencks did enormous amounts of work on OpenEJB to bring it up to EJB 2.1 compliance. (Open EJB was originally only EJB 1.1 compliant.) Gianny D'Amour, an early addition to Geronimo, wound up adding what David calls "one of the biggest patches to Geronimo or OpenEJB I've ever seen, largely completing our CMP [container-managed persistence] implementation." Jacek Laskowski, a long-time OpenEJB committer, started the first Geronimo-Tomcat integration effort, which was driven to completion by Geronimo's Jeff Genender, who also ended up earning OpenEJB commit.
In fact, David said that when it comes to OpenEJB and Geronimo, "It's largely one community." That's part of the reason why when Geronimo invited OpenEJB to become part of Apache, the answer was once again yes.
OpenEJB is still in the process of obtaining all the necessary paperwork to become part of the Apache incubator -- any third parties, such as companies that hold copyright on any portion of the code, need to make the proper grants and donations in writing. After that's done, the OpenEJB code will have its own section in Subversion under the incubator. The mailing lists will be under the incubator domain, and so on, making it much easier for those involved in both projects.
The incubator has been described as an airlock of sorts. It's for projects that have been invited to be part of Apache but have not yet been formally accepted. To graduate from the incubator, a project must adapt to the so-called Apache way of doing things. "There's a lot of criteria," David explained, "but basically you have to demonstrate a healthy community, and you have to have clean IP."
The project is currently working on the so-called clean IP aspect of the process, getting signoffs from companies, such as Intalio, which funded early development. But a healthy community is not a problem. The project has been around for six years and has a number of dedicated committers. (And those ranks have swelled considerably with the addition of those who have come in from Geronimo.) This kind of diversity is crucial to Apache. David explained, "Diversity is a critical aspect to code and the community surviving the withdrawal of people resources." In other words, when parts of the community go away for a while, which is inevitable on any long-lived project, the community as a whole has to be strong and diverse enough to survive.
Meanwhile, OpenEJB must make at least one release as part of the incubator process. Already the project has been profoundly affected by its involvement with Geronimo, particularly on the container, which required the most work to upgrade to EJB 2.1.
OpenEJB actually consists of two parts -- the server and the container -- and the team makes a point of keeping them separate. The EJB specification talks about the container and server contract as distinct parts, but never actually defines the parts. OpenEJB defines a container-server contract, and in the end the server part of OpenEJB was incorporated into Geronimo pretty much as is, but the container part was completely rewritten for the project. "We don't use all of Jetty, and we don't use all of OpenEJB that had been around before Geronimo's existence," David noted. "One of the things [members of the Geronimo community] pride ourselves on is that we didn't just glue together a bunch of pieces randomly and come out with some sort of Frankenstein result."
The server side of OpenEJB handles the distributed part of the equation. In any distributed system you need two things: the ability to locate the component or service you want to use and a way to call it once you locate it. Locating the component or service typically involves some sort of registry. In Web services, it's Universal Description, Discovery and Integration (UDDI). In CORBA, it's CosNaming. In EJB, it's Java Naming and Directory Interface (JNDI). Ideally, you should be able to take care of the second part -- invoking the component -- (be it a Web service, a CORBA stub, or a remote EJB) via normal programming means. In other words, you should be able to invoke the component as though it were a local object.
The server part of the environment handles this invocation process, making sure that the invocation gets to the actual remote object and that the response gets back to the client. The server also handles tasks, such as "communicating transaction security state across calls," David said.
I have to admit, that's a pretty tall order for Plain Old Java Objects (POJOs). Already, I'm beginning to see the advantages of using EJBs. But still, I'm a Web services guy, so remote systems don't scare me. What else does EJB do for me as a programmer? Plenty, it seems -- much of it centered around the functions performed by the container.
Three types of EJBs exist -- session beans (stateless and stateful), message-driven beans (MDBs), and entity beans. "I've never liked the terms stateless or stateful," David admitted, "because they both hold state. It's just that they have different guarantees on that state. I used to teach EJB [classes], and I would always tell my students to think of them in terms of dedicated instances and shared instances. Dedicated instances are stateful session beans, and shared instances are stateless session beans. You can think of a shared component as a book you borrow from the library. If you give it back after you're done reading it, you can check it out again, but you may not get the same physical book, even if it's the same title. And somebody may have scribbled and written in it, and you have to account for that when you make a call on it."
Dedicated, or stateful, beans don't have that problem, because once you request one, it's yours. Nobody else can use that component instance, so you can be sure any scribbles in it are yours. The challenge here is that you now run the risk of accumulating a nearly infinite number of these private states on the server, so you'll need a way to push those that aren't being used out to disk. All of that's handled by the container.
The container also manages MDBs, which enable you to easily use the Java Message Service (JMS) to pass messages around. "You can have [message-driven beans] transactionally invoked, via JMS, which is a nice handy feature," David explained. "You don't have to write much code. All you would have to do is implement the interface, and the requests come in to you from JMS." In such an application, you don't have to worry much about the form of the client receiving your messages.
And then there's the issue of entity beans, which have their own advantages -- mostly surrounding persistence and caching. For example, you can pull information from a database and use an entity bean to cache the data for the duration of a transaction. "That's the kind of optimization that would be hard for you to program yourself, reliably," said David.
All of this functionality is the container's responsibility. The container "manages pools of stateless beans and caches of stateful beans and entity beans," David told me, "and when an invocation comes in, it does the required things to ready a component for invocation. It prepares any transactional state or guarantees any security requirements before invoking, and then once it invokes, it deals with any type of failure, rolling back transactions, that sort of thing, and then sends the request back to the server to be communicated to the client."
Now, that's an awful lot for the container to do. All by itself, it's probably worth using beans rather than trying to manage all of that by yourself. But that's not all the container does. The container also manages the life cycle of each component.
You might say, "So what does that mean?" That means that the container knows exactly what's happening to a component and can let you know. For example, you might like to know before it's about to invoke a component, before it starts a transaction within the component, before it ends a transaction, or before it destroys the component, and so on. Why would you want to know? Well, because you could actually perform an action at that point. For example, you can implement a callback that, say, sends a message when the transaction is complete or when one is rolled back. This gives you complete control over the life cycle of your component.
This power doesn't come without a price, however. That price is the fact that you have to actually implement all those callbacks -- whether you want to use them or not. This can become a problem for programmers who may not need all of the functionality that EJB provides, because the requirement to implement every single callback isn't a matter of choice of the EJB implementation, but rather a consequence of the fact that EJBs are implemented via plain old Java interfaces. "It becomes a really cumbersome API to develop against if you have lower-end needs," said David.
Fortunately, most of that complexity will go away with the coming of EJB 3.0, which is a major change to the way EJBs are constructed. Rather than implementing interfaces or callbacks, you'll simply annotate your plain old Java class. "In EJB 3.0, you can just say 'Pow, that's a component, I've labeled it stateless,'" David commented. To implement callbacks, you'll simply create the method and annotate it appropriately. "It requires a lot less work on your part, and so these antipatterns that people have basically found for EJB using session locators and all this crazy type stuff, so they can basically shed the EJB API and still have -- all that stuff is now unnecessary."
Of course, that's for the future when (and, I suppose, if) the OpenEJB 3 branch started at the first of the year becomes part of Geronimo. But even now there are compelling reasons why OpenEJB fits so well with the application server.
As you may know, Geronimo is based on the concept of GBeans, which enables you as an administrator to determine exactly which components you want to activate. So you can have a super-streamlined version or a super-industrial-strength version, but what you want to support is up to you. OpenEJB aligns well with this concept because the clean separation between the server and the container enables it to be flexible when determining what transports to support. For example, whereas some EJB systems require you to have CORBA, Web services, and any other transports the server wants to offer, OpenEJB enables you to pick and choose by wrapping each transport as a GBean. This way, you can have two different CORBA orbs, any number of Web service implementations, and whatever else you feel is necessary. Or, alternatively, you can support none of them and allow only local invocations. Also, the way the server is constructed, you can support multiple transports without having to have multiple copies of the application server or even the application. (Author's note: David points out that this capability is especially useful for Web services, where the intention is for complete interoperability, but the reality is somewhere short of that goal.)
Moving forward, OpenEJB has some exciting features on the horizon; some brand new, some not so new. For example, David is very excited about the proposed return of embedded testability for container-driven testing. This is the ability to easily test OpenEJB components using JUnit. Normally, these components don't run without a container, requiring you to perform special setup before testing and teardown afterward. But embedded testability enables you to create an environment that includes the container as an embedded part of the system, the same way that you can embed a database like IBM Cloudscape™. "That was something we had in OpenEJB 1, we lost in OpenEJB 2, and we're going to bring back in OpenEJB 3," explained David. "So if you write OpenEJB components, you can run them with your regular JUnit tests with no muss or fuss."
OpenEJB 3 will also look at supporting the Java Persistence Architecture API (JPA). David related that "OpenEJB has historically preferred to use other components for its persistence. In OpenEJB 1, we used Castor, and in two we used TranQL. In three we're going to be using OpenJPA, and that API is now standard, so it's going to be pluggable. So if TranQL or Castor or any other project did decide to support JPA, we'll be able to support any of them -- or all of them at the same time."
OpenEJB will also support constructor injection, which enables the container to provide various classes and objects at run time. The EJB 3.0 specification talks about public field injection and setter injection, but constructor injection will enable you to avoid creating setters for values you don't expect to change. And, of course, it helps to avoid the necessity of accomplishing the same functionality using public fields. "That's generally something that we stopped doing in 1995, about three days after Java was invented," David declared.
With persistence, transaction management, and the knowledge that programming to this API will not always be so painful, I can see where the value lies in investigating EJBs further, especially for projects destined to run on Apache Geronimo. They're a powerful force in Web applications -- and, in fact, even in non-Web applications. Take a look at the Resources section of this article for links to help you continue your own investigation.
Read more about the Apache Incubator.
Join the mailing list at the Apache Geronimo Web site.
- Read "Deploy J2EE applications on Apache Geronimo" (developerWorks, January 2006) information about using OpenEJB and XDoclet for deployment descriptors.
Read Neal Sanche's article "Dive into EJB Web applications with Geronimo (developerWorks, July 2005).
- Check out "Create, deploy, and debug Apache Geronimo applications" (developerWorks, May 2005)
to learn about using Eclipse to deploy your application to a remote instance of Geronimo.
- Read "Building a better J2EE server, the open source way" (developerWorks, May 2005) for great information about the development process behind Geronimo, including its JSR 88 support.
- Learn about Geronimo's support for the full J2EE 1.4 specification in the two-part series from developerWorks: "Geronimo! Part 1: The J2EE 1.4 engine that could" and "Geronimo! Part 2: Tame this J2EE 1.4 bronco."
- Read the JSR 88 Specification.
- See "Understand Geronimo's Deployment Architecture," which provides a detailed description of Geronimo deployment plans and how Geronimo uses them.
- Learn how to connect your database to a Web application written for Geronimo in this article (developerWorks, June 2005).
- Peruse the tutorial, "Apache Geronimo uncovered" (developerWorks, August 2005) to explore the ins and outs of Geronimo and compare its features and capabilities to those of IBM WebSphere® Application Server Community Edition.
- 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.
- Check out the developerWorks Apache Geronimo project area for articles, tutorials, and other resources to help you get started developing with Geronimo today.
- Check out the IBM Support for Apache Geronimo offering, which lets you develop Geronimo applications backed by world-class IBM support.
- Find helpful resources for beginners and experienced users at the Get started now with Apache Geronimo section of developerWorks.
- 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 products and technologies
Download the latest release of Apache Geronimo.
- Innovate your next open source development project with IBM trial software, available for download or on DVD.
- Download your free copy of IBM WebSphere® Application Server Community Edition V1.0 -- a lightweight J2EE application server built on Apache Geronimo open source technology that is designed to help you accelerate your development and deployment efforts.
- Participate in the discussion forum.
- Stay up to date on Geronimo developments at the Apache Geronimo blog.
- Get involved in the developerWorks community by participating in developerWorks blogs.
Nicholas Chase has been involved in Web site development for companies such as Lucent Technologies, Sun Microsystems, Oracle, and the Tampa Bay Buccaneers. Nick has been a high school physics teacher, a low-level radioactive waste facility manager, an online science fiction magazine editor, a multimedia engineer, an Oracle instructor, and the chief technology officer of an interactive communications company. He is the author of several books, including XML Primer Plus.