Monday, July 14, 2008

Take Control of Class loading in Java

How this can be achieved?? , but first let us explore why this is required. The objective which I have targeted here is classpath version conflicts.

The Java Classpath

Java relies on the environment property/variable, CLASSPATH, to designate the path that the Java runtime will use to search for classes and other resources, as they are needed. The CLASSPATH property can be designated using the CLASSPATH environment variable or the command-line option, -classpath.
A Java runtime typically finds and loads classes in the following order:

1) In the list of bootstrap classes – Classes which embody the Java platform, such as the classes in rt.jar.

2) In the list of extension classes – Classes utilizing the Extension Mechanism Framework (http://java.sun.com/j2se/1.4.2/docs/guide/extensions/spec.html) to extend the Java platform, stored in archive files (.jar, .zip, etc.) located in the /lib/ext directory of the runtime environment.

3) User classes – Classes that do not utilize the extension mechanism architecture identified using the -classpath command-line option or the CLASSPATH environment variable.

JDK 1.3 introduced the Class-Path manifest entry to be used to specify optional jars and directories that will be loaded if needed. The following illustrates a sample Class-Path entry:
Class-Path: mystuff/utils.jar mystuff/logging.jar mylib/

Consider the situation when a different version of a library exists on the classpath than an executing class may be expecting.

Classpath Version Conflicts

The runtime identity of a class in Java is defined by its fully-qualified name (the package name prepended to the class name), sometimes known as the FQN, and the ID of the classloader that loaded the class. Thus, each instance of a class loaded by multiple classloaders instances (In a JVM, each and every class is loaded by some instance of a java.lang.ClassLoader), is regarded as separate entities by the Java runtime. This means that multiple versions of the same class can be loaded into the Java runtime at any given time. This is a very powerful and flexible feature; however, the side effects of this can be confusing to a developer if not used intelligently.

Imagine that we load a new version of a database DAO with a slightly different API to meet the demands of a new feature of a DAO client, but we still need the old DAO for other clients not ready for the new API. In typical runtime environments, the new DAO will simply replace the old version and all new instances will be created from the new version. However, if the update takes place without stopping the runtime environment (hot-loading) any already existing instances of the old DAO will reside in memory alongside any instances of the new version of the DAO as they are created. This is confusing at best.

Even worse is the danger of a DAO client expecting to create an instance of the old version of the DAO, but actually getting an instance of the new version with the altered API.To ensure stability and safety, calling code must be able to designate the exact version of a class that it intends to use. This can be addressed with the introduction of a class-loading, component-container model and some simple class-loading techniques.

The success of a Java component packaged and deployed within an archive depends on:

a) The developer being able to specify which version of a component to instantiate

b) Loading the correct version of the component’s ancillary classes (dependency) 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.One of the biggest problems when dealing with shared libraries in Java, using standard classloaders, is the single namespace into which all classes are loaded. This makes it very difficult to use different versions of the same library at any given time. What is needed is the ability for a component to define its own namespace into which the component and all of its ancillary libraries reside.

Will discuss the concept of defining components and component namespaces by the archive into which they are stored.

No comments: