package NetworkAdapter.Implementation; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.nio.ByteBuffer; import java.util.Enumeration; import java.util.Vector; /** * A class loader that combines multiple class loaders into one.<br> * The classes loaded by this class loader are associated with this class loader, * i.e. Class.getClassLoader() points to this class loader. * <p> * Author Christian d'Heureuse, Inventec Informatik AG, Zurich, Switzerland, www.source-code.biz<br> * License: LGPL, http://www.gnu.org/licenses/lgpl.html<br> * Please contact the author if you need another license. */ public class JoinClassLoader extends ClassLoader { private ClassLoader[] delegateClassLoaders; public JoinClassLoader (ClassLoader parent, ClassLoader... delegateClassLoaders) { super (parent); this.delegateClassLoaders = delegateClassLoaders; } protected Class<?> findClass (String name) throws ClassNotFoundException { // It would be easier to call the loadClass() methods of the delegateClassLoaders // here, but we have to load the class from the byte code ourselves, because we // need it to be associated with our class loader. String path = name.replace('.', '/') + ".class"; URL url = findResource(path); if (url == null) { throw new ClassNotFoundException (name); } ByteBuffer byteCode; try { byteCode = loadResource(url); } catch (IOException e) { throw new ClassNotFoundException (name, e); } return defineClass(name, byteCode, null); } private ByteBuffer loadResource (URL url) throws IOException { InputStream stream = null; try { stream = url.openStream(); int initialBufferCapacity = Math.min(0x40000, stream.available() + 1); if (initialBufferCapacity <= 2) initialBufferCapacity = 0x10000; else initialBufferCapacity = Math.max(initialBufferCapacity, 0x200); ByteBuffer buf = ByteBuffer.allocate(initialBufferCapacity); while (true) { if (!buf.hasRemaining()) { ByteBuffer newBuf = ByteBuffer.allocate(2*buf.capacity()); buf.flip(); newBuf.put (buf); buf = newBuf; } int len = stream.read(buf.array(), buf.position(), buf.remaining()); if (len <= 0) break; buf.position (buf.position()+len); } buf.flip(); return buf; } finally { if (stream != null) stream.close(); }} protected URL findResource (String name) { for (ClassLoader delegate : delegateClassLoaders) { URL resource = delegate.getResource(name); if (resource != null) return resource; } return null; } protected Enumeration<URL> findResources (String name) throws IOException { Vector<URL> vector = new Vector<URL>(); for (ClassLoader delegate : delegateClassLoaders) { Enumeration<URL> enumeration = delegate.getResources(name); while (enumeration.hasMoreElements()) { vector.add (enumeration.nextElement()); }} return vector.elements(); } } // end class JoinClassLoader