In August 2003, the Apache Software Foundation (the group responsible for the popular Apache HTTP Server) announced plans to create an open source, certified J2EE server -- and Geronimo was born. As a compliant J2EE server, Geronimo is a very large project covering a diverse feature set. In this first part of a two-part series, I'll introduce Geronimo from a user perspective to give you an appreciation of the project's sheer scope. Then I'll explain some terminology you're certain to encounter when studying Geronimo documentation or exploring the project source code. Last but not least, you'll get an overview of Geronimo -- zooming in on several key concepts -- from a systems-design perspective.
After reading this article, you'll be ready to explore Geronimo further on your own as a user of the server -- or even as a contributor to the open source project. Part 2 of this series will give you some hands-on experience with the server and will explore application configuration, deployment, and management in more detail.
My sincere thanks to Geir Magnusson, Jr., Jeremy Boynes, David Jencks, and Alan D. Cabrera from the Geronimo team for their valuable comments on drafts of this article.
Geronimo: A J2EE 1.4 compliant server
As a J2EE server, Geronimo can deploy and run your Web and enterprise applications. You can use Java ServerPages (JSPs), servlets, filters, and Enterprise JavaBeans (EJBs) to compose your application. The application has access to external RDBMS through Java Data Access API (JDBC) connector, to directory services through the Java Naming and Directory Interface (JNDI), to transactional message queues through the Java Message Service (JMS), to e-mail through JavaMail, and so on.
The goal of J2EE certification is both a blessing and a curse for the Geronimo project (see The toll of certification). In order to be certifiable, Geronimo must support all mandatory features described in the J2EE 1.4 specification (see Resources). The specification refers to a collection of other specifications that also have their own mandatory clauses. Figure 1 gives you some idea of what Geronimo must implement before qualifying for certification.
Figure 1. Geronimo as a J2EE 1.4 compliant server

In Figure 1, the bold words inside the boxes are the names of specific APIs, and the italic words indicate how Geronimo implements them currently. You probably recognize some of the italicized project names.
A potpourri of open source projects
Geronimo's server infrastructure -- consisting of the kernel, tools, and library -- is designed and written from scratch by experienced developers. But many of the constituent components are existing projects selected from Apache's own project community, and from other open source projects with licenses compatible with the Apache License (see Resources and Why another J2EE server?).
Table 1 lists the many other open source projects that Geronimo comprises today. This divide-and-conquer strategy repurposes tested and proven open source assets and significantly reduces Geronimo's overall development burden.
Table 1. Open source projects integrated into Geronimo
| Specification required for J2EE certification | Area of coverage | Project or code used by Geronimo |
|---|---|---|
|
Servlets 2.4 JavaServer Pages (JSP) 2.0 | Web tier container with support for JSPs and servlets | Jetty and Tomcat (see Resources) |
| Enterprise Java Beans (EJB) 2.1 | EJB container | OpenEJB (see Resources). |
| Java Message Service (JMS) 1.1 | Messaging service | ActiveMQ (see Resources) |
| Java Naming and Directory Interface (JNDI) 1.2.1 | Directory service/naming API | Custom code implementation |
| Java Transaction API (JTA) 1.0 | Transactions | Custom manager with High-speed ObjectWeb Logger (HOWL) for transaction logging, XA supported, evolving to Java Open Transaction Manager (JOTM) (see Resources) |
| JavaMail 1.3 | Custom coding | |
| JavaBeans Activation Framework (JAF) 1.0 | Activation -- handling html/text/gif/jpg MIME types, primarily for JavaMail attachments | Custom coding |
| JSR 77 -- J2EE Management 1.0 | Manageability | Custom coding with MX4J (see Resources) |
| JSR 88 -- J2EE Deployment 1.1 | Deployment and configuration -- cross-vendor server deployability | Custom code implementation |
| Java Management Extensions (JMX) 1.2 | Manageability | MX4J (see Resources) |
| Java Data Access API (JDBC) 3.0, 2.1 | Database | Code from TranQL (see Resources) |
| Java API for XML Processing (JAXP) 1.2 | SAX, DOM APIs; third-party SAX, DOM, XSLT engine pluggability | JDK support where applicable, and Apache Xerces |
| J2EE Connector Architecture (J2CA) 1.5 | Connector | Custom coding. Includes JMS resources and JDBC pools. |
| JSR 109 -- Implementing Enterprise Web Services 1.1 | Web services | Apache Axis (see Resources) |
| Java API for XML-based RPC (JAX-RPC) | Web services | Apache Axis |
| SOAP with Attachments API for Java (SAAJ) 1.2 | Web services | Apache Axis |
| Java API for XML Registries (JAXR) 1.0 | Web services | Apache Scout (see Resources) |
| JSR 115: Java Authorization Contract for Containers (JACC) | Security -- authorization and authentication | Custom development using JDK's JAAS support |
| Internal database | Database | Derby (see Resources) |
| Persistence mechanism | Database | Unified substrate for CMP and Beans/POJO oriented schemes over TranQL (see Resources) |
| Interoperability | TCP/IP, HTTP1.1, SSL3.0, TLS 1.0, SOAP 1.1, WS-I Basic Profile 1.0 CORBA - IIOP, RMI-IIOP, EJB Interop, CORBA Interop Naming Service, JRMP | JDK support (that is, ORB and JRMP), support from other packages, and custom code |
The complexity of the system depicted in Figure 1 is enough to give most system architects a headache. But when you consider the open source projects that must be integrated together to form Geronimo, the need for a unifying model of integration becomes apparent.
The idea is to create a generic service container that can deploy and run arbitrary services. For example, OpenEJB can run as a service on this container to host all the EJBs, and Jetty or Tomcat can run as another service in the same container to host all the servlets and JSPs. Not only does this model make the integration of existing open source services straightforward, but it also adds the ability to host any compatible service in the future -- including non-J2EE services, such as the Spring application framework (see Resources).
The container's design must be kept generic yet support the plugging in of J2EE and non-J2EE services. This is a very difficult design task. The container should handle all the tedious and repetitive work that nobody wants to do, but it must not be so all-encompassing that it gets in the way of the plugged-in services. The designers of Geronimo, with some assistance from the J2EE 1.4 specification, have identified three required functional areas among all services:
- Manageability
- Configuration management
- Service lifecycle
This list covers three of the primary functions of the Geronimo service container. You'll see shortly how Geronimo implements these requirements.
Lofty goals: Scalability, manageability, and configuration management
Taking the lead from the telecommunications industry, Geronimo's designers are attacking the problem of large-scale manageability and configuration management. The term Operations, Administrations, Maintenance and Provisioning (OAM & P) has been bread-and-butter for telecom system engineers, but it's relatively new to Java system designers. In systems where hundreds or thousands of instances of a service are running concurrently, and failure-plus-recovery occurs every single minute, the view of how one operates, administers, and maintains the system changes significantly. For example, manual modification of configuration files for each instance is totally out of the question.
In the ultimate vision, you could give a work order like this one to a cluster of Geronimo instances:
Provision the Pet Store Web application for 50,000 customers per hour during peak loading, with a Service Level Agreement restriction of 99% uptime and no more that five seconds to process an order, until June 15. On June 15, reduce peak loading to 10,000 customers per hour and SLA restriction to 80% uptime and 10 seconds per order, until August 31. Remove the Web application on September 1.
Upon receipt of the work order, your network management system would then provision and schedule all the configuration and deployment changes for you across the cluster, monitor progress, and adaptively tune your system over time to achieve your objectives.
This vision is still quite far away from today's reality (at least for non-telecom systems), but Geronimo's architecture has been designed from day one with it in mind.
The first basic step in achieving a usable container design that's consistent with the Geronimo vision is to make sure the container is manageable. The Geronimo team's approach to this goal has evolved over time.
The natural route to accomplishing goal of manageability is to make the Java Management Extensions (JMX) the container's core. If every relevant object instance within the container is properly instrumented and is manageable, then the running system can be managed, monitored, and controlled by external tools, and scalability features can be implemented. The first cut of Geronimo's kernel design, illustrated in Figure 2, stemmed from this line of thinking.
Figure 2. Original Geronimo kernel design with JMX core

In Figure 2, JMX is at the container's very core -- the kernel -- and every relevant object in the container is an MBean. MBeans are required to be completely instrumented and manageable. The Geronimo team selected MX4J (see Resources) for this purpose.
In practice, however, the Geronimo team realized that it had stretched MX4J beyond its intended design. Geronimo was no longer using MX4J just as a JMX, but as a general-purpose yet high-volume system for object location, interobject communications, method interception, and so on. As the team continued along this road, the container's complexity escalated and performance started to dive.
Another discovery that the team made is that it's difficult to adapt existing service code to a system with a management-centric core. The boxes on top of the JMX core in Figure 2 represent services, and the vertical "fork" of dotted lines represents code that handles manageability concerns. The manageability-concern code is in line with the design of the JMX-centric service, while the service logic code is orthogonal (and crosscutting). This creates service code that is difficult to write and maintain. It was time for a change of plans.
Building a better kernel, IoC style
Geronimo's revised kernel design is shown in Figure 3.
Figure 3. Current kernel architecture for Geronimo (an IoC kernel)

As Figure 3 shows, the JMX implementation is no longer at the kernel's core. Instead, the kernel architecture is based on Inversion of Control (IoC; see About IoC). JMX is still very much part of the kernel, because manageability is still of utmost importance, but it is relegated to being one of the many dependencies that can be injected into a service at deployment time. This greatly facilitates the creation of new services, because the code can be (and should be) centered around service logic. To gain JMX manageability, it only has to follow certain coding conventions for IoC dependency injection. This design also makes it simpler to move existing services to Geronimo, where a thin wrapper can be created around the existing service, adapting it to the IoC kernel. Note that the services are no longer represented by JMX MBeans, but by Geronimo-specific GBeans, which you'll learn more about in the next section.
This design can support completely JMX-free unmanaged operations, where components interact purely through the kernel. It provides a lightweight solution in situations where Geronimo is running as an embedded component of an IDE, command-line tool, or other custom application.
The terminology I've used up to this point (with the exception of GBeans) has been generic. Before going any further, I should introduce you to some terms you will find in Geronimo and their definitions.
Consistent with J2EE terminology for a deployable unit, each deployable software unit is often referred to as a module (see Modules and configurations). A module can contain many Java class and GBeans and is typically associated with one or more Geronimo deployment plans. (I'll describe GBeans and explain Geronimo deployment plans in the following subsections.) For example, a module can be a Web application in a Web archive (WAR) file or an enterprise application in an enterprise archive (EAR) file. A module is a user concept. Internally, the Geronimo kernel doesn't see modules and works only with configurations (defined later).
A Geronimo deployment plan is the Geronimo-specific metadata that is required to deploy a module (configuration) successfully. Physically, it is an XML file. It can be located inside a module's archives or stored externally (where it can be managed and edited through a deployment/management tool). A Geronimo deployment-plan XML file can have different names, depending on the module type and its location. For example, the Geronimo deployment plan for an EJB JAR module, embedded in the JAR, is called openejb-jar.xml; while a Geronimo deployment plan for an enterprise-application EAR module is called geronimo-application.xml when embedded in the archive. When deployment plans are maintained outside of the archive, they can have any name. Geronimo has default deployment plans for simple module types such as WAR, EAR, and JAR.
Whereas a module is a deployable unit, a GBean is a manageable unit in Geronimo. A single deployable unit can contain zero or more manageable units. Therefore, a single deployed module in Geronimo can deploy many GBeans. Not all classes in a module/configuration need to be GBeans. Only entities that want to receive lifecycle callback, or entities that want to expose JMX manageable attributes and operations, need to be made GBeans. A GBean can have multiple running instances. Geronimo assigns each instance a unique name when a GBean starts up. Internally, Geronimo sees only GBeans and configurations, and not modules. Module is a user concept and GBean is a system concept
A configuration is the assembled deployment of one or more modules. Internally, Geronimo sees a configuration as packaged deployment of one or more GBeans. The Geronimo kernel understands and manages configurations. You can think of a configuration as something that you want to run. In J2EE, it can be an enterprise application; outside of J2EE, it can be a collection of custom services that you have created.
One key idea behind a configuration is that you can serialize it, and then deserialize it back on any other system running Geronimo -- and have the same configuration running on the other Geronimo instance. The ability to migrate a configuration is very important to scalability. For example, imagine having to start 500 instances of Geronimo with the Pet Store application. With a persisted Pet Store configuration ready, the task becomes as simple as starting the instances with the serialized configuration.
A configuration can also have external dependencies. It's the container's job to manage these dependencies and make sure that they're available upon request.
A running Geronimo system consists of many running configurations. Configurations can have hierarchical relationships. Each configuration has a unique user-specified configuration ID. A configuration can specify another configuration as its parent configuration. A child configuration inherits its parent's classloader and therefore has access to all the parent configuration's classes. This can be useful, for example, if you need to share libraries between two separately deployed configurations.
The important Geronimo concepts I'll describe in this section will help you in your own investigation of Geronimo or its source code.
GBeans are much more than JMX MBeans. A GBean makes a great facade for a manageable service. One benefit of a GBean is that the container can manage its service's lifecycle. The container will call a GBean on the changing of state if the GBean implements the optional GBeanLifecycle interface, shown in Listing 1:
Listing 1. The optional
GBeanLifecycle interface for GBeans
public interface GBeanLifecycle {
void doStart() throws Exception;
void doStop() throws Exception;
void doFail();
}
|
Figure 4 shows the states that a GBean transitions through.
Figure 4. GBean lifecycle and JSR 77 managed state

You can see in Figure 4 that a module containing a GBean can be deployed or distributed to a target. A target can be a single machine or a cluster of machines. When you distribute to a target, the GBean configuration is verified and stored, but not started on the target. If you deploy to a target, the GBean is started.
When the server is stopped, GBean persistent states are persisted to the configuration store. This means that the same GBean configuration will start up on the next server restart. When you undeploy a GBean, the associated configuration is removed from the target. Any running instances are stopped, and you can't restart the GBean without redeploying it.
Between the starting (0) and the stopped (3) state are the state transitions that trigger callback on the GBeanLifecycle interface. These also correspond to the JSR 77 manageable states (see Two key specifications: JSRs 77 and 78).
Configurations are persisted in serialized format to a configuration store. Geronimo supports plug-in providers for configuration stores. For example, instead of storing configurations to a local disk, you can store them to an enterprise directory service through a JNDI provider. This can potentially enable geographically separated clusters of Geronimo instances to share configurations.
Because Geronimo supports JSR 88 for deployment-tools interoperability, the values in the configuration store, which is the current parameterization of the deployed module, can be edited using a JSR-88 compliant third-party tool -- potentially within a GUI-based IDE or through a network management system.
The dependency manager is a vital component in Geronimo. Starting a specific configuration frequently requires starting its dependencies first. For example, a Web application that accesses JMS and an RDBMS through JDBC needs to make sure that ActiveMQ has started and that the JDBC Connector module is started and available. The dependency manager scans all of a module's deployment descriptors and deployment plans in order to determine dependencies. It's the job of the dependency manager to make sure that a module's dependencies can be satisfied before starting it. You specify a module's dependencies explicitly inside the Geronimo deployment plan.
Wiring up GBeans: References and interaction
It might seem at first glance that a container's job is almost done once a GBean is successfully deployed and running. But this is far from true. Another major functional requirement for the container is to "wire up" the references between the GBeans, allowing them to interact.
When a configuration is started, any GBean that obtains a reference to another GBean is actually handed a container-generated proxy. The proxy has the exact same interface as the referenced GBean. This decouples the two GBeans and enables the container to manage the lifecycle of the referenced GBean.
Resolvable references to other GBeans are accessed through a dynamically generated invoker proxy. This effectively enables the GBeans to call one another without kernel intervention. Figure 5 illustrates this behavior.
Figure 5. Wiring up GBeans

In Figure 5, GBean 1 invokes a method on GBean 2. GBean 2 is a resolvable reference, and Geronimo dynamically generates an invoker proxy. The invoker allows the two GBeans to interact directly. Geronimo currently uses cglib, a bytecode-generation tool (see Resources), to generate the invoker code dynamically.
Geronimo has the potential to become one of the more attractive containers for server-side product development. Its rich feature set, the no-obligation Apache License, and the benefits of a "ready-to-deploy" J2EE 1.4 container are sure to appeal to many developers. Having read this article, you now know what the Geronimo server is about and why it's an important milestone in open source software development. You've explored Geronimo's architecture and become familiar with some key terminology and concepts. Part 2 of this series will lead you through hands-on examples working with the actual server.
- Part 2 of this series focuses on operation, deployment, configuration, and management using Geronimo.
- Gluecode Software CTO and principal Geronimo contributor Jeremy Boynes shares his perspective on Geronimo, the direction of Java programming, and the state of open source software in this recent interview from developerWorks.
- The official site for the Geronimo project has the latest source code and binaries, and an active community on the mailing lists and wiki.
- The Apache Software Foundation, where you can read the detailed text of the latest Apache License, is the home of Geronimo.
- For the text of alternative open source software licenses, see the Lesser General Public License and the General Public License from the GNU Project.
- Learn more about Jetty, the default servlet and JSP container integrated with Geronimo, from the project site.
- Discover Tomcat, the alternate servlet and JSP container for Geronimo.
- Explore the capabilities of OpenEJB, the EJB container in Geronimo.
- Derby is the default relational database service and JDBC provider for Geronimo. Visit the Derby project Web site for manuals, source code, and an active user community on the mailing lists.
- Geronimo integrates Axis, a versatile Web services stack, to achieve compliance with the WS-I Basic Profile.
- One of Geronimo's goals is to use the same substrate to implement both EJB and lighter-weight POJO persistence. The solution is the TranQL project.
- The Geronimo team works closely with the folks at ObjectWeb for transaction support. HOWL and JOTM are the key ObjectWeb projects relevant to Geronimo.
- The Geronimo team hopes to integrate the Apache Directory Server, code-named Apache Eve, in the near future.
- To handle manageability requirements, Geronimo uses the MX4J library for its JMX implementation.
- Geronimo uses Apache Scout to implement JAXR for Web services compatibility.
- Geronimo uses the excellent cglib code-generation library to set up interception pipelines for inter-GBean references.
- The versatile Velocity template engine is used extensively in
the Geronimo build process and in console modules.
- Geronimo uses Apache Maven to manage multiproject code builds and Apache Ant for individual project builds. Version control for most projects is managed using Subversion.
- To learn more about the Java Management Extensions (JMX), check out Sing Li's From black boxes to enterprises: JMX 1.1 series (developerWorks, Fall 2002).
- For more information on the Inversion of Control pattern and dependency injection in general, see the Spring application framework.
- You can learn about an alternative open source J2EE 1.4 certified server, available under an LGPL license, at the Java Open Application Server (JOnAS) Web site.
- For the set of detailed J2EE 1.4 specifications, visit the J2EE specifications page.
- Java technology managers, architects, and developers can get a window into J2EE technologies from the J2EE Pathfinder series.
- Read "Java liberation: An interview with Jason Hunter" (developerWorks, April 2002) to learn about the history of open source projects' participation in the Java Community Process.
- Get involved in the developerWorks community by participating in
developerWorks
blogs.
- You'll find articles about every aspect of Java programming in the developerWorks Java technology zone.
- Browse for books on these and other technical topics.

Sing Li is a consultant and freelance writer. He has contributed to Beginning JavaServer Pages, Professional Apache Tomcat 5, Pro JSP - Third Edition, Early Adopter JXTA, Professional Jini, Beginning J2ME: From Novice to Professional, Third Edition, and numerous other books. He is also a regular contributor to technical magazines and an active evangelist of the VON and P2P evolutions. You can reach Sing at westmakaha@yahoo.com.





