FileDocCategorySizeDatePackage
URLClassLoader.javaAPI DocExample3352Thu Apr 03 15:26:50 BST 1997None

URLClassLoader.java

import java.util.Hashtable;
import java.net.*;
import java.io.*;

public class URLClassLoader extends ClassLoader {

    Hashtable cache;
    URL u;

    public URLClassLoader(URL u) {
    
      this.u = u;
      cache = new Hashtable();
    
    }


    public synchronized Class loadClass(String  name, boolean resolve) 
     throws ClassNotFoundException {
    
      // first look for the class in the cache
      Class c = (Class) cache.get(name);
      
      // If it's not in the cache, then look
      // in the system classes
      if (c == null) {
        try {
          c = findSystemClass(name);
        }
        catch (ClassNotFoundException e) {
        
        }
      }
      
      // if the class still hasn't been found,  
      // load it from the network
      if (c  ==  null) {
        byte b[] = loadClassData(name);
        c = defineClass(b, 0, b.length);
        cache.put(name, c);
      }
      if (resolve) {
        resolveClass(c);
      }
      
      return  c;

   }  // end loadClass
    
    private byte[] loadClassData(String name) 
     throws ClassNotFoundException {
    
      byte[] b;
      InputStream theClass = null;
      int bfr = 128;

      try {
        
        URL classURL = new URL(u, name + ".class");

        URLConnection uc = classURL.openConnection();
        uc.setAllowUserInteraction(false);
        
        // I don't know why, but uc.getInputStream absolutely
        // has to come before uc.getContentLength or you'll
        // get a nasty NullPointerException
        try {
          theClass = uc.getInputStream();
        }
        catch (NullPointerException e) {
          System.err.println(e);
          throw new ClassNotFoundException(name + " input stream problem");
        }
        int cl = uc.getContentLength();

        // A lot of web servers don't send content-lengths
        // for .class files
        if (cl == -1 ) {
          b = new byte[bfr * 16];
        } 
        else {
          b = new byte[cl];
        }

        int bytesread = 0;
        int offset = 0;

        while (bytesread >= 0) {
          bytesread = theClass.read(b, offset, bfr);
          if (bytesread == -1) break;
          offset += bytesread;
          if (cl == -1 && offset == b.length) { // grow the array
            byte temp[] = new byte[offset * 2];
            System.arraycopy(b, 0, temp, 0, offset);
            b = temp;
          }
          else if (offset > b.length) {
            throw new ClassNotFoundException(name 
             + " error reading data into the array");
          }
        }

        if (offset < b.length) { // shrink the array
          byte temp[] = new byte[offset];
          System.arraycopy(b, 0, temp, 0, offset);
          b = temp;
        }

        // Make sure all the bytes were received
        if (cl != -1 && offset != cl) {
          throw new ClassNotFoundException("Only " + offset +
            " bytes received for " + name + 
            "\n Expected " + cl + " bytes");
        }
      } // end try
      catch (Exception e) {
       throw new ClassNotFoundException(name + " " + e);
      }
      finally {
        try {
          if (theClass != null) theClass.close();
        }
        catch (IOException e) {
        }

      }
      
      return b;

    }  // end loadClassData


}  // end URLClassLoader