Archives and Components
Because archive files (jar files, zip files, etc.) are so tightly coupled with the Java class-loading mechanism and deployment tools, they are a natural candidate to employ as vessels for self-defining components. The success of a Java component packaged and deployed within an archive depends on:
- Developers being able to specify which version of a component to instantiate
- Loading the correct version of the component's ancillary classes based on information found in the same jar file as the component
This gives complete control to developers and consumers of the component as to which version of each component is actually created and used.
In the following sections, I will discuss the concept of defining components and component namespaces by the archive into which they are stored.
Sharing Ancillary Resources
|Figure 1. Using Multiple Classloaders: Because of the way Java's naming convention works, using different classloaders defines different namespaces.|
One of the biggest problems when dealing with shared libraries in Java when using standard classloaders is that all classes are loaded into a single namespace. This makes it very difficult to use different versions of the same library at any given time. What you need is the ability for a component to define its own namespace into which the component and all of its ancillary libraries would be loaded.
Because the runtime identity of a class in Java is defined by the class's fully-qualified name and the ID of its classloader, a namespace already exists for each classloader. Therefore, you can use the classloader to build a component container that defines a namespace for a component and its dependencies.
For example, if I have a class named "com.jeffhanson.components.HelloWorld" for which I want to run two versions, the solution is to create an instance of one version of the HelloWorld class with one classloader and create the other version of the HelloWorld class with another classloader. Figure 1 illustrates this concept.
As I'll demonstrate in this article, the technique of instantiating a class using two different classloaders actually creates a virtual namespace. However, I have actually just created multiple instances of the same version of the class.
To facilitate loading and instantiating multiple versions of the same class, I will demonstrate, in the following sections, a component-container framework that will build on the classloader namespace mechanism to allow loading different versions of the same class.