Level: Intermediate Sing Li (westmakaha@yahoo.com), Freelance writer, Wrox Press
07 Jun 2005 Geronimo is a server-side workhorse, running JSPs, servlets, EJBs, and databases, queuing, and performing other services. On the client side, Geronimo offers a client application container that can ease the design and coding of your client applications. This article gives you a close look at the role of this container and shows you how to create a Geronimo client with or without container support.
Geronimo applications are usually Web based. The Jetty and Tomcat engines, part of Geronimo, support Web-based user interfaces created with JavaServer Pages, JavaServer Faces, servlets, and other templating technology or frameworks. Users typically access the application using a standard Web browser. Web applications accessed through browsers are often called thin-client solutions.
In many situations, however, Web-based user interfaces might not be appropriate. In these cases, code can be created using a GUI library (such as AWT, Swing, or SWT) on the client side. These client applications, often called fat-client solutions, still access business-tier EJBs and EIS-tier services hosted by Geronimo, like their thin-client counterparts.
This article introduces you to the Geronimo client application container -- a J2EE 1.4 component that can significantly reduce the complexity of creating fat-client solutions.
You'll learn about the role of the client application container within Geronimo's architecture.
A hands-on example shows you how to create and deploy client applications with the container. In addition, this article explores the possibility of creating a stand-alone application that accesses Geronimo-hosted EJBs without using the client container.
The role of the client application container
The Geronimo client application container provides a standard J2EE environment for
client-side application code. This client-side programming environment resembles the server-side environment. However, unlike server-side J2EE modules, which execute in a managed environment within the Geronimo server, client applications execute independently in an unmanaged environment. The client application container extends some of the J2EE APIs and services for the use of client applications, but does not provide any component management or hosting facility. Figure 1 shows the client application container in action.
Figure 1: The Geronimo client application container in action

Figure 1 shows two client machines with applications accessing a single Geronimo server. Users on these machines can access hosted Web applications using a standard Web browser. Also, each client machine has a Geronimo fat-client application executing inside the client application container. These fat-client applications can present a simple command-line user interface, or, more typically, they contain a rich user interface created using popular client-side GUI technology. These applications can access the Web tier by connecting back to the server using their own HTTP connections, or they can access business and EIS tier objects through the help of the Geronimo client application container.
From Figure 1, you can see that the Geronimo client application container:
- Is physically separate from the Geronimo server
- Runs in an independent Java™ VM (or physical machine) than the server
- Provides a wrapper around the client application
- Communicates with the Geronimo server over the network
- Has an intimate working relationship with the server, providing transparent reference resolution, mapping, and dependency management for the client application
The possible world of J2EE client solutions includes thin clients, fat clients, and other
alternative client-side access technology. This article focuses only on the fat-client solutions. See the sidebar Alternative client-side access technology for other possible solutions.
 |
Alternative client-side access technology
Of course, other than Java clients with rich GUI, other technology exists for the implementation of user interface on client applications. For example, a Web browser can present a Java Applet-based user interface that accesses server resources, or Java Web Start can download and run complete client application from a single URL. Geronimo supports these implementations using standard protocols, such as HTTP, HTTPS, CORBA, and RMI. The client application container does not play any part in these alternative solutions.
|
|
Using the Geronimo client application container when you write the client-side Java application, you simply reference any business tier object as if you were coding on the server.
For example, you can reference EJBs hosted on the server using the same JNDI context as if you were coding a Web application on the server-side (as long as the deployer has mapped the EJB to the same name in the deployment descriptor). The Geronimo client application container resolves your EJB reference and accesses the EJB remotely, transparent to you. Figure 2 illustrates how the client application container simplifies client application coding.
Figure 2. Client application container providing seamless access to server-side objects

 |
Other container services
Together with the server, the client container extends a variety of other services to the
client application (see the dashed box in Figure 2). Some examples include security services, such as login/authentication, server-side dependencies management, activation services for Message-Driven Beans, and Web services lookup. These services and their details are outside the scope of this article but may be covered in future articles.
|
|
In Figure 2, you can see that the client application container provides a reference resolution and mapping layer with JNDI. This layer provides seamless access to server-side objects, such as EJBs. Underneath the hood, the client application container can communicate with the server using any supported protocol and transport, such as JRMP or IIOP. The client application hosted within the container doesn't need to be concerned with these details. In fact, an application deployer can change the JNDI name mapping and client/server communications details at deployment time, all without the need to modify the application.
In addition to the EJB mapping, the client application container provides other services to the client application. See the sidebar Other client container services for more information.
Client application packaging
While servlets and JSPs are packaged in Web ARchive (WAR) files, and EJBs are packaged in EJB JAR files, J2EE client applications are packaged in client application JAR files. Conveniently, client application JAR files can be placed within the same Enterprise ARchive (EAR) file with the associated WAR, EJB JAR, and RAR files for the same enterprise application . You can have multiple client application JAR files in a single EAR file. Having everything in one EAR file makes distribution, deployment, and maintenance straightforward.
For example, you can deploy the EAR on the server to start all the EJBs and Web tier components, and then deploy the same EAR on a client application container and select a client application to start. Figure 3 shows the packaging of a client application JAR file
within an EAR.
Figure 3. Packaging client application archives in an EAR file
Client deployment descriptor and deployment plans
The article "Geronimo! Part 2: Tame this J2EE 1.4 bronco" (developerWorks, May 2005) reveals that deployed WAR and EJB JAR files in Geronimo must include an associated J2EE standard deployment descriptor and, optionally, a Geronimo-specific deployment plan. The deployment of client application archives using the client application container also follows this general pattern. Table 1 describes the required deployment descriptor and optional deployment plan.
Table 1. Deployment descriptors and plans for Geronimo client application archives
|
File name
|
Required?
|
Description
| |
application-client.xml | Yes | Standard J2EE deployment descriptor | |
geronimo-application-client.xml
| No, Geronimo will use default |
Geronimo-specific deployment plan |
As noted in Table 1, if you do not include a geronimo-application-client.xml in your archive, Geronimo uses a default. The default works in most cases, unless you have special server-side dependencies, security, or resource adapter requirements.
Stand-alone Geronimo client
Despite the versatility of the Geronimo client application container, you might encounter some circumstances where its use isn't desirable. For instance, the actual client application might be part of an existing large, monolithic legacy system that cannot be readily separated and archived. In such cases, it might be necessary to create a client application without the help of the client container. This can be done quite easily with Geronimo.
Figure 4 illustrates the operation of a stand-alone Geronimo client application working without the client application container.
Figure 4. Stand-alone client application operation
Without assistance from the client container, the stand-alone Java application must explicitly configure the JNDI transports and communications protocol to match those used by the Geronimo server instance. If configuration of the server changes, this application code must be modified. Because the application will need access to EJBs and Geronimo communication protocols, the libraries containing the support classes must be included. Because there is no client application container, any additional service extended by the container will not be available to the application. While not the preferred way of creating clients, a stand-alone client often might be the only feasible solution.
The following hands-on example shows you how to code an application client, first using the Geronimo client application container, then as a stand-alone application client.
A GUI client example
This example is from the Really Big Pet Store example used in "Geronimo! Part 2: Tame this J2EE 1.4 bronco". You will be adding a simple GUI client to the enterprise application. This simple Swing-based GUI client application will access the CMP2 entity EJB in the business tier and display all the pet store product categories.
The entity EJB, called CategoryBean, represents a product category. Corresponding categories data is stored in an RDBMS at the EIS tier. See the original article for information on setting up the JDBC connector and the RDBMS. Figure 5 looks under the hood of this version of the Really Big Pet Store application:
Figure 5. Structure and data flow of a GUI client application
As shown in Figure 5, the GUI client called CatClient resides within the client application container. It access the CategoryBean CMP2 EJB in the server and calls its findAll() method to obtain a list of product categories. Note that the StoreController servlet from the original Really Big Pet Store Web application, hosted by Jetty in the Web tier, also accesses the CategoryBean EJB through a stateless session local EJB named CategoriesBean.
There will be two versions of this client application.
- The first version runs inside the Geronimo client application container and makes use of its EJB mapping facility (as shown in Figure 5).
- The second version is a stand-alone version of the same application. It accesses the Geronimo server directly and does not use the client application container.
Coding the GUI client
The first version of the example is archived in an EAR file named reallybigpet.ear, found in the dist directory of the code distribution. Before you can deploy this EAR, make sure you consult the original article (see Resources) and the README files to set up the required JDBC connector and RDBMS tables.
The CatClient client application is packaged in its own JAR file, called bigpetstore-clientapp.jar. This JAR file is part of the EAR file. The standard J2EE deployment descriptor for this client archive is application-client.xml, shown in Listing 1. This descriptor is placed in the META-INF directory of the JAR file.
Listing 1. client-application.xml for the CatClient application
<?xml version="1.0"?>
<!--DOCTYPE application-client PUBLIC
"-//Sun Microsystems, Inc.//DTD J2EE Application Client 1.2//EN"
"http://java.sun.com/j2ee/dtds/application-client_1_2.dtd"-->
<application-client 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/application-client_1_4.xsd"
version="1.4">
<display-name>dW Geronimo Application Client Example</display-name>
<ejb-ref>
<ejb-ref-name>ejb/CategoryEntityBean</ejb-ref-name>
<ejb-ref-type>Entity</ejb-ref-type>
<home>com.ibm.dw.reallybigpet.ejb.cmp.CategoryHome</home>
<remote>com.ibm.dw.reallybigpet.ejb.cmp.CategoryRemote</remote>
</ejb-ref>
</application-client>
|
In Listing 1, a reference to the server-side entity EJB is specified in the deployment descriptor. The Geronimo server will locate the actual EJB based on the home and remote interface and the EJB type specified. The reference name for this EJB is mapped to ejb/CategoryEntityBean. This mapping can be configured by a deployer during deployment time. This extra level of mapping allows a client application to be developed using fixed-reference names and flexibly map to actual EJBs at the deployment time.
The client application container needs to know which class in the client application JAR is the class to start. You, therefore, need to make sure that the manifest of the client application JAR file has a main class: entry. In this case, the main class specified in the META-INF/MANIFEST.MF file is com.ibm.dw.reallybigpet.client.CatClient:
Main-Class: com.ibm.dw.reallybigpet.client.CatClient
|
bigpetstore-clientapp.jar does not include a Geronimo-specific deployment plan -- the client application does not need one. The default plan provided by Geronimo is adequate.
JNDI access to remote EJBs using client application container
In the actual client code, CatClient.java, the code accesses the EJB using these steps:
- Obtain a JNDI initial context, supplied by the client application container
- Look up the context java:comp/env, and then the entry ejb/CategoryEntityBean (note that this entry corresponds to the mapped name ejb/CategoryEntityBean from Listing 1)
- Use the
PortableRemoteObject.narrow() method to narrow the returned remote object to the type of EJB home interface
- Use the EJB home interface to create or fetch instances of EJBs, in the same manner as server-side EJB programming
Listing 2 shows the code for CatClient.java. This class has a Swing-based GUI that will display all the product categories available in the Really Big Pet Store. You will find the EJB lookup code in the getCats() method within CatClient.java in Listing 2.
In Listing 2, the getCats() method invokes the findAll() method on the EJB's home interface and iterates through the returned CategoryRemote remote instances to obtain their ids and names. This information is placed into a Vector. This Vector is used in the init() method to initialize a Swing JList for the GUI. This JList displays the categories information to the end user.
Creating the client application configuration
Now you can try out CatClient using the client application container. With the server running, make sure that you have undeployed any reallybigpet configurations from previous runs of the examples (use the deployer's list-modules command to see the deployed configurations). Also make sure that you have the PetsDB configuration (JDBC connector) deployed and running.
Deploy the reallybigpet.ear file, containing the server-side EJB and the client application JAR, using the command:
java -jar bin\deployer.jar deploy reallybigpet.ear
|
The deployer tool prompts you for user and password. Use system for user and manager for password.
To see the currently deployed configurations, use the deployer's list-module command:
java -jar bin\deployer.jar list-modules
|
You should see the system configurations, together with the server-side reallybigpet configuration and the client application configuration, as shown below. The client application configuration is shown in bold:
Found 22 modules
org/apache/geronimo/Tomcat
org/apache/geronimo/ActiveMQServer
org/apache/geronimo/J2EEDeployer
org/apache/geronimo/DefaultDatabase
org/apache/geronimo/SpringDeployer
org/apache/geronimo/Secure
org/apache/geronimo/DebugConsole
org/apache/geronimo/Server
org/apache/geronimo/DeployerSystem
org/apache/geronimo/ClientSystem
org/apache/geronimo/SystemDatabase
org/apache/geronimo/Client
org/apache/geronimo/Demo
org/apache/geronimo/SpringRuntime
PetsDB
org/apache/geronimo/InteropServer
org/apache/geronimo/SystemJMS
reallybigpet/bigpetstore-clientapp
reallybigpet
org/apache/geronimo/RuntimeDeployer
org/apache/geronimo/System
org/apache/geronimo/RemoteClassLoadingDeployer
|
Because a Geronimo-specific deployment plan is not included with the client application JAR file, Geronimo used a default name for the client configuration. This name is constructed using the name of the deployed EAR file, put together with the name of the client application JAR file. In this case, the client configuration is named reallybigpet/bigpetstore-clientapp.
Running the client application container
The code for the client application container is located in bin/client.jar. To deploy the CatClient application using the container, start the client application container with the client configuration name as argument:
java -jar bin/client.jar reallybigpet/bigpetstore-clientapp
|
When you run the CatClient application, you should see a Swing GUI with a list showing all the categories for the Really Big Pet Store (see Figure 6).
Figure 6: CatClient displaying categories from CMP entity EJB
In Figure 6, the Swing JList displays the names of the product categories at their associated ids. For example, the highlighted category with id 2 is the Clearance category. If you want, you can update the petcats table in your RDBMS, and the updates will appear in the JList when you start the application again.
Coding a stand-alone client
Without the support of the client application container, a stand-alone client must perform its own JNDI lookup for the server-side entity EJB. Listing 3 shows the getCats() method from the stand-alone client, CatClientStandalone.java.
In Listing 3, the JNDI initial context is fabricated using a custom context factory (an OpenEJB specific wrapper), called org.openejb.client.RemoteInitialContextFactory. The URL connects to the local machine at port 4201, which is the EJB network server's port (see the sidebar About Geronimo development builds for more information on development build restrictions). The default authentication information for the current build is testuser:testpassword respectively.
 |
About Geronimo development builds
The example in this article works with the latest unstable build and has been tested
on SVN build 179212 (05/31/05), as well as 169186. The primary purpose for the latest unstable build is to facilitate development and testing. As such, the provider URL information for JNDI is set to access the local machine only (for easy testing). The default security policy also only accepts EJB protocol connections from the local machine. This restricts client
testing to a loop-back setup -- unless you reconfigure and rebuild the server. In future
Geronimo releases, these restrictions may be lifted.
|
|
Making do without the client application container
Because the client application container is not available, the setup for the java:comp/env context is not performed. In addition, because there is no reference mapping layer, you must specify the raw JNDI name of the remote EJB. The JNDI name for the EJB in Listing 3 is CategoryBean. You can set up the raw JNDI name used by Geronimo on the server by specifying a <jndi-name> element for the EJB. This element is specified within an <entity>sub-element of the <enterprise-beans> element in the Geronimo-specific openejb-jar.xml deployment plan for the entity EJB.
Without client application container support, you need to explicitly include any Geronimo or EJB classes that are referenced directly or indirectly. This can be quite an extensive list. For the CatClientStandalone client, the required library JAR files include:
- openejb-core-2.0-SNAPSHOT.jar
- geronimo-spec-j2ee-1.4-rc4.jar
- geronimo-kernel-1.0-SNAPSHOT.jar
- geronimo-security-1.0-SNAPSHOT.jar
- cglib-nodep-2.1.jar
You will need all of the above JAR files, found in the Geronimo repository and the lib directory, as well as EJB interface classes, such as CategoryHome and CategoryRemote. The source code distribution (see Resources) has an ant target called sajar that will create a standalone-clientapp.jar file, bundling the stand-alone client application with the EJB interfaces. There is also a run.bat batch file in the standalone subdirectory that will set up the classpath to access the dependent library JAR files. This batch file contains:
java -cp ./standalone-clientapp.jar;lib/openejb-core-2.0-SNAPSHOT.jar;
lib/geronimo-spec-j2ee-1.4-rc4.jar;lib/geronimo-kernel-1.0-SNAPSHOT.jar;
lib/cglib-nodep-2.1.jar;lib/geronimo-security-1.0-SNAPSHOT.jar
com.ibm.dw.reallybigpet.client.CatClientStandalone
|
Note that this batch file starts the com.ibm.dw.reallybigpet.client.CatClientStandalone class directly, and does not invoke the bin\client.jar client application container.
Testing the stand-alone client application
You must ensure that all the dependent JAR files are copied into the standalone\lib directory before the batch file will work properly.
To try out the stand-alone client, use the run.bat batch file. This starts the client, displaying the product categories from the entity EJB. The resulting display is identical to Figure 6.
Conclusion
The Geronimo client application container extends the J2EE application development environment to client-side applications. You can save substantial development effort and enjoy the flexible deployment time control of a J2EE 1.4 container by using it. In situations where the client application container cannot be used, you can still use the Geronimo libraries to code stand-alone client applications to access business tier objects on a Geronimo server.
Download | Description | Name | Size | Download method |
|---|
| Sample code tested on Geronimo build 179212 | code.zip | 1.3MB | HTTP |
|---|
Resources
- Take a look at the two-part series on Geronimo. Part 1, "The J2EE 1.4 engine that could" (developerWorks, May 2005) is an introduction to and conceptual overview for Geronimo, while Part 2, "Tame this J2EE 1.4 bronco" (developerWorks, May 2005) covers Geronimo configuration, deployment, and management and provides hands-on examples of deploying Web applications and EJBs.
- The developerWorks Apache Geronimo project area provides resources for Geronimo developers.
- The official site for the Geronimo project has the latest source code and binaries, and an active community on the mailing lists and wiki.
- Learn about and download Gluecode SE, a Java-certified, production-grade platform built on the Apache Geronimo application server.
- Jetty is the default servlet and JSP container integrated with Geronimo. Visit the official Jetty site for more information.
- Tomcat is the alternate servlet and JSP container for Geronimo. Discover Tomcat at the official Tomcat Web site.
- The EJB container in Geronimo is OpenEJB. Explore the OpenEJB project for more information on its capabilities.
- The default relational database service and JDBC provider for Geronimo is the Derby project. See the Derby project Web site for manuals, source code, and an active user community on the mailing lists.
- Get involved in the developerWorks community by participating in developerWorks blogs.
About the author
Rate this page
|