import java.util.*; import java.io.*; import java.net.*; public class URLClassLoader extends ClassLoader { Hashtable cache = new Hashtable(); URL theURL; public URLClassLoader(URL u) { // convert to a directory URL String file = u.getFile(); int i = file.lastIndexOf('/'); if ((i > 0) && (i < file.length()-1)) { try { u = new URL(u, file.substring(0, i+1)); } catch (MalformedURLException e) { } } theURL = u; } public URL getURL() { return theURL; } private Class downloadClass(String name) throws IOException { if (!name.toLowerCase().endsWith(".class")) name += ".class"; URL u = new URL(theURL, name); InputStream is = null; try { try { URLConnection uc = u.openConnection(); uc.setAllowUserInteraction(false); is = uc.getInputStream(); int cl = uc.getContentLength(); int buffersize; // Many servers don't return content length headers // If so, we'll guess that 2048 is long enough // and expand the array as we need to. if (cl <= 0) buffersize = 2048; else buffersize = cl; byte dotclass[] = new byte[buffersize]; int totalRead = 0; int bytesRead = 0; while ((bytesRead = is.read(dotclass, totalRead, dotclass.length - totalRead)) >= 0) { totalRead += bytesRead; if (totalRead == dotclass.length) { if (cl < 0) { // We don't know the content-length so we // keep reading until there aren't any bytes left byte temp[] = new byte[2*totalRead]; System.arraycopy(dotclass, 0, temp, 0, totalRead); dotclass = temp; } else { break; } } } return defineClass(dotclass, 0, totalRead); } finally { if (is != null) is.close(); } } catch (IOException e) { throw e; } catch (Throwable t) { throw new IOException(u + " did not load"); } } public Class loadClass(String name) throws ClassNotFoundException { return loadClass(name, true); } public Class loadClass(String name, boolean resolve) throws ClassNotFoundException { Class c = null; // try to get it from the cache; c = (Class) cache.get(name); if (c == null) { // not in the cache try { return findSystemClass(name); } catch (Throwable t) { } // not a system class try { c = downloadClass(name); } catch(IOException e) { // download failed } } if (c == null) { throw new ClassNotFoundException(name); } if (resolve) { resolveClass(c); } cache.put(name, c); return c; } }