package dcj.util;
import java.lang.*;
import java.net.*;
import java.io.*;
import java.util.Hashtable;
/**
* Source code from "Java Distributed Computing", by Jim Farley.
*
* Class: StreamClassLoader
* Example: 2-9
* Description: A class loader that uses an InputStream as the source
* of the bytecodes defining the classes it loads. Note that this
* ClassLoader does its own caching of class bytecodes, which is no
* longer necessary as of JDK 1.1, since the ClassLoader base class
* provides its own caching mechanism now. Also, this class loader
* doesn't follow the standard convention of checking the local
* CLASSPATH with the default ClassLoader before attempting to load
* a requested class over the stream.
*/
public abstract class StreamClassLoader extends ClassLoader {
// Instance variables and default initializations
Hashtable classCache = new Hashtable();
InputStream source = null;
// Constructor
public StreamClassLoader() { }
// Parse a class name from a class locator (URL, filename, etc.)
protected abstract String parseClassName(String classLoc)
throws ClassNotFoundException;
// Initialize the input stream from a class locator
protected abstract void initStream(String classLoc) throws IOException;
// Read a class from the input stream
protected abstract Class readClass(String classLoc, String className)
throws IOException, ClassNotFoundException;
// Implement the ClassLoader loadClass() method.
// First argument is now interpreted as a class locator, rather than
// simply a class name.
public Class loadClass(String classLoc, boolean resolve)
throws ClassNotFoundException {
String className = parseClassName(classLoc);
Class c = (Class)classCache.get(className);
// If class is not in cache...
if (c == null) {
// ...try initializing our stream to its location
try { initStream(classLoc); }
catch (IOException e) {
throw new ClassNotFoundException("Failed opening stream to URL.");
}
// Read the class from the input stream
try { c = readClass(classLoc, className); }
catch (IOException e) {
throw new ClassNotFoundException("Failed reading class from stream: "
+ e);
}
}
// Add the new class to the cache for the next reference.
// Note that we cache based on the class name, not locator.
classCache.put(className, c);
// Resolve the class, if requested.
if (resolve)
resolveClass(c);
return c;
}
} |