HomeDocumentation > Apache Geronimo v1.0 - Developer's Guide > Do it yourself (A self-built Geronimo-based Application Server)
{scrollbar}

Do it yourself - Apache Geronimo, Part II: A self-built Geronimo-based Java Magazin Application Server

by Christian Dedek and Kristian Köhler, published in Java Magazin 6.2006, translated and edited by Marcel Ackermann

Our own application server? Geronimo makes it possible. Building an own server distribution seems redundant, but on a closer look an optimised execution platform does make sense for the own application. We present the process of packing our own Geronimo-based server distribution. The source code of our Java Magazin application server can be downloaded from http://www.oio.de/public/geronimo/jm-artikel.

The first part of this series of articles concentrated on the basic architecture of the Geronimo application server. As well as the administration and installation of the server, its usage as a Java EE-conform application server was presented. We put emphasis on the deployment of Java EE-application archives and the principle server architecture.
As shown, Geronimo works configuration based. Geronimo-server components are administered as configurations on the server like own applications. The configurations compose the range of functions. Building a server distribution is bounded to the combination of configurations, which define the functions. The underlying Apache Software License and the available tools make it easy to set up a Geronimo-based distribution. The Apache Software Foundation's revision control provides the following server distributions:

  • Java EE Jetty: Java EE-conform server with preconfigured Jetty-Web-Container
  • Java EE Tomcat: Java EE-conform server with preconfigured Tomcat-Web-Container
  • Minimal Tomcat: Distribution with pure Web-Container-support
  • Web JMS Tomcat Server: Distribution with Web-Container and JMS-support
  • Java EE Installer: Self-extracting installer archive for a Java EE-conform server with configurable range of functions.

As shown in the first part of the series, some corporations already use the advantages of an own server distribution for commercial scenarios. The best example is certainly IBM, who position with the WebSphere Application Server Community Edition a Geronimo-based Java EE-conform application server as standalone product for small- and medium-sized companies.
Building an own distribution does not only volunteer for the heavyweights of the IT-sector, in contrast, the Geronimo can be fitted in its range of functions to the own application, so it runs in an optimised server environment. For example you must not activate the configuration for EJB-support if you do not use any EJBs on your server.
A Geronimo-based product distribution can combine an optimised server distribution with installed applications. Examples of optimised server distributions are:

  • pure Java EE-Web-Container with process-internal database
  • EAI-server from a JMS-implementation, database and routing engine
  • Web Service Engine zur generischen Bereitstellung vorhandener Dienste innerhalb einer serviceorientierten Architektur
  • server with functionality for Spring Deployment
  • portal server from JSR 168-conform portlet-container and content management system
    Installable applications could be standard Java EE-archives (EAR, WAR, RAR ...) as well as own application formats (encrypted ZIP ...).

The construction plan

It is possible to create complex structures out of simple modules, as packing a distribution follows the module principle. In the first step the simple components are manufactured. In this picture a component corresponds to a Geronimo configuration. Necessary services and functions of the optimised server environment as well as the integrated applications must be provided as configurations. The size and extent of a component are to be determined by the developer in this case. E.g. by defining a database binding in form of its own configuration, one receives a small, easily re-usable unit. If the same database binding is integrated into a more complex configuration, a larger component results, featuring a larger range of functions.
In the second step of manufacturing the components are arranged to the final product distribution. The type and origin of the components do not play a role for the process of building up.
In the following section the production of own components is demonstrated. First its own service for an optimised server environment is presented. As the second component a Java EE-conform application serves. Both components are arranged in the connection as well as further configurations to their own Geronimo based product.

The own module

In the first article we got to know the basic architecture of the Geronimo. Thereby the GBeans are elementary. They are the smallest manageable unit within the server. So an own service is also integrated by at least one GBean into the server. The task of the GBean is the definition and supply of the administration and configuration interface between the service and the application server. The Geronimo kernel does not differentiate between Java EE-Application-components and proprietary services. The GBeans of a configuration are stored on the server in the ConfigStore. In our metaphor it represents the construction kit for the keeping of the components (see box ConfigStore).

ConfigStore

Configurations are administered in the Geronimo kernel by objects of the type Configuration Store, here briefly ConfigStore. The ConfigStore offers installing, loading, searching and deinstalling of configurations, which are addressed by their clear configId. The data of a configuration are exchanged between ConfigStore and Geronimo kernel in the form of ConfigurationData-objects. The CAR archive file format is defined for the durable storage of the configurations. Thereby one CAR archive contains exactly one configuration. Whilst a ConfigStore does not differentiate whether the CAR archive contains Java EE-components or its own Geronimo services. The standard implementation of the ConfigStore uses the local file system to store all configuration data. Configurations are stored in separate subdirectories of the folder config-store. These directories contain the content of an unpacked CAR archive.

The actual implementation of an own service can be done without special consideration of the application server. The integration can be accomplished later by the supply of one or more GBeans. Here our example of the development and integration of a GBean sets. The administrative interface between Geronimo and its service is represented as simply as possible by a string field serviceName. The only task of the GBeans is the implementation of the method getGBeanInfo(), which returns a GBeanInfo object for the description of the interface. Instead of producing the meta data object manually, the class GBeanInfoBuilder can be applied to simplify the implementation of the Builder Patterns (Erich Gamma et al.: Entwurfsmuster, Addison-Wesley, 1996, 119 ff.). Furthermore the GBean in the example uses the possibility of supplying its own service with signals from the life cycle management of the application server. Therefore the interface GBeanLifeCycle is implemented with the methods doStart(), doStop() and doFail() (listing 1).

Listing 1 GBean Examplepublic class BeispielGBean implements GBeanLifecycle { private String serviceName; public String getServiceName() { return serviceName; } public void setServiceName(String serviceName) { this.name = serviceName; } public static final GBeanInfo GBEAN_INFO; static { GBeanInfoBuilder builder = new GBeanInfoBuilder(BeispielGBean.class); builder.addAttribute("serviceName", String.class, true); GBEAN_INFO = builder.getBeanInfo(); } public static GBeanInfo getGBeanInfo() { return GBEAN_INFO; } public void doStart() throws Exception { System.out.println("doStart "); } public void doStop() throws Exception { System.out.println("doStop "); } public void doFail() { } }

For the registration and concrete configuration of the GBeans, the Geronimo uses the same mechanism as with the deployment of Java EE standard components. Similar to the JSR 88, the deployment plans describe the environment settings of all GBeans of one configuration in the form of a XML file. So a deployment plan must be arranged for our example, which describes the GBean and its binding to the server (listing 2).

Listing 2 Deployment plan of the GBean example<?xml version="1.0"?> <configuration xmlns="http://geronimo.apache.org/xml/ns/deployment-1.0" configId="de/oio/gbean-sample/1.0"> <dependency> <groupId>de.oio.geronimo</groupId> <artifactId>gBeanBeispiel</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <gbean name="OIOSample" class="de.oio.geronimo.SampleGBean"> <attribute name="serviceName">Kristian</attribute> </gbean> </configuration>

A configuration is described by an element called configuration. It must contain at least one unique value within the server environment for the attribute configID to identify the configuration. A GBean is defined by the element gbean. By means of the attributes name and class a unique name within the configuration, as well as the implementation class of the GBean, is determined. Through an attribute element an attribute of the management interface of the GBean can be initialized by dependecy injection. The implementation class of the GBean and the associated classes of the service are put to the Geronimo server over a repository at the disposal. With dependency elements references in the deployment plan to archives, which contain these classes, are arranged (see box repository).

Repository

The Geronimo administers all libraries the server needs within a repository. Configurations can share libraries through the repository. These do not have to be kept redundant in each configuration. However configurations thereby get run time dependent and can only be executed in a server with suitable repository. The structure is ajar against Maven. Resources in the repository are referenced by a clear identifier from four components.

  • groupID: The short name of the related group. Several JAR archives from one supplier are bundled in a group.
  • type: The file type corresponds to the file extension. For libraries JAR is used.
  • artifactID: The short name of the file. Within a group individual libraries are differentiated by their artifactID.
  • version: Version number of the file
    The standard repository implementation stores the files inside the repository folder. The appropriate file name is made up here as follows: <groupId>/<type>s/<artifactId>-<version>.<type>. A reference to the file de.geronimo/jars/gBeanBeispiel-1.0-SNAPSHOT.jar within the repository directory of an Geronimo installation then has the following form within a deployment plan:
xml<groupId>de.oio.geronimo</groupId> <artifactId>gBeanBeispiel</artifactId> <version>1.0-SNAPSHOT</version>

To complete the first component the CAR archive must be created. For this purpose the Maven-based packaging plugin can be used. Geronimo 1.0 uses a plugin for Maven 1; version 1.1 of Geronimo is extended by a plugin for Maven 2. An alternative tool support by Ant is in planning.
A deployment at run-time would be a fundamental alternative with the production of CAR archives. However an existing Geronimo distribution must be started, that is why we do not continue dealing with this possibility here.
If the GBean implementation is located in a Maven 1 based project you can apply the following code snippet, the packaging plugin can be called after the compilation of the project. The resulting CAR file is copied automatically into the Maven repository.

xml<project default="default"> <goal name="default"> <attainGoal name="car:install"/> </goal> </project>

The plugin reverts to the ConfigurationBuilder of the Geronimo core, known from the first article. Thereto a minimum server is started by the plugin, to which the deployment plan is passed. The for the deployment plan responsible builder creates a ConfigurationData object, which is saved as config.ser in the CAR archive.
The own service in the form of the CAR archive is the first finished component and can be used as a part of an optimized server environment in later distributions. All Geronimo components are provided by this mechanism.

The Java EE component

With the Deployment of a Java EE archive a configuration is likewise created. This is also stored by the ConfigStore in form of a CAR file. In the range of the standard deployment we had not dealt more in greater detail with this server characteristic. The deployment plan differs from the deployment plan of the previous component by another root element application. Within the deployment plans equal environment configurations can be defined by GBeans by elements of the same name areas. The server does not differentiate here between GBeans from Java EE-archives and special Geronimo services. The structure of the plan is ajar against a Java EE-standard-deployment-descriptor. The attribute configId again defines a name for the clear identification of the later component. The example makes use of an EAR archive ear-sample-1.0-SNAPSHOT.ear, in which a web application is stored web-sample-1.0-SNAPSHOT.war (listing 3).

Listing 3 Deployment-Plan for an EAR archive<?xml version="1.0" encoding="UTF-8"?> <application xmlns="http://geronimo.apache.org/xml/ns/j2ee/application-1.0" configId="de.oio/geronimo/application/1.0/car"> <module> <web>web-sample-1.0-SNAPSHOT.war</web> <web-app xmlns="http://geronimo.apache.org/xml/ns/j2ee/web/jetty-1.0" configId="Web"> </web-app> </module> </application>

The Maven plugin can also be used to create CAR archives from a Java EE standard archiv. For this a stand-alone Maven project can be set up, with the assistance of which the configuration is provided. The file project.xml contained in it must, as shown in the following source code, be extended by the dependences to the appropriate Java EE-archives. The maven.xml file of the project must contain again the packaging plugin indication. After executing the Maven system here the CAR file also lies in the Maven repository.

xml<dependency> <groupId>de.oio.geronimo</groupId> <artifactId>ear-sample</artifactId> <version>1.0-SNAPSHOT</version> <type>ear</type> </dependency>

The responsible builder of the server core forms the most serious difference to the production of the CAR archive of a server service. For Java of EE-archives, not the ConfigurationBuilder but a ModuleBuilder is responsible. It evaluates the deployment plan and provides the appropriate ConfigurationData-object. The Geronimo kernel selects the correct builder transparently for the user. The ModuleBuilder is thereby needed only for the evaluation of the deployment plan. An existing configuration within the ConfigStore does not need a ModuleBuilder for its use. Removing the ModuleBulder results in a distribution without deployment possibility for Java EE-archives. A Java EE-application in the form of a CAR archive represents an already valid configuration. Such a component is also applicable in a distribution without Java EE deployment.

Stein auf Stein

Building the individual components up can take place by means of the Maven Geronimo assembly plugin. The plugin is used as well within the Geronimo project for packing the offered server distributions.
Each server distribution should be created as a separate Maven project. In the appropriate project.xml file all necessary components must be registered as dependences. This extends from the Geronimo kernel to the start and stop scripts of the server. Own applications must be indicated in this connection, too. The following source code shows an extract of the file. In this example Jetty is taken up as a configuration to the server. The CAR file from the Maven repository is installed by the assembly plugin in the ConfigStore and is consequently available in the server.

xml<dependency> <groupId>geronimo</groupId> <artifactId>jetty</artifactId> <type>car</type> <version>1.2-SNAPSHOT</version> <properties> <geronimo.assemble>install</geronimo.assemble> </properties> </dependency> ...

All integrated configurations must be available as CAR archives. These dependences can be dissolved either by the local or over a remote Maven repository. You can find the configurations for Geronimo 1.0 among others on http://www.ibiblio.org/maven/geronimo/cars/. This makes an assembly of a Geronimo server possible without compiling the Geronimo sources itself.
Inside the src-directory further files, which are also copied into the distribution, can be deposited. The config.xml should be stored in var/config. When the server starts, this file gets evaluated in order to select the start configuration, as addressed in the last article. It should also contain the configurations which can be started from its own distribution.
The integration of the Maven plugin into the project can be achieved by the the following XML block in the file maven.xml.

xml<project default="default"> <goal name="default" prereqs="assemble:install"/> </project>

After the successful execution of Maven one finds the own server distribution as TAR.GZ and ZIP archive in the target folder of the project. The name of the distribution is defined by the Maven property geronimo.assembly.name. Illustration 1 shows the console output of the offered assembled Java Magazin-server after the successful server start with the startup-script.

The Master Craftsman certificate

In the product distribution described so far Java EE-application archives are stored in the standard implementation of the ConfigStore. Different requirements of the software distribution of a product cannot be modeled with this standard mechanism. The architecture of the server however permits the exchange of the ConfigStore implementation to realize different distribution scenarios. The following scenarios are e.g. imaginable:

  • central distribution server
  • central license mechanism based on application components
  • farming of clustered applications
  • encryption of application archives
    The sources of such a server extension do not have to inherit the open-source-license. (...) In the following, we point out how an additional ConfigStore can be created and integrated in the server.

Own construction kit

Apart from the normal requirements to a GBean the own ConfigStore has to implement the interface org.apache.geronimo.kernel.config.ConfigurationStore. The interface contains methods to install, load, search and uninstall configurations. These are addressed here by their clear configId and passed in the form of ConfigurationData-objects. For storing the configurations, ConfigurationData-objects can be serialized by Geronimo helper classes quite easily.

ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); GBeanData configurationGBeanData = ExecutableConfigurationUtil.getConfigurationGBeanData(configurationData); configurationGBeanData.writeExternal(oos); byte[] bites = baos.toByteArray(); //save with possible encryption

In the methods to load the configuration, license examinations could be integrated, which would examine whether a configuration can be loaded in this ConfigStore or not. Since the ConfigStore implementation is a GBean, the method getGBeanInfo must be provided. This can be done with the class GBeanInfoBuilder as shown in the following example.

GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic(AlternativeConfigStoreImpl.class, "ConfigurationStore");

The most important value in this example is the second parameter in the call of the method createStatic. It concerns here the indication of the Java EE-type ConfigurationStore, which is reflected in the unique name (see box ObjectNameGroup) of the GBeans, under! which it is registered at the server.

ObjectNameGroup

With an ObjectNameGroup a GBean installed in the Geronimo can be referenced clearly. The group consists of several components, whose individual names lean against the Java EE-management-specification (JSR 77).

  • domain
  • server
  • application
  • module
  • type
  • name
    The ObjectNameGroup is modelled again on a JMX ObjectName, by which the GBean is registered at the JMX MBeanServer. The name of the ObjectNameGroup Domain is mapped here on the JMX ObjectName Domain. The further name components are indicated as "key property list" of the JMX ObjectName. Example of a resulting JMX ObjectName: geronimo.server:EJBModule=daytrader-ejb-1.2-SNAPSHOT.jar,J2EEApplication=geronimo/ daytrader-derby-tomcat/1.2-SNAPSHOT/car,J2EEServer=geronimo,j2eeType= EntityBean,name=AccountEJB

The dependency injection mechanism for GBeans within Geronimo supports not only a static reference to an individual GBean but also the definition of a reference to a quantity of GBeans. With this mechanism a GBean can announce interest in further GBeans. If an appropriate GBean is started and/or stopped again, a reference is set via dependency injection. The indication of the target Bean is made by a name pattern, which can contain parts of the ObjectNameGroup. The indication of :j2eeType=WebModule, e.g. represents a reference indication to all GBeans with a j2eeType-web module. In this way the web container can let itself being informed of newly installed web modules to react accordingly. A direct reference between installation mechanism and execution environment is not necessary.
In the standard configuration of Geronimo the ConfigurationManager administers all ConfigStore instances in this way. It lets inform itself over the start and/or stopping of all GBeans, which have the type ConfigurationStore (listing 4).
By the Java EE-type-indication provided on the creation of the GBeanData-object, shown above, within the own ConfigStore implementation the GBean has the type ConfigurationStore. By Starting the Bean, the ConfigurationManager is informed accordingly about it. A further registration of the ConfigStore is not necessary.

Listing 4 Deployment plan - snippet for ConfigurationManager<!-- Configuration Manager service --> <gbean name="ConfigurationManager" class="org.apache.geronimo.kernel.config.EditableConfigurationManagerImpl"> <reference name="Stores"> <gbean-name>*:j2eeType=ConfigurationStore,*</gbean-name> </reference> <reference name="AttributeStore"> <name>AttributeManager</name> </reference> <reference name="PersistentConfigurationList"> <type>AttributeStore</type> <name>AttributeManager</name> </reference> </gbean>

Topping out ceremony

To be able to apply the own ConfigStore GBean in the server, its own configuration for the store must be provided. So, once again the Geronimo Maven 1 packaging plugin can be used. The deployment plan is presented in listing 5. The configuration can be used afterwards by its own assembling of the server. An adjustment of the existing server configurations is not necessary.

Listing 5 Deployment plan for an own ConfigStore<configuration xmlns="http://geronimo.apache.org/xml/ns/deployment-1.0" configId="de.oio.geronimo/alternative-configStore-config/1.0-SNAPSHOT/car" domain="geronimo.server" server="geronimo"> <gbean name="AlternativeConfigStore" class="de.oio.geronimo.config.AlternativeConfigStoreImpl"> </gbean> </configuration>

The moving in

Within Geronimo all ConfigStores are administered as targets. This term originates from the Java EE-application-deployment-specification and designates the available installation targets. These targets of a server can be displayed with the command line tool of Geronimo deploy. The execution of deploy.bat list-targets results in the example:

Available Targets: geronimo.server:J2EEApplication=null,J2EEModule=geronimo/j2ee-system/1.2-SNAPSHOT/car,J2EEServer=geronimo,j2eeType=ConfigurationStore,name=Local geronimo.server:J2EEApplication=null,J2EEModule=de.oio.geronimo/alternative-configStore-config/1.0-SNAPSHOT/car,J2EEServer=geronimo,j2eeType=ConfigurationStore,name=AlternativeConfigStore

The second entry is an own ConfigStore which was registered with the ConfigId de.oio.geronimo/alternative-configStore-config/1.0-SNAPSHOT/car. An output of all in this target installed modules can be obtained with the following call:

deploy.bat list-modules geronimo.server:J2EEApplication=null,J2EEModule=de.oio.geronimo/alternative-configStore-config/1.0-SNAPSHOT/car,J2EEServer=geronimo,j2eeType=ConfigurationStore,name=AlternativeConfigStore

After the construction is before the construction

The integration-oriented software architecture of the Geronimo facilitates the production of an own server distribution. The Java Magazin application server made available on http://www.javamagazin.de/geronimo can be used as a basis for an own product. Have fun with doing it yourself!

Christian Dedek and Kristian Köhler occupy themselves at Orientation in Objects with architecture, development and consulting of Java EE-applications. Contact: geronimo@oio.de. Marcel Ackermann's fields of activity at Orientation in Objects are Java OO development, SWT/Jface/Eclipse RCP, Ajax and Business Intelligence.