01: package abbot.util;
02:
03: import abbot.Log;
04:
05: /** Provides support for loading a class <i>before</i> checking the parent
06: * class loader for it. If the shouldDelegate method returns false for a
07: * given class name, it will defer to its parent class loader only if the
08: * class is not found in this loader's path. This provides a means for
09: * reloading classes that would otherwise be permanently cached by the app
10: * or boot class loaders.<p>
11: * The name for this class is not quite correct; it <i>will</i> delegate to
12: * its parent if it doesn't find a given class.
13: */
14: public class NonDelegatingClassLoader extends PathClassLoader {
15:
16: public NonDelegatingClassLoader(String path, ClassLoader parent) {
17: super (path, parent);
18: }
19:
20: /** Returns whether the given class should be given to the parent class
21: * loader to try before this one does. The default implementation always
22: * returns false. Making this method return true will revert to the
23: * standard class loader behavior.
24: */
25: protected boolean shouldDelegate(String name) {
26: return false;
27: }
28:
29: /** Find the given class in the search path. */
30: public Class findClass(String name) throws ClassNotFoundException {
31: Log.debug("Looking up " + name + " with " + this );
32: return super .findClass(name);
33: }
34:
35: /** Load the given class, but attempt to load <i>before</i> the parent if
36: shouldDelegate returns false for the given class.
37: */
38: protected synchronized Class loadClass(String name, boolean resolve)
39: throws ClassNotFoundException {
40: if (shouldDelegate(name)) {
41: Log.debug("Delegating lookup for " + name);
42: return super .loadClass(name, resolve);
43: }
44: Log.debug("Non-delegating lookup for " + name);
45: Class c = findLoadedClass(name);
46: if (c == null) {
47: try {
48: c = findClass(name);
49: } catch (SecurityException se) {
50: Log.debug(se);
51: // We're not allowed to find it, so give it to the parent
52: return super .loadClass(name, resolve);
53: } catch (ClassNotFoundException cnf) {
54: // If we can't find it, maybe the parent can
55: return super .loadClass(name, resolve);
56: }
57: if (resolve) {
58: resolveClass(c);
59: }
60: } else {
61: Log.debug("Class already loaded " + name);
62: }
63: return c;
64: }
65: }
|