edu.rice.cs.util.classloader
Class StickyClassLoader
java.lang.Object
|
+--java.lang.ClassLoader
|
+--edu.rice.cs.util.classloader.StickyClassLoader
- public class StickyClassLoader
- extends ClassLoader
A ClassLoader
that works as the union of two classloaders, but
always tries to delegate to the first of these.
The purpose for this class is to ensure that classes loaded transitively
due to some class's loading are also loaded with the right classloader.
Here's the problem: Say that class A contains a reference to class B,
but the specific B is unknown to clients of class A.
Class A is loadable by the standard classloader, but class B needs
to be loaded with a (known) custom classloader.
If A were loaded using
the standard classloader, it would fail because this would cause the
transitive loading of B to be done by the system loader as well.
If A were loaded with the custom loader, the same thing would happen --
the custom loader would delegate to the system loader to load A (since
it doesn't load non-custom-loader-requiring classes), but this would
associate class A with the system classloader. (Every class is associated
with the loader that called ClassLoader.defineClass(byte[], int, int)
to define it
in the JVM.) This association would make B be loaded by the standard loader!
To get around this problem, we use this class, which acts mostly
as a union of two classloaders. The trick, however, is that the
StickyClassLoader has itself associated with all classes it loads, even
though the actual work is done by the two loaders it delegate to.
(It does this by calling ClassLoader.findResource(java.lang.String)
on the
subordinate loaders to get the class data, but then by calling
ClassLoader.defineClass(byte[], int, int)
itself to preserve the association.
- Version:
- $Id: StickyClassLoader.java,v 1.7 2002/02/21 04:56:25 brianstoler Exp $
Fields inherited from class java.lang.ClassLoader |
bootstrapClassPath, classes, defaultDomain, defaultPermissions, getClassLoaderPerm, initialized, loadedLibraryNames, nativeLibraries, nativeLibraryContext, nocerts, package2certs, packages, parent, scl, sclSet, sys_paths, systemNativeLibraries, usr_paths |
Method Summary |
URL |
getResource(String name)
Gets the requested resource, looking first in the new loader
and then in the old loader. |
protected Class |
loadClass(String name,
boolean resolve)
Loads the given class, delegating first to the new class loader and
then second to the old class loader. |
Methods inherited from class java.lang.ClassLoader |
, addClass, check, checkCerts, checkPackageAccess, compareCerts, copyFrom, defineClass, defineClass, defineClass, defineClass0, definePackage, findBootstrapClass, findBootstrapClass0, findClass, findLibrary, findLoadedClass, findNative, findResource, findResources, findSystemClass, getBootstrapClassPath, getBootstrapResource, getBootstrapResources, getCallerClassLoader, getDefaultDomain, getGetClassLoaderPerm, getPackage, getPackages, getParent, getResourceAsStream, getResources, getSystemClassLoader, getSystemResource, getSystemResourceAsStream, getSystemResources, initializePath, isAncestor, loadClass, loadClassInternal, loadLibrary, loadLibrary0, removeSystemClassLoader, resolveClass, resolveClass0, setSigners |
Methods inherited from class java.lang.Object |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, registerNatives, toString, wait, wait, wait |
_newLoader
private final ClassLoader _newLoader
_classesToLoadWithOld
private final String[] _classesToLoadWithOld
StickyClassLoader
public StickyClassLoader(ClassLoader newLoader,
ClassLoader oldLoader)
- Creates a sticky class loader with the given primary and secondary
loaders to join together.
All classes will be attempted to be loaded with the primary loader,
and the secondary will be used as a fallback.
- Parameters:
newLoader
- Primary loaderoldLoader
- Secondary loader
StickyClassLoader
public StickyClassLoader(ClassLoader newLoader,
ClassLoader oldLoader,
String[] classesToLoadWithOld)
- Creates a sticky class loader with the given primary and secondary
loaders to join together.
All classes will be attempted to be loaded with the primary loader
(except for classes in
classesToLoadWithOld
),
and the secondary will be used as a fallback.
- Parameters:
newLoader
- Primary loaderoldLoader
- Secondary loaderclassesToLoadWithOld
- All class names in this array will be loaded
only with the secondary classloader. This is
vital to ensure that only one copy of some
classes are loaded, since two differently
loaded versions of a class act totally
independantly! (That is, they have different,
incompatible types.) Often it'll be necessary
to make key interfaces that are used between
components get loaded via one standard
classloader, to ensure that things can be
cast to that interface.
getResource
public URL getResource(String name)
- Gets the requested resource, looking first in the new loader
and then in the old loader.
- Overrides:
getResource
in class ClassLoader
- Parameters:
name
- Name of resource to find- Returns:
- URL of the resource if found/accessible, or null if not.
loadClass
protected Class loadClass(String name,
boolean resolve)
throws ClassNotFoundException
- Loads the given class, delegating first to the new class loader and
then second to the old class loader. The returned Class object will have
its ClassLoader (
Class.getClassLoader()
) set to be this. This is very
important because it causes classes that are loaded due to this class
being loaded (ancestor classes/interfaces, referenced classes, etc) to
use the same loader.
There are a few exceptions to this explanation:
- If the class is in java.* or javax.*, it will be loaded using
ClassLoader.getSystemClassLoader()
. This is because only
the system loader is allowed to load system classes!
Also: sun.*.
- If the class name is in the list of classes to load with the
old class loader (passed to constructor), the new loader is not
considered when trying to load the class.
This is useful to make sure that certain classes (or interfaces)
only have one copy in the system, to ensure that you can cast to that
class/interface regardless of which loader loaded the other class.
- Overrides:
loadClass
in class ClassLoader