A first look at Apache Geronimo

Start developing and deploying J2EE apps on Apache's open source J2EE server

The ambitious Apache Geronimo project has been going full-steam for more than a year now and has recently made its third milestone release. If you haven't checked it out yet, this article will help you get started. We'll download and install Geronimo, review some of its architecture, and go through a couple of sample J2EE applications.

Although no date has been set for the official release, its list of stated goals is indeed impressive:

  • Pass Sun Microsystems' J2EE 1.4 certification
  • Reuse as much existing ASF (Apache Server Foundation) code as possible
  • Integrate technology outside of ASF within Geronimo, most notably OpenEJB and ActiveMQ from codehaus.org

Geronimo is a J2EE server, which means it includes all the containers required by the J2EE 1.4 specification (but, thanks to smart thinking, is backwards compatible to earlier versions). Wherever possible, Geronimo uses existing open source products. Some of these are:

  • Servlet container services: Jetty and Tomcat
  • Enterprise JavaBean container: OpenEJB
  • Java Message Service (JMS) provider: ActiveMQ
  • Database connection pooling: TranQL
  • Transaction support: HOWL (High-speed ObjectWeb Logger)
  • Database: Axion, Derby
  • Java Management Extensions (JMX) support: MX4J

Each service is implemented by a core object called a GBean. Much work went into the design of these GBeans so the core server could manage their entire lifecycles without manual intervention.

Geronimo and JBoss
Geronimo has also had to deal with some legal noise from JBoss, who alleges similarities between the Geronimo and JBoss codebases. It appears as if the ASF has successfully repudiated these allegations, but as yet, JBoss has not acquiesced. If nothing else, this situation means the project is being carefully watched by its competitors!

Build and install Geronimo

Although the Geronimo team makes milestone releases available (the current one is M3), I recommend using the latest source and building Geronimo yourself. While building from source can be time consuming, you will need the latest source to get the examples in this article to work. (I did my best to get them running on M3, but alas, they wouldn't all work.) To build Geronimo, you need three things: the Subversion version control system client, Apache Maven, and the Geronimo source code. I assume you have downloaded and installed the first two per their instructions. Now, with both the Subversion client and the Maven executable in your PATH, you can build Geronimo.

First, you need to download Geronimo. To do that, type this Subversion command:

 svn checkout http://svn.apache.org/repos/asf/geronimo/trunk geronimo

This command creates a directory called geronimo, which contains the Geronimo source code, in the directory where you are currently located. Now, change into the geronimo directory and do the build:

 cd geronimo
maven -Dmaven.test.skip=true -Dmaven.itest-skip=true m:rebuild-all 

The two system properties tell Maven to ignore all the tests and just do a straight build. While the Geronimo build instructions tell you to build without them, I couldn't get Geronimo built without some tests failing. Thankfully, however, whatever failed did not affect this article's examples.

If this is your first time executing Maven, you may have to wait a bit. On one of my Windows XP machines with an ISDN connection, execution took an hour and a half! But chances are your time will be considerably less. Still, find a good movie to watch while you wait.

Eventually, the build will complete—hopefully with success. If it showed a failure, you'll have to wait until the next day and hope whatever was broken has been fixed. Or join one of the Geronimo lists and let the team know about your problems.

In the source code tree, you will find the build files in the modules/assembly/target/geronimo-1.0-SNAPSHOT subdirectory. Rather than remembering all that, create a symbolic link somewhere convenient. In my case, I did:

 cd ~/build/ext
ln -s geronimo/modules/assembly/target/geronimo-1.0-SNAPSHOT geronimo-latest

>From now on, I'll refer to this Geronimo installation directory as $GERONIMO_HOME.

Create a sample Web application

Currently, Geronimo does not come with much in the way of demo or default applications. So let us start with the first of a series of sample applications we will build for this article. Find a development space somewhere (mine is in ~/devel/test), and create a directory called gtest. I'll refer to this directory as $GERONIMO_DEVEL. Within this directory, create the following directories:

 etc
src
web

Our first project is just a simple Web application. For this, we need three files. First, we need a simple JSP (JavaServer Pages) page, index.jsp, which we put in the web directory:

 <%@ page language="java" import="java.util.Date" %>
<html>
 <head>
  <title>Geronimo Test Application</title>
  <style type="text/css">
   <!--
    a { text-decoration: none }
    body { font-family: verdana, helvetica, sans serif; font-size: 10pt; }
    td { font-family: verdana, helvetica, sans serif; font-size: 10pt; }
    p { font-family: verdana, helvetica, sans serif; font-size: 10pt; }
    ul { font-family: verdana, helvetica, sans serif; font-size: 10pt; }
    h3 { font-family: verdana, helvetica, sans serif; font-size: 12pt; font-weight: bold; color: #547180; }
   -->
  </style>
 </head>
 
 <body>
  <br/> 
  <br/> 
  <center><h3>Geronimo Test Application</h3><br/>
  <table width="50%"><tr><td>
   <p>Welcome to Geronimo. Today is <%=(new Date())%>. This is a J2EE application running inside of Geronimo. Here are some things you can try</p>
   <ul>
    <li><a href="ejbtest.jsp">Test a simple EJB</a></li>
    <li><a href="dbtest.jsp">Test a JDBC connection pool</a></li>
   </ul>
  </td></tr></table>
  </center>
 </body>
</html>

Second, we need a Web application descriptor, web.xml, which goes in the etc directory:

 <?xml version="1.0"?>
   
<!DOCTYPE web-app
    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/dtd/web-app_2_3.dtd">
   
<web-app id="GeronimoTestWebApp">
    <display-name>GeronimoTestWebApp</display-name>
</web-app> 

Note the id attribute in the <web-app> tag. This gives Geronimo a name for your application. (If you don't supply the name, Geronimo will try to use the value of the <display-name> tag.) Without a name—technically a configuration id—Geronimo can't deploy the application.

DTDs and XML schemas
I purposely use the Servlet 2.3 specification document type definition for my web.xml to keep things as simple as possible. Geronimo supports not only DTDs, but also the newer XML schemas as used in the J2EE 1.4 specification. As I imagine many of you have spent much of your time developing against the 1.3 specification, it is nice to know you don't have to update all your descriptor files to run on Geronimo.

Finally, we need an Ant build file. If you don't have Ant installed, you can download it from Resources. Once you install it, make sure the bin directory in the Ant installation directory is in your PATH. This is the build file we'll use. It is called build.xml and goes right in $GERONIMO_DEVEL:

 <project default="build" basedir=".">
   
  <property name="ghome" value="${user.home}/devel/build/ext/geronimo-latest"/>
   
  <path id="cp"> 
    <pathelement path="${java.class.path}"/>
    <fileset dir="${ghome}/repository/geronimo-spec/jars">
      <include name="*.jar"/>
    </fileset>
  </path>
 
  <target name="prepare">
    <mkdir dir="dist"/>
    <mkdir dir="classes"/>
    <mkdir dir="build"/>
 
    <delete>
     <fileset dir="classes"
       includes="**/*.class"/>
    </delete>
 
    <mkdir dir="build/WEB-INF"/>
    <mkdir dir="build/WEB-INF/lib"/>
 
    <copy file="etc/web.xml" todir="build/WEB-INF"/>
    <copy file="etc/geronimo-jetty.xml" todir="build/WEB-INF"
       failonerror="false"/>
    <copy todir="build">
      <fileset dir="web"/>
    </copy>
  </target>
 
  <target name="compile" depends="prepare">
    <javac srcdir="src" destdir="classes"
           debug="on" optimize="off" deprecation="off">
      <classpath refid="cp"/>
    </javac>
  </target>
 
  <target name="jar" depends="compile">
    <jar jarfile="build/WEB-INF/lib/gtest-ejbs.jar">
     <fileset dir="classes"
       includes="**/*.class"/>
     <metainf dir="etc" includes="ejb-jar.xml,openejb-jar.xml"/>
    </jar>
  </target>
 
  <target name="war" depends="jar">
    <war destfile="dist/gtest.war" webxml="build/WEB-INF/web.xml">
      <fileset dir="build">
        <exclude name="WEB-INF/web.xml"/>
      </fileset>
    </war>
  </target>
 
  <target name="ear" depends="war">
    <copy todir="dist" file="build/WEB-INF/lib/gtest-ejbs.jar"/>
    <ear destfile="dist/gtest.ear" appxml="etc/application.xml">
      <fileset dir="dist" includes="*.war,*.jar"/>
    </ear>
  </target>
 
</project>

As you can see, this build file contains commands to build not just our Web application, but also our J2EE application. You will have to edit the one <property> tag at the top of the build file for your purposes. Make sure it points to the Geronimo binary installation directory. In my case, it points to the symbolic link I just created.

For now, we want only a simple war file. So, type the following (make sure you are in $GERONIMO_DEVEL):

 ant war

This command creates a file called gtest.war in the dist subdirectory. It should not produce an error, since no compilation is involved.

Run the Web application

Finally we can fire up Geronimo! We need two terminal or command windows to do this. In one, go to $GERONIMO_HOME and type:

 java -jar bin/server.jar

You'll see a bunch of messages spilling onto your screen eventually followed by the message Server startup completed. This tells you Geronimo is now running. If you want to stop the server, just hit Ctrl-C. (Yes, I too am hoping a more elegant stop mechanism is coming!) You might only encounter problems if you have a servlet container (like Tomcat) running on port 8080 or an RMI (remote method invocation) server running on port 1099. These are both ports that Geronimo uses, and it can't start if they are in use.

In the second terminal or command window, also go to $GERONIMO_HOME. We now install our Web application. This command is:

 java -jar bin/deployer.jar --user system --password manager deploy
$GERONIMO_DEVEL/dist/gtest.war

This command requires some explanation. First of all, we are using the Geronimo deployer, which has many deployment commands:

  • deploy: Install and start a component
  • distribute: Install a component
  • list-modules: List installed modules
  • redeploy: Redeploy an already installed component
  • start: Start a component
  • stop: Stop a component
  • undeploy: Stop and uninstall a component

The deploy command we use is essentially the combination of the distribute and start commands.

When you use the deployer, you must provide an administration login, which we do on the command line. If you don't supply it there, the deployer will ask you for it. The login I use here comes with Geronimo by default. What is really cool about Geronimo is that you don't have to specify the kind of component you are installing: the deployer figures it out. In our first use of this tool, we just give it our .war file and the deployer will deploy the file as a Web application.

Once you run the deploy command, you should receive the response:

 Deployed GeronimoTestWebApp

Go back to your first terminal window and check out the message that just popped up:

 07:16:59,814 INFO  [LocalConfigStore:config-store] Installed configuration GeronimoTestWebApp in location 26
07:16:59,929 INFO  [ConfigurationManagerImpl] Loaded Configuration geronimo.config:name="GeronimoTestWebApp"
07:17:00,053 INFO  [Configuration] Started configuration GeronimoTestWebApp
07:17:00,471 INFO  [Container] Started org.mortbay.jetty.servlet.WebApplicationHandler@1cd022c
07:17:00,472 INFO  [GeronimoTestWebApp] JSR154 unwrappedDispatchSupported=true
07:17:00,477 INFO  [JettyWebAppContext] JettyWebAppContext started
07:17:00,478 INFO  [Container] Started WebApplicationContext[/GeronimoTestWebApp,GeronimoTestWebApp]

This message says that Geronimo has deployed the application, or configuration, called GeronimoTestWebApp. Geronimo has installed it in a numbered location—26 in this example, but yours will differ. It then tells us that the Web application has started in Jetty and is available under the URI-base of /GeronimoTestWebApp.

After all this work, it is time to be rewarded with some output! Point your browser to http://[server]:8080/GeronimoTestWebApp where "[server]" refers to the machine on which you installed Geronimo. Figure 1 shows the output I received:

Figure 1. Our first Web application in Geronimo. Click on thumbnail to view full-sized image.
1 2 3 Page 1