ONJava.com    
 Published on ONJava.com (http://www.onjava.com/)
 See this if you're having trouble printing code examples


Developing for Jakarta Avalon

by Jim Alateras
05/29/2002

This article briefly describes the Jakarta Avalon project and defines the steps required to specify, implement, package, and deploy an application for the Jakarta Avalon Phoenix v4.0a4 application server.

What is Avalon?

Avalon was conceived by the Apache JServ team in 1999 as a framework for building server-side components using programming idioms and design patterns such as service oriented programming, inversion of control, and separation of concerns. In its original form, Avalon was distributed as a single piece of component technology, incorporating framework, components, utilities, and kernel. In mid- to late 2001, the project was migrated to Jakarta and separated into a number of modules: Framework, Excalibur, Phoenix, and Cornerstone. In recent times, Avalon has been used as the basis for other core Jakarta technologies, the most prominent of them being Cocoon2 and James.

Avalon is based on a number of core programming idioms and design patterns that promote quality, reusability and maintainability. The principle of inversion of control is that the component is externally managed; and the tenet of separation of concerns is that a component has many concerns, which must be individually addressed (i.e., security, management, configuration). Avalon lends itself to service-oriented programming, the concept of decomposing a system into a number of services and aggregating those services to build more complex services.

Layers Within Avalon

Avalon consists of four core layers, which are described in the following sections. Figure 1 illustrates the relationships between these layers.

Diagram.
  Figure 1.


Framework

This is the basis of all other frameworks and components in Avalon. The framework contains interfaces for composing a set of components, managing a component and its sub-components, and configuration of the components and their sub-components. It also addresses other issues such as threading, context, lifecycle, etc.

The Framework introduces two very important concepts, components and services. A component is a combination of an interface and its implementation. A client of a component always programs to the interface API, allowing the implementation to change without impact. A service, on the other hand, is synthesized from a number of components and controls the lifecycle of the components. A service can be a messaging server, which requires components such as protocol handlers, event managers, thread pooling, and database-connection pooling.

The framework promotes seven contracts: component, activity, configuration, context, logger, parameters, thread, and miscellany. The framework does not dictate which interfaces must be implemented by components. In fact, the only policy that the framework imposes is the component lifecycle and the events that occur within the lifecycle. The lifecycle of a component is divided into three phases -- initialization, activation, and destruction -- and within each phase, a number of events can transpire.

Excalibur

Related Reading

Ant: The Definitive Guide
By Jesse E. Tilly, Eric M. Burke

Excalibur is a library of low-level reusable components (like the command line processor, collection classes, concurrency control (i.e., mutex, synchronization), naming, and thread management) that conform to the Avalon Framework Contracts. The module accommodates both well-established and newly developed components. New components are initially placed in the scratchpad region and transitioned to the staging area once they have stabilized.

Excalibur also provides a default implementation for building containers, reading configuration files, and managing children components. It handles many things under the hood to ensure that components defined in the configuration file are correctly instantiated and the lifecycle contract is correctly managed. Jakarta Cocoon2 is written at the Excalibur layer.

Phoenix

Phoenix provides a lightweight kernel for hosting components or blocks conforming to the Avalon framework. Phoenix is responsible for managing the lifecycle of all specified blocks and provides fundamental services such as class loading, logging, security, and pooling. A number of deployment descriptors are used to dynamically define the various blocks used by the system and their dependencies and configuration.

The Phoenix default manager, or engine, is built around the concepts of the Avalon Framework and uses all of the fundamental design patterns and programming idioms. Additionally, it uses several Excalibur components, including the repository manager, logging facility, and package manager. A JMX MBean server is used to manage the Phoenix kernel and its hosted applications. Clients can connect to the MBean server through the RMI adaptor, which is part of the Phoenix distribution.

Phoenix applications are deployed as SARs (server archives) in a preconfigured directory. The Phoenix kernel is responsible for unpacking and verifying the contents of the archive before running up the application.

Cornerstone

Cornerstone provides a set of common reusable Blocks, which are implementations of services. Applications built for the Phoenix kernel are likely to use many of the blocks present in the Cornerstone repository. Some of the available blocks include the thread pool manager, scheduler, and persistent store.

Developing an Application for Phoenix

This section briefly outlines the steps required to define, develop, package, and deploy an application in the Phoenix environment. The level of abstraction offered by Phoenix and the number of reusable blocks available in the Cornerstone repository provide a high-value proposition for developing server-side components using Avalon.

Step 1: Defining the Service

In Avalon, every component is associated with a role, since components are selected or retrieved by role. The role and the interface for our FxConversion service is defined below.

public interface FxConversion extends Component {
public String ROLE = “com.nuix.avalon.fx.FxConversion”;
public double convert(String in_ccy, String out_ccy, double amount)
throws FxConversionException;
}

Step 2: Implementing the Service

The MyFxConversion class implements the FxConversion interface, in addition to several of the lifecycle and threading interfaces defined by the Avalon Framework. Although not visible, the implementation uses the Scheduler and SocketManager components, which are part of the Cornerstone distribution.

public class MyFxConversion
extends AbstractLogEnabled
implements FxConversion, Configurable, Initializable, Composable {
}

Step 3: Deployment Descriptors

Once the MyFxConversion block has been completed, the deployment descriptors must be compiled. The Phoenix container relies on three deployment descriptors: assembly, config, and environment.

The Assembly File

The assembly file outlines the various components that the Foreign Exchange System requires. Each component specifies its dependencies, as shown below. The Phoenix container uses the information in the assembly file to build a dependency list of components and then to manage the lifecycle of these components.

There are several things worth pointing out; firstly, the provide child element of a block element always specifies the role of the component that it depends upon, not the actual class implementing the role. Secondly, the order that blocks are specified is unimportant for Phoenix to build its dependency list.

The Foreign Exchange application uses some of the blocks (i.e., DefaultThreadManager, DefaultSocketManager, and DefaultTimeScheduler) that are part of Cornerstone distribution.

<assembly>
<!-- The ThreadManager block -->
<block class="org.apache.avalon.cornerstone.blocks.threads.DefaultThreadManager" 
name="thread-manager" />
<!-- The Socket Manager block -->
<block class="org.apache.avalon.cornerstone.blocks.sockets.DefaultSocketManager" 
name="sockets" />
<!-- The TimeScheduler block -->
<block class="org.apache.avalon.cornerstone.blocks.scheduler.DefaultTimeScheduler" 
name="scheduler">
<provide name="thread-manager" 
role="org.apache.avalon.cornerstone.services.threads.ThreadManager" />
</block>
<block class="com.nuix.avalon.fx.MyFxConversion" name="fx-conversion" >
<provide name="sockets" 
role="org.apache.avalon.cornerstone.services.sockets.SocketManager"/>
<provide name="scheduler" 
role="org.apache.avalon.cornerstone.services.scheduler.TimeScheduler"/>
</block> 
</assembly>

The Configuration File

The configuration file, which must be Phoenix-compliant, contains information needed to configure the various system components. Phoenix uses the information in this file during the startup or the reconfigure stages.

A sample configuration file is shown below:

<config>
<thread-manager>
<thread-group>
<name>default</name>
<priority>5</priority> 
<is-daemon>false</is-daemon>
<max-threads>40</max-threads>
<min-threads>20</min-threads>
<min-spare-threads>20</min-spare-threads>
</thread-group>
</thread-manager>
<sockets>
<server-sockets>
<factory name="plain" 
class="org.apache.avalon.cornerstone.blocks.sockets.DefaultServerSocketFactory" />
</server-sockets>
<client-sockets>
<factory name="plain" 
class="org.apache.avalon.cornerstone.blocks.sockets.DefaultSocketFactory" />
</client-sockets>
</sockets>
<!-- this section is specific to the the MyFxConversion Block -->
<fxconversion-server>
<port>4556</port>
</fxconversion-server>
</config>

The Environment File

The environment file is used to specify server-wide settings like the security policy or the logging settings. An example of such a file is shown below.

<environment>
<logs>
<category name="" target="default" priority="DEBUG" />
<category name="objectstorage" target="objectstorage-target" priority="DEBUG" />
<category name="eca-server" target="simple-server" priority="DEBUG" />
<log-target name="default" location="/logs/avalon-demo.log" />
<log-target name="objectstorage-target" location="/logs/objectstorage.log" />
<log-target name="simple-server" location="/logs/simple-server.log" />
</logs>
<policy>
<grant code-base="file:${app.home}${/}SAR-INF${/}lib${/}*">
<permission class="java.security.AllPermission" />
</grant>
</policy>
</environment>

Step 4: Packaging the System

A system must be packaged into a SAR (Service ARchive) before it can be deployed into the Phoenix environment. The content of the archive is shown below.

0 Fri Feb 08 11:09:14 GMT+11:00 2002 META-INF/
0 Fri Feb 08 11:09:14 GMT+11:00 2002 SAR-INF/
0 Fri Feb 08 11:09:14 GMT+11:00 2002 SAR-INF/classes/
0 Fri Feb 08 11:09:14 GMT+11:00 2002 SAR-INF/lib/
99071 Tue Jan 29 23:10:58 GMT+11:00 2002 SAR-INF/lib/cornerstone.jar
8383 Fri Feb 08 11:08:46 GMT+11:00 2002 SAR-INF/lib/fx-conversion-server.jar
1223 Wed Jan 30 16:41:36 GMT+11:00 2002 SAR-INF/config.xml
1527 Fri Feb 08 11:08:00 GMT+11:00 2002 SAR-INF/assembly.xml
842 Wed Jan 30 16:39:34 GMT+11:00 2002 SAR-INF/environment.xml
51 Fri Feb 08 11:09:14 GMT+11:00 2002 META-INF/MANIFEST.MF

The important entry is the fx-conversion-server.jar, which contains the MyFxCoversion block. All of the other blocks that MyFxConversion uses are found in the cornerstone.jar archive.

Step 5: Deploying the System

Finally, to deploy the system, copy the myfxconversion.sar file to the apps subdirectory. When Phoenix starts up, it will extract the archive into a subdirectory of the same name.

Conclusion

The Avalon development effort began in September 1999 and now represents a solid platform for developing server side service-oriented applications. The lower layers of Avalon, namely Framework and Excalibur, are finalized, very stable and have been used for developing core technologies such as Cocoon2 and James. The upper layer, in particular Phoenix, is still in alpha and will make a transition to beta in the near future, once the JMX issues are resolved. There is low to medium risk in adopting this technology for developing server-side components.

References

Jim Alateras is an independent consultant specializing in open source and emerging technologies.


Return to ONJava.com.

Copyright © 2009 O'Reilly Media, Inc.