org.apache.commons.logging
Class PathableClassLoader

java.lang.Object
  extended by java.lang.ClassLoader
      extended by java.security.SecureClassLoader
          extended by java.net.URLClassLoader
              extended by org.apache.commons.logging.PathableClassLoader

public class PathableClassLoader
extends URLClassLoader

A ClassLoader which sees only specified classes, and which can be set to do parent-first or child-first path lookup.

Note that this classloader is not "industrial strength"; users looking for such a class may wish to look at the Tomcat sourcecode instead. In particular, this class may not be threadsafe.

Note that the ClassLoader.getResources method isn't overloaded here. It would be nice to ensure that when child-first lookup is set the resources from the child are returned earlier in the list than the resources from the parent. However overriding this method isn't possible as the java 1.4 version of ClassLoader declares this method final (though the java 1.5 version has removed the final qualifier). As the ClassLoader javadoc doesn't specify the order in which resources are returned, it's valid to return the resources in any order (just untidy) so the inherited implementation is technically ok.


Constructor Summary
PathableClassLoader(ClassLoader parent)
          Constructor.
 
Method Summary
 void addLogicalLib(String logicalLib)
          Specify a logical library to be included in the classpath used to locate classes.
 void addLogicalLib(String[] logicalLibs)
          Specify a collection of logical libraries.
 void addURL(URL url)
          Allow caller to explicitly add paths.
 URL getResource(String name)
          Same as parent class method except that when parentFirst is false the resource is looked for in the local classpath before the parent loader is consulted.
 InputStream getResourceAsStream(String name)
          Same as parent class method except that when parentFirst is false the resource is looked for in the local classpath before the parent loader is consulted.
 Enumeration getResourcesInOrder(String name)
          Emulate a proper implementation of getResources which respects the setting for parentFirst.
protected  Class loadClass(String name, boolean resolve)
          Override ClassLoader method.
 void setParentFirst(boolean state)
          Specify whether this classloader should ask the parent classloader to resolve a class first, before trying to resolve it via its own classpath.
 void useExplicitLoader(String prefix, ClassLoader loader)
          Specify a classloader to use for specific java packages.
 void useSystemLoader(String prefix)
          For classes with the specified prefix, get them from the system classpath which is active at the point this method is called.
 
Methods inherited from class java.net.URLClassLoader
definePackage, findClass, findResource, findResources, getPermissions, getURLs, newInstance, newInstance
 
Methods inherited from class java.security.SecureClassLoader
defineClass, defineClass
 
Methods inherited from class java.lang.ClassLoader
clearAssertionStatus, defineClass, defineClass, defineClass, defineClass, definePackage, findLibrary, findLoadedClass, findSystemClass, getPackage, getPackages, getParent, getResources, getSystemClassLoader, getSystemResource, getSystemResourceAsStream, getSystemResources, loadClass, resolveClass, setClassAssertionStatus, setDefaultAssertionStatus, setPackageAssertionStatus, setSigners
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

PathableClassLoader

public PathableClassLoader(ClassLoader parent)
Constructor.

Often, null is passed as the parent, ie the parent of the new instance is the bootloader. This ensures that the classpath is totally clean; nothing but the standard java library will be present.

When using a null parent classloader with a junit testcase, it *is* necessary for the junit library to also be visible. In this case, it is recommended that the following code be used:

 pathableLoader.useExplicitLoader(
   "junit.",
   junit.framework.Test.class.getClassLoader());
 
Note that this works regardless of whether junit is on the system classpath, or whether it has been loaded by some test framework that creates its own classloader to run unit tests in (eg maven2's Surefire plugin).

Method Detail

addURL

public void addURL(URL url)
Allow caller to explicitly add paths. Generally this not a good idea; use addLogicalLib instead, then define the location for that logical library in the build.xml file.

Overrides:
addURL in class URLClassLoader

setParentFirst

public void setParentFirst(boolean state)
Specify whether this classloader should ask the parent classloader to resolve a class first, before trying to resolve it via its own classpath.

Checking with the parent first is the normal approach for java, but components within containers such as servlet engines can use child-first lookup instead, to allow the components to override libs which are visible in shared classloaders provided by the container.

Note that the method getResources always behaves as if parentFirst=true, because of limitations in java 1.4; see the javadoc for method getResourcesInOrder for details.

This value defaults to true.


useSystemLoader

public void useSystemLoader(String prefix)
For classes with the specified prefix, get them from the system classpath which is active at the point this method is called.

This method is just a shortcut for

 useExplicitLoader(prefix, ClassLoader.getSystemClassLoader());
 

Of course, this assumes that the classes of interest are already in the classpath of the system classloader.


useExplicitLoader

public void useExplicitLoader(String prefix,
                              ClassLoader loader)
Specify a classloader to use for specific java packages.

The specified classloader is normally a loader that is NOT an ancestor of this classloader. In particular, this loader may have the bootloader as its parent, but be configured to see specific other classes (eg the junit library loaded via the system classloader).

The differences between using this method, and using addLogicalLib are:


addLogicalLib

public void addLogicalLib(String[] logicalLibs)
Specify a collection of logical libraries. See addLogicalLib.


addLogicalLib

public void addLogicalLib(String logicalLib)
Specify a logical library to be included in the classpath used to locate classes.

The specified lib name is used as a key into the system properties; there is expected to be a system property defined with that name whose value is a url that indicates where that logical library can be found. Typically this is the name of a jar file, or a directory containing class files.

If there is no system property, but the classloader that loaded this class is a URLClassLoader then the set of URLs that the classloader uses for its classpath is scanned; any jar in the URL set whose name starts with the specified string is added to the classpath managed by this instance.

Using logical library names allows the calling code to specify its desired classpath without knowing the exact location of the necessary classes.


loadClass

protected Class loadClass(String name,
                          boolean resolve)
                   throws ClassNotFoundException
Override ClassLoader method.

For each explicitly mapped package prefix, if the name matches the prefix associated with that entry then attempt to load the class via that entries' classloader.

Overrides:
loadClass in class ClassLoader
Throws:
ClassNotFoundException

getResource

public URL getResource(String name)
Same as parent class method except that when parentFirst is false the resource is looked for in the local classpath before the parent loader is consulted.

Overrides:
getResource in class ClassLoader

getResourcesInOrder

public Enumeration getResourcesInOrder(String name)
                                throws IOException
Emulate a proper implementation of getResources which respects the setting for parentFirst.

Note that it's not possible to override the inherited getResources, as it's declared final in java1.4 (thought that's been removed for 1.5). The inherited implementation always behaves as if parentFirst=true.

Throws:
IOException

getResourceAsStream

public InputStream getResourceAsStream(String name)
Same as parent class method except that when parentFirst is false the resource is looked for in the local classpath before the parent loader is consulted.

Overrides:
getResourceAsStream in class ClassLoader


Copyright © 2001-2009 Apache Software Foundation. All Rights Reserved.