/************************************************************************** * 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 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. * **************************************************************************/ /* ** $Id: NewSystemClassLoader.java,v 1.2 2006/02/17 10:53:19 cvs Exp $ */ package wonka.vm; import java.io.File; import java.io.InputStream; import java.io.IOException; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.net.MalformedURLException; import java.net.URL; import java.security.AllPermission; import java.security.PermissionCollection; import java.security.ProtectionDomain; import java.util.Enumeration; import java.util.Vector; import java.util.jar.JarFile; import java.util.jar.JarEntry; /** The system class loader is a singleton. ** It searches for class and resource files in the system class path, ** e.g. fsroot/system. */ public final class NewSystemClassLoader extends ClassLoader { /** ** The bootstrap classpath, as an array of Zip/JarFile's and/or ** File's (the latter must be directories). */ private static Object[] bootclasspath; /** ** The one and only instance of SystemClassLoader. */ private static NewSystemClassLoader theSystemClassLoader; /** ** A PermissionCollection which contains AllPermission. */ /** ** The unique instance which represents the the System domain. */ private static ProtectionDomain systemProtectionDomain; private static native void setSystemClassLoader(NewSystemClassLoader scl); /** ** Get the identity of the system class loader. ** The instance is created if it does not already exist. ** The caller must have RuntimePermission "getClassLoader". ** (In fact normally this method should only be called by ** java.lang.ClassLoader). ** ** While creating the SystemClassLoader singleton we also create ** the systemProtectionDomain. */ public synchronized static NewSystemClassLoader getInstance() { if (theSystemClassLoader == null) { PermissionCollection theAllPermission; if (wonka.vm.SecurityConfiguration.ENABLE_SECURITY_CHECKS) { theAllPermission = new wonka.security.DefaultPermissionCollection(); theAllPermission.add(new AllPermission()); systemProtectionDomain = new ProtectionDomain(null, theAllPermission); } theSystemClassLoader = new NewSystemClassLoader(); setSystemClassLoader(theSystemClassLoader); } else { if (wonka.vm.SecurityConfiguration.ENABLE_SECURITY_CHECKS) { SecurityManager sm = System.getSecurityManager(); if(sm!=null) { sm.checkPermission(new RuntimePermission("getClassLoader")); } } } return theSystemClassLoader; } /** ** A private constructor, so that only getInstance() can create an instance. ** Its parent is the bootstrap class loader, represented by `null'. ** ** We parse the bootclasspath into its component jarfiles or directories, ** and put them in an array of Object (as JarFile and File respectively). */ private NewSystemClassLoader() { super((ClassLoader)null); Vector v = new Vector(); String bcp = getBootclasspath(); Etc.woempa(9, "SystemClassLoader/<init>: bootclasspath = "+bcp); try { // just to prevent a bootstrapping problem Class.forName("java.util.jar.JarFile"); new ClassCastException(); } catch (ClassNotFoundException e) { e.printStackTrace(); } while (true) { int colon = bcp.indexOf(':'); String s = colon < 0 ? bcp : bcp.substring(0, colon); if (s.endsWith("/")) { v.addElement(new File(s)); } else { try { v.addElement(new JarFile(s, false)); } catch (IOException ioe) { Etc.woempa(9, "SystemClassLoader/<init>: unable to create JarFile" + "(" + s + ") : " + ioe); } } if (colon < 0) { break; } bcp = bcp.substring(colon + 1); } bootclasspath = new Object[v.size()]; Enumeration e = v.elements(); int i = 0; while (e.hasMoreElements()) { bootclasspath[i] = e.nextElement(); Etc.woempa(9, "SystemClassLoader/<init>: bootclasspath["+i+"]: "+bootclasspath[i]); ++i; } } /** **Find the class with a given name, by searching bootclasspath. */ protected Class findClass(String dotname) throws ClassNotFoundException { wonka.vm.Etc.woempa(7, "System Class Loader: findClass("+dotname+")"); String filename = dotname.replace('.','/') + ".class"; byte[] bytes = null; int length = 0; InputStream in = null; wonka.vm.Etc.woempa(7, "System Class Loader: findClass("+dotname+"): filename = " + filename); for (int i = 0; i < bootclasspath.length; ++i) { Etc.woempa(7, "SystemClassLoader/findClass: bootclasspath["+i+"]: "+bootclasspath[i]); try { JarFile jf = (JarFile)bootclasspath[i]; try { wonka.vm.Etc.woempa(7, "System Class Loader: findClass("+dotname+"): seeking in " + jf); JarEntry je = jf.getJarEntry(filename); wonka.vm.Etc.woempa(7, "System Class Loader: findClass("+dotname+"): seeking " + filename + " in " + jf); if (je != null){ length = (int)je.getSize(); in = jf.getInputStream(je); wonka.vm.Etc.woempa(7, "System Class Loader: findClass("+dotname+"): found " + filename + " in " + jf + ", length = " + length); break; } } catch (IOException e){ length = 0; e.printStackTrace(); } } catch (ClassCastException cce) { File f = new File(bootclasspath[i] + filename); wonka.vm.Etc.woempa(7, "System Class Loader: findClass("+dotname+"): seeking file " + f); if (f.isFile()) { try { length = (int)f.length(); in = new FileInputStream(f); wonka.vm.Etc.woempa(7, "System Class Loader: findClass("+dotname+"): found file " + f + ", length = " + length); break; } catch (FileNotFoundException fnfe) { } } } } if (length > 0) { try { bytes = new byte[length]; length = in.read(bytes); int j = filename.lastIndexOf('/'); if(j > 0){ String packagename = dotname.substring(0,j); if (getPackage(packagename) == null) { definePackage(packagename,"","","","","","",null); } } return defineClass(dotname,bytes,0,length,systemProtectionDomain); } catch(IOException ioe) { } } throw new ClassNotFoundException("SystemClassLoader couldn't find "+dotname); } /** ** Private method to see if a resource is present in a particular element ** of bootclasspath. */ private URL tryResource(String name, Object bcpelem) { URL url = null; try { JarFile jf = (JarFile)bcpelem; JarEntry je = jf.getJarEntry(name); if (je != null) { try { url = new URL("jar:" + jf + "!/"+name); } catch (MalformedURLException e) { e.printStackTrace(); } } } catch (ClassCastException cce) { File f = new File(bcpelem + name); if (f.isFile()) { try { url = new URL("file:"+f); } catch (MalformedURLException e) { Etc.woempa(10, "SystemClassLoader: exception = "+e+", file = "+f); //e.printStackTrace(); } } } return url; } /** ** Find the (first) resource with a given name, by searching bootclasspath. */ protected URL findResource(String name) { URL url = null; for (int i = 0; i < bootclasspath.length; ++i) { url = tryResource(name, bootclasspath[i]); if (url != null) { break; } } return url; } public InputStream getResourceAsStream(String name){ for (int i = 0; i < bootclasspath.length; ++i) { try { JarFile jf = (JarFile)bootclasspath[i]; try { JarEntry je = jf.getJarEntry(name); if (je != null){ return jf.getInputStream(je); } } catch (IOException e){} } catch (ClassCastException cce) { File f = new File(bootclasspath[i] + name); if (f.isFile()) { try { return new FileInputStream(f); } catch (FileNotFoundException fnfe) {} } } } return null; } /** ** Find all resources with a given name, by searching bootclasspath. */ protected Enumeration findResources (String name) throws IOException { URL url = null; Vector v = new Vector(); for (int i = 0; i < bootclasspath.length; ++i) { url = tryResource(name, bootclasspath[i]); if (url != null) { v.addElement(url);; } } return v.elements(); } protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException { Class loaded = findLoadedClass(name); if (loaded == null) { loaded = findClass(name); } if (resolve) { try { resolveClass(loaded); } catch (NullPointerException e) {} } return loaded; } public String toString() { return ("System Class Loader"); } private static native String getBootclasspath(); /** ** Enter the standard packages into the `packages' hashtable. ** TODO: get this info from wre.jar or our defined classes. */ private void defineStandardPackages() { definePackage("com.acunia.device","","","","","","",null); definePackage("com.acunia.device.uart","","","","","","",null); definePackage("com.acunia.device.serial","","","","","","",null); definePackage("wonka.resource","","","","","","",null); definePackage("wonka.security","","","","","","",null); definePackage("java.lang","","","","","","",null); definePackage("java.lang.ref","","","","","","",null); definePackage("java.lang.reflect","","","","","","",null); definePackage("java.io","","","","","","",null); definePackage("java.util","","","","","","",null); definePackage("java.net","","","","","","",null); definePackage("java.awt.event","","","","","","",null); definePackage("java.awt","","","","","","",null); definePackage("java.security","","","","","","",null); definePackage("java.security.cert","","","","","","",null); definePackage("java.math","","","","","","",null); definePackage("java.text","","","","","","",null); definePackage("java.rmi","","","","","","",null); definePackage("javax.comm","","","","","","",null); definePackage("wonka.vm","","","","","","",null); } /** Get a list of packages defined by the bootstrap class loader. */ protected Package[] getPackages() { synchronized (this) { if (packages.size() == 0) { defineStandardPackages(); } } Enumeration ownpackages = packages.keys(); Package[] package_array = new Package[packages.size()]; int i = 0; while(ownpackages.hasMoreElements()) { package_array[i++] = (Package)ownpackages.nextElement(); } return package_array; } /** Find a Package defined by the system or bootstrap class loader. */ protected Package getPackage(String pkgname) { synchronized (this) { if (packages.size() == 0) { defineStandardPackages(); } } return (Package)packages.get(pkgname); } }