1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
|
package com.bioxpr.loader;
public class JarClassLoader extends MultiClassLoader
{
private JarResources jarResources;
public JarClassLoader (String jarName)
{
// Create the JarResource and suck in the jar file.
jarResources = new JarResources (jarName);
}
protected byte[] loadClassBytes (String className)
{
// Support the MultiClassLoader's class name munging facility.
className = formatClassName (className);
// Attempt to get the class data from the JarResource.
return (jarResources.getResource (className));
}
}
package com.bioxpr.loader;
import java.util.Hashtable;
/**
* A simple test class loader capable of loading from
* multiple sources, such as local files or a URL.
*
* This class is derived from an article by Chuck McManis
* http://www.javaworld.com/javaworld/jw-10-1996/indepth.src.html
* with large modifications.
*
* Note that this has been updated to use the non-deprecated version of
* defineClass() -- JDM.
*
* @author Jack Harich - 8/18/97
* @author John D. Mitchell - 99.03.04
*/
public abstract class MultiClassLoader extends ClassLoader {
// ---------- Fields --------------------------------------
private Hashtable classes = new Hashtable();
private char classNameReplacementChar;
protected boolean monitorOn = false;
protected boolean sourceMonitorOn = true;
// ---------- Initialization ------------------------------
public MultiClassLoader() {
}
// ---------- Superclass Overrides ------------------------
/**
* This is a simple version for external clients since they
* will always want the class resolved before it is returned
* to them.
*/
@SuppressWarnings("unchecked")
public Class loadClass(String className) throws ClassNotFoundException {
return (loadClass(className, true));
}
// ---------- Abstract Implementation ---------------------
@SuppressWarnings("unchecked")
public synchronized Class loadClass(String className,
boolean resolveIt) throws ClassNotFoundException {
Class result;
byte[] classBytes;
monitor(">> MultiClassLoader.loadClass(" + className + ", " + resolveIt + ")");
//----- Check our local cache of classes
result = (Class)classes.get(className);
if (result != null) {
monitor(">> returning cached result.");
return result;
}
//----- Check with the primordial class loader
try {
result = super.findSystemClass(className);
monitor(">> returning system class (in CLASSPATH).");
return result;
} catch (ClassNotFoundException e) {
monitor(">> Not a system class.");
}
//----- Try to load it from preferred source
// Note loadClassBytes() is an abstract method
classBytes = loadClassBytes(className);
if (classBytes == null) {
throw new ClassNotFoundException();
}
//----- Define it (parse the class file)
result = defineClass(className, classBytes, 0, classBytes.length);
if (result == null) {
throw new ClassFormatError();
}
//----- Resolve if necessary
if (resolveIt) resolveClass(result);
// Done
classes.put(className, result);
monitor(">> Returning newly loaded class.");
return result;
}
// ---------- Public Methods ------------------------------
/**
* This optional call allows a class name such as
* "COM.test.Hello" to be changed to "COM_test_Hello",
* which is useful for storing classes from different
* packages in the same retrival directory.
* In the above example the char would be '_'.
*/
public void setClassNameReplacementChar(char replacement) {
classNameReplacementChar = replacement;
}
// ---------- Protected Methods ---------------------------
protected abstract byte[] loadClassBytes(String className);
protected String formatClassName(String className) {
if (classNameReplacementChar == '\u0000') {
// '/' is used to map the package to the path
return className.replace('.', '/') + ".class";
} else {
// Replace '.' with custom char, such as '_'
return className.replace('.',
classNameReplacementChar) + ".class";
}
}
protected void monitor(String text) {
if (monitorOn) print(text);
}
// --- Std
protected static void print(String text) {
System.out.println(text);
}
} // End class |
Partager