A Java 2 Network Class Loader
by Lorenzo Bettini and Donato Cappetta

Example 1:
protected Class findClass(String className) throws ClassNotFoundException
{
   byte[] byte_code = loadBytesFromMySource(className);
   if (byte_code == null)
     throw new ClassNotFoundException(className);
   return defineClass(byte_code, ...);
}

Listing One
package loader;

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

public class NetworkClassLoader  extends ClassLoader {
    private String hostName = null;
    private int serverPort;
    private Socket socket = null;
    private ObjectInputStream is = null;
    private ObjectOutputStream os = null;
    private boolean connected = false;
    private int tab = -1; // just to print with indentation
    private Hashtable resourceTable = new Hashtable(); // key name, value File

    public NetworkClassLoader() {
        this("localhost", 5050);
    }
    public NetworkClassLoader(String hostName, int serverPort) {
        super();
        this.hostName = hostName;
        this.serverPort = serverPort;
    }
    protected Class findClass(String className)
        throws   ConnectClassServerException, JavaPackageException,
                 ClassNotFoundException, ClassFormatError {
        byte[] classBytes = null;
        Class classClass = null;
        // try with the network server
        try {
            // connect to the ClassServer
            if (!connected)
                connect();
            classBytes = loadClassFromServer(className);
        } catch (IOException ioe){
            disconnect();
            throw new ConnectClassServerException(ioe.toString());
        }
        // convert the byte array into a Class and put it in the cache.
        classClass = defineClass(className,classBytes,0,classBytes.length);
        if (classClass == null)
            throw new ClassFormatError(className);
        Print(className + " loaded from the SERVER");
        return classClass;
    }        //end loadClass()
    protected URL findResource(String name)
    {
      URL resourceURL;
      try {
          File localResourceFile = (File) resourceTable.get(name);
          // we have to download it
          if (localResourceFile == null) {
              Print("findResource: " + name + " at the SERVER");
              byte[] resourceBytes = loadResourceFromServer(name, "BINARY");
              if (resourceBytes == null) {
                  Print("Resource " + name + " not found on server!");
                  return null;
              }
              localResourceFile=createLocalResourceFile(name,resourceBytes);
              resourceTable.put(name, localResourceFile);
              Print("stored locally: " + localResourceFile);
          }
          return getLocalResourceURL(localResourceFile);
      } catch (Exception e) {
          Print("Exception " + e);
      }
      return super.findResource (name);
    }
    protected URL getLocalResourceURL(File file) throws MalformedURLException
    {
        return file.toURL();
    }
    protected File createLocalResourceFile(String name, byte[] bytes) 
        throws MalformedURLException, FileNotFoundException, IOException
    {
        File resFile = File.createTempFile
            ("__temp_res_", "_" + createLocalResourceName(name));
        resFile.deleteOnExit();

        FileOutputStream fostream = new FileOutputStream(resFile);
        fostream.write(bytes, 0, bytes.length);
        fostream.close();
        return resFile;
    }
    protected String createLocalResourceName(String name)
    {
        return name.replace('/', '_');
    }
    public synchronized Class loadClass(String name, boolean resolve)
        throws ClassNotFoundException
    {
        ++tab;
        Print("Loading class " + name);
        Class result =  super.loadClass(name, resolve);
        --tab;
        return result;
    }
    protected void Print(String s)
    {
        for (int i = 0; i < tab; ++i )
            System.out.print(" ");
        System.out.println(s);
    }
    protected void connect() throws UnknownHostException, IOException {
        System.out.println("Connecting to the ClassServer " 
                                          + hostName + ":" + serverPort);
        socket = new Socket(hostName, serverPort);
        connected = true;
        os = new ObjectOutputStream(new 
                           BufferedOutputStream(socket.getOutputStream()));
        os.flush();
        is = new ObjectInputStream(new 
                           BufferedInputStream(socket.getInputStream()));

        System.out.println("Connected");
    }        //end connect()
    protected void disconnect(){
        try {
            connected = false;
            os.close(); os = null;
            is.close(); is = null;
            socket.close(); socket = null;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }        //end disconnect()
    protected byte[] loadClassFromServer(String className)
        throws ClassNotFoundException, SocketException, IOException
    {
        byte[] classBytes = loadResourceFromServer(className, "CLASS");
        if (classBytes == null)
            throw new ClassNotFoundException(className);
        return classBytes;
    }   //end loadClassFromServer()

    protected byte[] loadResourceFromServer(String resourceName, String type)
        throws FileNotFoundException, ClassNotFoundException,
               SocketException, IOException
    {
        byte[] fileBytes = null;
        // load the file data from the connection

        // send the name of the file
        sendRequest(resourceName, type);
        
        // read the packet
        ResourcePacket resourcePacket = (ResourcePacket) is.readObject();
        
        if (! resourcePacket.isOK())
            throw new FileNotFoundException(resourcePacket.getError());
        fileBytes = resourcePacket.getResourceBytes();
        return fileBytes;
    }   //end loadResourceFromServer()
    protected void sendRequest(String name, String type)
    throws IOException
    {
        os.reset();
        os.writeObject(new ResourceRequest(name, type));
        os.flush();
    }
}  //end class NetworkClassLoader




1

