/************************************************************************** * Parts copyright (c) 2001 by Punch Telematix. All rights reserved. * * Parts copyright (c) 2009 by /k/ Embedded Java Solutions. * * All rights reserved. * * * * Redistribution and use in source and binary forms, with or without * * modification, are permitted provided that the following conditions * * are met: * * 1. Redistributions of source code must retain the above copyright * * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * * notice, this list of conditions and the following disclaimer in the * * documentation and/or other materials provided with the distribution. * * 3. Neither the name of Punch Telematix or of /k/ Embedded Java Solutions* * nor the names of other contributors may be used to endorse or promote* * products derived from this software without specific prior written * * permission. * * * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * * IN NO EVENT SHALL PUNCH TELEMATIX, /K/ EMBEDDED JAVA SOLUTIONS OR OTHER * * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * **************************************************************************/ /************************************************************************** * Copyright (c) 2001 by Punch Telematix. All rights reserved. * * * * Redistribution and use in source and binary forms, with or without * * modification, are permitted provided that the following conditions * * are met: * * 1. Redistributions of source code must retain the above copyright * * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * * notice, this list of conditions and the following disclaimer in the * * documentation and/or other materials provided with the distribution. * * 3. Neither the name of Punch Telematix nor the names of * * other contributors may be used to endorse or promote products * * derived from this software without specific prior written permission.* * * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * * IN NO EVENT SHALL PUNCH TELEMATIX OR OTHER CONTRIBUTORS BE LIABLE * * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * **************************************************************************/ package java.net; import java.security.SecureClassLoader; import java.security.PermissionCollection; import java.security.CodeSource; import java.util.jar.Manifest; import java.util.jar.Attributes; import java.io.IOException; import java.util.Vector; import java.util.Enumeration; import wonka.vm.ClassLoaderURLHandler; /** * * $Id: URLClassLoader.java,v 1.2 2006/05/16 08:30:38 cvs Exp $ * */ public class URLClassLoader extends SecureClassLoader{ URL [] urls; ClassLoaderURLHandler[] handlers; private static boolean verbose = false; private static void debug(String s) { if (verbose) { System.err.println(s); } } private static final Manifest emptyMan = new Manifest(); private static void permissionCheck() { // Note: we assume that java.net is a restricted package. if (wonka.vm.SecurityConfiguration.ENABLE_SECURITY_CHECKS) { SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPackageAccess("java.net"); } } } public URLClassLoader(URL[] urls) throws SecurityException { debug("Loading: create URL handlers for " + this); handlers = ClassLoaderURLHandler.createClassLoaderURLHandlers(urls); this.urls = urls; } public URLClassLoader(URL[] urls, ClassLoader parent) throws SecurityException { super(parent); debug("Loading: create URL handlers for " + this); handlers = ClassLoaderURLHandler.createClassLoaderURLHandlers(urls); this.urls = urls; } public URLClassLoader(URL[] urls, ClassLoader parent, URLStreamHandlerFactory factory) throws SecurityException { super(parent); debug("Loading: create URL handlers for " + this); handlers = ClassLoaderURLHandler.createClassLoaderURLHandlers(urls); this.urls = urls; } public static URLClassLoader newInstance(final URL[] urls) throws SecurityException{ permissionCheck(); //TODO: do as a privileged action return new URLClassLoader(urls); } public static URLClassLoader newInstance(final URL[] urls, ClassLoader parent) throws SecurityException{ permissionCheck(); //TODO: do as a privileged action return new URLClassLoader(urls, parent); } protected void addURL(URL url){ debug("Loading: add URL handler to " + this); ClassLoaderURLHandler handler = ClassLoaderURLHandler.createClassLoaderURLHandler(url); debug("Loading: new URL handler = " + handler); int length = handlers.length; ClassLoaderURLHandler[] newhandlers = new ClassLoaderURLHandler[length+1]; System.arraycopy(handlers, 0, newhandlers, 0, length); newhandlers[length] = handler; handlers = newhandlers; URL[] newurls = new URL[urls.length+1]; System.arraycopy(urls, 0, newurls, 0, urls.length); newurls[urls.length] = url; urls = newurls; } protected Package definePackage(String pname, Manifest man, URL url) throws IllegalArgumentException { Attributes attr = man.getMainAttributes(); String specTitle = attr.getValue("Specification-Title"); String specVersion = attr.getValue("Specification-Version"); String specVendor = attr.getValue("Specification-Vendor"); String implTitle = attr.getValue("Implementation-Title"); String implVersion = attr.getValue("Implementation-Version"); String implVendor = attr.getValue("Implementation-Vendor"); return definePackage(pname, specTitle, specVersion, specVendor, implTitle, implVersion, implVendor, url); } protected Class findClass(String name) throws ClassNotFoundException { String filename = name.replace('.','/') + ".class"; int l = handlers.length; for(int i = 0 ; i < l ; i++){ ClassLoaderURLHandler handler = handlers[i]; byte[] bytes = handler.getByteArray(filename); if(bytes != null){ URL url = urls[i]; int idx = name.lastIndexOf('.'); String pname = name.substring(0,idx == -1 ? 0 : idx); // TODO: get manifest right if (getPackage(pname) == null){ definePackage(pname, handler.getManifest() , url); } if(url.getProtocol().equals("jar")) { String u = ("" + url).substring(4); u = u.substring(0, u.indexOf('!')); try { url = new URL(u); } catch(Exception e) { } } return defineClass(name, bytes, 0, bytes.length, new CodeSource(url, (java.security.cert.Certificate[])null)); } } throw new ClassNotFoundException(name); } public URL findResource(String name){ int l = handlers.length; for(int i = 0 ; i < l ; i++){ ClassLoaderURLHandler handler = handlers[i]; URL url = handler.getURL(name); if(url != null){ return url; } } return null; } public Enumeration findResources(String name) throws IOException{ // TODO; wasn't there something about leading slash? int l = handlers.length; Vector v = new Vector(l); for(int i = 0 ; i < l ; i++){ ClassLoaderURLHandler handler = handlers[i]; URL url = handler.getURL(name); if(url != null){ v.add(url); } } return v.elements(); } protected PermissionCollection getPermissions(CodeSource codes){ PermissionCollection pc = super.getPermissions(codes); //ToDo add extra permissions to allow usage of the URL's return pc; } /** ** returns a clone of the original URL array (for securiry reasons). */ public URL[] getURLs(){ return (URL[])urls.clone(); } }