ObjectLedge container

Introduction

A container a provides the environment in which components may operate. It instantiates the components, connects them together (this is called compositioning), manages their lifecycle (notifies them about system startup and shutdown), provides them with logging facilities and configuration. The container may also provide run-time administrative functionality, from log verbosity adjustments, through component reconfiguration and JMX-enabled components management to aspect weaving/unweawing and component implementation hot swapping.

ObjectLedge container builds on the excelent PicoContainer and NanoContainer packages. Thanks to their flexible design, we were able to create a number of extensions necessary to implement configuration and logging facilities of our container that can be seamlessly plugged into Pico/Nano.

Compositioning

The composition of components is described using an XML file. We are using a custom implementation of the org.picoextras.script.xml.XmlFrontEnd that is a bit more expressive than the one found in NanoContainer (but we'd love to see our changes folded back to Nano!) See the extensions page for more details.

Configuration

The components are configured using separate XML files. This makes locating the settings of a particular component easier than with a single XML or properties file. It is also more friendly to revision control systems, splitting the configuration into semantically distinct items. All of the configuration files are subject to schema checking in order to detect configuration problems early, and without the need to write boiler plate java code. We have chosen RelaxNG schema language, because it is compact and easy to read. We use simple naming scheme to associate the component with it's configuration file and the configuration schema. If a component class name is com.wombat.Printer the configuration file name is com.wombat.Printer.xml and the schema file path in the classpath is com/wombat/Printer.rng. To be more specific, the containter derives the names from the role of the component in the system. In simple cases it is equivalent to the component's class name, but usually it is the name of an interface the component imlements, that the other components depend on.

The configuration of a component, read from the XML file is passed to the component as an instance of org.jcontainer.dna.Configuration interface. All you need to do is to declare a parameter of that type in your component's constructor.

Logging

A similar facility is provided for logging. If your component declares an org.jcontainer.dna.Logger parameter in the constructor, it will be passed a logger instance. All the loggers are configured by a single component, the LoggingConfigurator, that will also provide runtime verbosity adjustment facilities in the future.

Lifecycle

We are using standard facilitis of the PicoContainer for the management. A component that implements org.picocontainer.lifecycle.Lifecycle will be notified about the container's startup, shutdown, and disposal.