Browse DevX
Sign up for e-mail newsletters from DevX


Take Control of Class Loading in Java  : Page 3

By building a classloading component container framework that isolates Java class loading to a specified jar file, you can be confident that the runtime will load the component versions you expect.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

Exploiting Classloader Namespaces
You can implement the component container framework concept as a container entity that is responsible for loading components defined in jar or zip archives and the ancillary classes needed by the components. The goals for this framework are to:

  1. Allow developers to specify which version of a component to instantiate.
  2. Load the correct ancillary classes for each component based on information found in the same jar file as the component.
  3. Share ancillary classes and archives across components.
You'll need a configuration file to define components and their corresponding ancillary files, as illustrated in the following examples:

<?xml version="1.0"?> <component name= "com.jeffhanson.components.HelloWorld"> <component-archive> HelloWorldComponentV1.jar </component-archive> <ancillary-resources> <ancillary-resource> log4j-1.2.12.jar </ancillary-resource> <ancillary-resource> concurrent-1.3.4.jar </ancillary-resource> </ancillary-resources> </component>

Compare the elements in the preceding example with the following example. The only change is the value of the component-archive element. This element value defines the name of the archive that contains each versioned component.

<?xml version="1.0"?> <component name= "com.jeffhanson.components.HelloWorld"> <component-archive> HelloWorldComponentV2.jar </component-archive> <ancillary-resources> <ancillary-resource> log4j-1.2.12.jar </ancillary-resource> <ancillary-resource> concurrent-1.3.4.jar </ancillary-resource> </ancillary-resources> </component>

To be sure the framework loads classes from only the specified locations, you must create a new ClassLoader that extends URLClassLoader. Override the loadClass method to prevent calls to it from propagating to the default classloader parent—and thus loading the class from the standard classpath. Doing that restricts class-searching to the URLs supplied to the classloader and lets you supply specific jar file locations to the classloader from which it will load components.

The following code illustrates the component classloading mechanism:

package com.jeffhanson.components; import java.net.URL; import java.net.URLClassLoader; public class RestrictedURLClassLoader extends URLClassLoader { public RestrictedURLClassLoader( URL[] urls) { super(urls, null); }

Figure 2. Component Container Framework Class Relationships: The figure illustrates the relationships between the classes of the component container framework.
public Class loadClass(String name) throws ClassNotFoundException { Class cls = super.loadClass(name); if (cls == null) { throw new ClassNotFoundException( "Restricted ClassLoader" + " is unable to find class: " + name); } return cls; } }
The restricted classloader is used by the component container to load components and any specified ancillary classes.

The component container uses the context classloader of the current thread to find the URL for the component. Then this URL is fed to the restricted classloader and used to instantiate the component. The component class is then cached by the component container for subsequent calls. Listing 1 shows the code for the component container, and Figure 2 illustrates the relationships between the classes of the component container framework.

Thanks for your registration, follow us on our social networks to keep up-to-date