Developing for Jakarta Avalonby Jim Alateras
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.
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 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 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 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.