FileDocCategorySizeDatePackage
StreamClassLoader.javaAPI DocExample2673Sun Feb 01 14:44:52 GMT 1998dcj.util

StreamClassLoader.java

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;
  }
}