layout: article title: Container Comparisons —
This document aims to compare PicoContainer to other IoC containers, both lightweight and not.
There are a number of published API specifications since Java was initially released that proport to be container/component designs. We discuss then here, suggesting there are goals that some have met, and some not. This may help you make better design choices for your own components.
The Spring Framework is a J2EE framework. As such, Dependency Injection and Lifecycle is only one of its concerns. PicoContainer, on the other hand, is concerned only with Dependency Injection , configuration and Lifecycle .
(Avalon ceased development in 2005)
Apache hosted a project that had been running for many years called Avalon. It had many components that fit that its design and many containers is written in Java. Avalon components were characterized by implementation of many optional interfaces. Avalon components were distributed with meta-information in XML in the jar file. More XML is required to assemble components together for the same of a application. Avalon Phoenix, Excalibur Component Manager (ECM), Avalon Fortress and Avalon Merlin were the pertinent containers.
The Avalon Framework required implementing components to implement a number of interfaces. By the end of the the project, this had proven historically to be a bit of a turn-off for component writers. Those interfaces were :-
Avalon InterfacePicoContainer equivalent | ||||
LogEnabled | Logging agnostic | |||
Contextualizable | n/a | |||
Serviceable (was Composable) | arguments are injected | |||
Configurable | arguments are injected | |||
Parameterizable | n/a | |||
Initializable | Constructor is the equivalent lifecycle concept | |||
Startable | Startable | |||
Suspendable | n/a | |||
Recontextualizable | n/a | |||
Recomposable | n/a | |||
Reconfigurable | n/a | |||
Reparameterizable | n/a | |||
Disposable | Disposable |
Avalon is a Contextualized Lookup IoC design.
import org.apache.avalon.framework.ServiceManager;
import org.apache.avalon.framework.Serviceable;
import org.apache.avalon.framework.ServiceException;
public class Shop implements Serviceable, Initializable {
StockManager stockManager;
String shopZipCode;
public void service(ServiceManager sm) throws ServiceException {
stockManager = (StockManager) sm.lookup("StockManager");
}
public void initialize() {
// all service()ing has been done.
}
}
A component has to have service (component) declarations in an external file. The Loom container (forked from Phoenix ) has .xinfo files for each component to meet such needs. All Avalon container have some mechanism for storing configuration and assembly externally to the class. Cross referenced against the xinfo files, Loom’s assembly.xml defines the implementations to be used for component types. Thus all Avalon components must be interface/implementation separated. Another Avalon using server technology is Keel .
It has to be said that all post-Avalon projects are not as active as they could be.
The downside of the this design is that components can only be used without the container with great difficulty. If at all. Thus a proper container is needed at all times, and you have to choose one for different purposes. If you do manage to instantiate components without a container, you might miss one of the essential service dependencies. The component-using class will continue to compile, but at run time it will be apparent that there are missing dependencies. Because of the these complexities, unit testing with frameworks like JUnit is very difficult for of Avalon components.
Sun have specified several container/component designs over the years.
Clearly Entity and Session beans run inside a container. The API is well defined, and to varying degrees of success one can deploy EJB applications to WebLogic, WebSphere, Orion and JBoss etc. For assembly and configuration, there is high use of element-normal XML . There are some mandated parent objects and interfaces for various to extend and/or implement. Resolution is done by the components themselves via JNDI more often than not.
PicoComponents are simpler in they they do not force an extensive XML markup, nor require the implementing of certain interfaces or extending base classes. Quite importantly the relationship between factory (home), implementation (bean) and interface (remote) parts is much more real in Pico-style components. EJB 2.0 components are nearly impossible to unit-test without much effort.
With the advent of EJB 3.0 (which the our team directly influenced), things became easier for EJB developers. Annotations were used to mark fields, and methods for injection. Strangely constructors were not eligible for injection. It was reported back to the our team that it was felt that the J2EE container makers would not find it easy making multi-argument constructor injection a reality.
Not so obvious - Servlets are contained by a servlet container. They are generally bundled with (or replaced by) value added propositions like JSP, but it is still a container/component design. High use of XML for assembly and configuration. Servlets have no concept of parent container or the container above that (sometimes EJB) and its provision of components, which is very unfortunate. Servlets have a number of interfaces to honor, none of which is too malignant. Servlets typically deal with external (or parent) components via RMI or JNDI. In more recent releases of EJB, local interfaces rather than RMI may be the mechanism for connection the parent components. WebLogic have always provided an optimizing mechanism for this interoperation
As with EJB, PicoComponents are far simpler. This is probably because they offer no web experience, without an extension. Servlets again are not that unit-testable.
Applets, though presently not so often used, are a good example of Container/Component separations. There is very little XML in use by Applets. Configuration is typically delivered in applet tags in HTML. Applets are granted some access to the parent container, the browser, and its DOM model for pages and other applets. There very little standardization for Browser as a container.
As with EJB, PicoComponents are far simpler. Applets are unit-testable but with a little effort. Complex DOM interoperation is impossible under unit testing.
public static void main(String\[\] args) {}
Familiar? Hopefully not Static plays no part in a good IoC container/component design. This includes static launching of Java Webstart (JNLP) applications. If you have to keep mainable functionality separate your components away from the main() class so they may be instantiated separately. In .NET you’ll have to make sure that the application assembly is a small bootstrap to a component one.
A huge map of clunky access components via a very non-IoC mechanism. It has to be strapped with much XML to prevent inappropriate access. This is not IoC because the component reaches out for external component dependancies whenever it feels like. This last fact clouds Serlvets and EJB use.
Nice container/component designs. In the case of Swing, perhaps a little difficult for coders to easily assemble applications.
The Eclipse platform is very compelling. It supports the notion of a pluggable application concept. Each component statically accesses other components via a factory (which at least Paul does not like), though it is clear that some complex classloader magic is going on. The underpinning set of graphical components, SWT , are a simple and elegant design.