| /* |
| * @(#)ClassLoader.java 1.162 02/03/19 |
| * |
| * Copyright 2002 Sun Microsystems, Inc. All rights reserved. |
| * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. |
| */ |
| |
| import java.io.InputStream; |
| import java.io.IOException; |
| import java.io.<error descr="Cannot resolve symbol 'StringWriter'">StringWriter</error>; |
| import java.io.<error descr="Cannot resolve symbol 'PrintWriter'">PrintWriter</error>; |
| import java.io.File; |
| import java.lang.reflect.<error descr="Cannot resolve symbol 'Constructor'">Constructor</error>; |
| import java.lang.reflect.<error descr="Cannot resolve symbol 'InvocationTargetException'">InvocationTargetException</error>; |
| import java.util.Hashtable; |
| import java.util.Enumeration; |
| import java.util.<error descr="Cannot resolve symbol 'Vector'">Vector</error>; |
| import java.util.<error descr="Cannot resolve symbol 'Stack'">Stack</error>; |
| import java.util.HashMap; |
| import java.util.<error descr="Cannot resolve symbol 'HashSet'">HashSet</error>; |
| import java.util.Map; |
| import java.util.NoSuchElementException; |
| import java.util.Set; |
| import java.util.<error descr="Cannot resolve symbol 'jar'">jar</error>.Manifest; |
| import java.net.URL; |
| import java.net.MalformedURLException; |
| import java.security.<error descr="Cannot resolve symbol 'AccessController'">AccessController</error>; |
| import java.security.<error descr="Cannot resolve symbol 'AccessControlContext'">AccessControlContext</error>; |
| import java.security.<error descr="Cannot resolve symbol 'PrivilegedAction'">PrivilegedAction</error>; |
| import java.security.<error descr="Cannot resolve symbol 'PrivilegedActionException'">PrivilegedActionException</error>; |
| import java.security.<error descr="Cannot resolve symbol 'PrivilegedExceptionAction'">PrivilegedExceptionAction</error>; |
| import java.security.<error descr="Cannot resolve symbol 'ProtectionDomain'">ProtectionDomain</error>; |
| import java.security.<error descr="Cannot resolve symbol 'Permissions'">Permissions</error>; |
| import java.security.<error descr="Cannot resolve symbol 'CodeSource'">CodeSource</error>; |
| import java.security.Policy; |
| import <error descr="Cannot resolve symbol 'sun'">sun</error>.misc.URLClassPath; |
| import <error descr="Cannot resolve symbol 'sun'">sun</error>.misc.Resource; |
| import <error descr="Cannot resolve symbol 'sun'">sun</error>.misc.CompoundEnumeration; |
| import <error descr="Cannot resolve symbol 'sun'">sun</error>.misc.ClassFileTransformer; |
| //import sun.misc.Launcher; |
| import <error descr="Cannot resolve symbol 'sun'">sun</error>.reflect.Reflection; |
| import <error descr="Cannot resolve symbol 'sun'">sun</error>.security.action.GetPropertyAction; |
| |
| /** |
| * A class loader is an object that is responsible for loading |
| * classes. The class <code>ClassLoader</code> is an abstract class. |
| * Given the name of a class, a class loader should attempt to locate |
| * or generate data that constitutes a definition for the class. A |
| * typical strategy is to transform the name into a file |
| * name and then read a "class file" of that name from a file system. |
| * <p> |
| * Every <code>Class</code> object contains a |
| * {@link Class#getClassLoader() reference} to the |
| * <code>ClassLoader</code> that defined it. |
| * <p> |
| * Class objects for array classes are not created by class loaders, but |
| * are created automatically as required by the Java runtime. The class |
| * loader for an array class, as returned by {@link Class#getClassLoader()} |
| * is the same as the class loader for its element type; if the element |
| * type is a primitive type, then the array class has no class loader. |
| * <p> |
| * Applications implement subclasses of <code>ClassLoader</code> in |
| * order to extend the manner in which the Java virtual machine |
| * dynamically loads classes. |
| * <p> |
| * Class loaders may typically be used by security managers to |
| * indicate security domains. |
| * <p> |
| * The <code>ClassLoader</code> class uses a delegation model to |
| * search for classes and resources. Each instance of |
| * <code>ClassLoader</code> has an associated parent class loader. |
| * When called upon to find a class or resource, a |
| * <code>ClassLoader</code> instance will delegate the search for |
| * the class or resource to its parent class loader before |
| * attempting to find the class or resource itself. The virtual |
| * machine's built-in class loader, called the bootstrap class loader, |
| * does not itself have a parent but may serve as the parent of a |
| * <code>ClassLoader</code> instance. |
| * <p> |
| * Normally, the Java virtual machine loads classes from the local |
| * file system in a platform-dependent manner. For example, on UNIX |
| * systems, the virtual machine loads classes from the directory |
| * defined by the <code>CLASSPATH</code> environment variable. |
| * <p> |
| * However, some classes may not originate from a file; they may |
| * originate from other sources, such as the network, or they could |
| * be constructed by an application. The method |
| * <code>defineClass</code> converts an array of bytes into an |
| * instance of class <code>Class</code>. Instances of this newly |
| * defined class can be created using the <code>newInstance</code> |
| * method in class <code>Class</code>. |
| * <p> |
| * The methods and constructors of objects created by a class loader |
| * may reference other classes. To determine the class(es) referred |
| * to, the Java virtual machine calls the <code>loadClass</code> |
| * method of the class loader that originally created the class. |
| * <p> |
| * For example, an application could create a network class loader |
| * to download class files from a server. Sample code might look like: |
| * <blockquote><pre> |
| * ClassLoader loader = new NetworkClassLoader(host, port); |
| * Object main = loader.loadClass("Main", true).newInstance(); |
| * . . . |
| * </pre></blockquote> |
| * <p> |
| * The network class loader subclass must define the methods |
| * <code>findClass</code> and <code>loadClassData</code> |
| * to load a class from the network. Once it |
| * has downloaded the bytes that make up the class, it should use the |
| * method <code>defineClass</code> to create a class instance. A |
| * sample implementation is: |
| * <p><hr><blockquote><pre> |
| * class NetworkClassLoader extends ClassLoader { |
| * String host; |
| * int port; |
| * |
| * public Class findClass(String name) { |
| * byte[] b = loadClassData(name); |
| * return defineClass(name, b, 0, b.length); |
| * } |
| * |
| * private byte[] loadClassData(String name) { |
| * // load the class data from the connection |
| * . . . |
| * } |
| * } |
| * </pre></blockquote><hr> |
| * |
| * @version 1.162, 03/19/02 |
| * @see java.lang.Class |
| * @see java.lang.Class#newInstance() |
| * @see java.lang.ClassLoader#defineClass(byte[], int, int) |
| * @see java.lang.ClassLoader#loadClass(java.lang.String, boolean) |
| * @see java.lang.ClassLoader#resolveClass(java.lang.Class) |
| * @since JDK1.0 |
| */ |
| abstract class ClassLoader { |
| |
| private static native void registerNatives(); |
| static { |
| registerNatives(); |
| } |
| |
| /* |
| * If initialization succeed this is set to true and security checks will |
| * succeed. Otherwise the object is not initialized and the object is |
| * useless. |
| */ |
| private boolean initialized = false; |
| |
| /* |
| * The parent class loader for delegation. |
| */ |
| private ClassLoader parent; |
| |
| /* |
| * Hashtable that maps packages to certs |
| */ |
| private Hashtable package2certs = new Hashtable(11); |
| |
| /* |
| * shared among all packages with unsigned classes |
| */ |
| java.security.<error descr="Cannot resolve symbol 'cert'">cert</error>.Certificate[] nocerts; |
| |
| /* |
| * The classes loaded by this class loader. The only purpose of this |
| * table is to keep the classes from being GC'ed until the loader |
| * is GC'ed. |
| */ |
| private <error descr="Cannot resolve symbol 'Vector'">Vector</error> classes = new <error descr="Cannot resolve symbol 'Vector'">Vector</error>(); |
| |
| /* |
| * The initiating protection domains for all classes |
| * loaded by this loader. |
| */ |
| private Set domains = new <error descr="Cannot resolve symbol 'HashSet'">HashSet</error>(); |
| |
| /* |
| * Called by the VM to record every loaded class with this loader. |
| */ |
| void addClass(Class c) { |
| classes.<error descr="Cannot resolve method 'addElement(java.lang.Class)'">addElement</error>(c); |
| } |
| |
| /* |
| * The packages defined in this class loader. Each package name is |
| * mapped to its corresponding Package object. |
| */ |
| private HashMap packages = new HashMap(); |
| |
| /** |
| * Creates a new class loader using the specified parent class loader |
| * for delegation. |
| * <p> |
| * If there is a security manager, its <code>checkCreateClassLoader</code> |
| * method is called. This may result in a security exception. |
| * |
| * @param parent the parent class loader |
| * |
| * @throws SecurityException if a security manager exists and its |
| * <code>checkCreateClassLoader</code> method doesn't allow creation of a |
| * new class loader. |
| * @see java.lang.SecurityException |
| * @see java.lang.SecurityManager#checkCreateClassLoader() |
| * @since 1.2 |
| */ |
| protected ClassLoader(ClassLoader parent) { |
| <error descr="Cannot resolve symbol 'SecurityManager'">SecurityManager</error> security = System.getSecurityManager(); |
| if (security != null) { |
| security.<error descr="Cannot resolve method 'checkCreateClassLoader()'">checkCreateClassLoader</error>(); |
| } |
| this.parent = parent; |
| initialized = true; |
| } |
| |
| /** |
| * Creates a new class loader using the <code>ClassLoader</code> |
| * returned by the method <code>getSystemClassLoader()</code> as the |
| * parent class loader. |
| * <p> |
| * If there is a security manager, its <code>checkCreateClassLoader</code> |
| * method is called. This may result in a security exception. |
| * |
| * @throws SecurityException |
| * if a security manager exists and its <code>checkCreateClassLoader</code> |
| * method doesn't allow creation of a new class loader. |
| * |
| * @see java.lang.SecurityException |
| * @see java.lang.SecurityManager#checkCreateClassLoader() |
| */ |
| protected ClassLoader() { |
| <error descr="Cannot resolve symbol 'SecurityManager'">SecurityManager</error> security = System.getSecurityManager(); |
| if (security != null) { |
| security.<error descr="Cannot resolve method 'checkCreateClassLoader()'">checkCreateClassLoader</error>(); |
| } |
| this.parent = getSystemClassLoader(); |
| initialized = true; |
| } |
| |
| /** |
| * Loads the class with the specified name. This method searches for |
| * classes in the same manner as the {@link #loadClass(String, boolean)} |
| * method. It is called by the Java virtual machine to resolve class |
| * references. Calling this method is equivalent to calling |
| * <code>loadClass(name, false)</code>. |
| * |
| * @param name the name of the class |
| * @return the resulting <code>Class</code> object |
| * @exception ClassNotFoundException if the class was not found |
| */ |
| public Class loadClass(String name) throws ClassNotFoundException |
| { |
| return loadClass(name, false); |
| } |
| |
| /** |
| * Loads the class with the specified name. The default implementation of |
| * this method searches for classes in the following order:<p> |
| * |
| * <ol> |
| * <li> Call {@link #findLoadedClass(String)} to check if the class has |
| * already been loaded. <p> |
| * <li> Call the <code>loadClass</code> method on the parent class |
| * loader. If the parent is <code>null</code> the class loader |
| * built-in to the virtual machine is used, instead. <p> |
| * <li> Call the {@link #findClass(String)} method to find the class. <p> |
| * </ol> |
| * |
| * If the class was found using the above steps, and the |
| * <code>resolve</code> flag is true, this method will then call the |
| * {@link #resolveClass(Class)} method on the resulting class object. |
| * <p> |
| * From the Java 2 SDK, v1.2, subclasses of ClassLoader are |
| * encouraged to override |
| * {@link #findClass(String)}, rather than this method.<p> |
| * |
| * @param name the name of the class |
| * @param resolve if <code>true</code> then resolve the class |
| * @return the resulting <code>Class</code> object |
| * @exception ClassNotFoundException if the class could not be found |
| */ |
| protected synchronized Class loadClass(String name, boolean resolve) |
| throws ClassNotFoundException |
| { |
| // First, check if the class has already been loaded |
| Class c = findLoadedClass(name); |
| if (c == null) { |
| try { |
| if (parent != null) { |
| c = parent.loadClass(name, false); |
| } else { |
| c = findBootstrapClass0(name); |
| } |
| } catch (ClassNotFoundException e) { |
| // If still not found, then call findClass in order |
| // to find the class. |
| c = findClass(name); |
| } |
| } |
| if (resolve) { |
| resolveClass(c); |
| } |
| return c; |
| } |
| |
| /* |
| * This method is called by the virtual machine to load |
| * a class. |
| */ |
| private synchronized Class loadClassInternal(String name) |
| throws ClassNotFoundException { |
| |
| return loadClass(name); |
| } |
| |
| private void checkPackageAccess(Class cls, <error descr="Cannot resolve symbol 'ProtectionDomain'">ProtectionDomain</error> pd) { |
| final <error descr="Cannot resolve symbol 'SecurityManager'">SecurityManager</error> sm = System.getSecurityManager(); |
| if (sm != null) { |
| final String name = cls.getName(); |
| final int i = name.lastIndexOf('.'); |
| if (i != -1) { |
| <error descr="Cannot resolve symbol 'AccessController'">AccessController</error>.doPrivileged(new <error descr="Cannot resolve symbol 'PrivilegedAction'">PrivilegedAction</error>() { |
| public Object run() { |
| sm.<error descr="Cannot resolve method 'checkPackageAccess(java.lang.String)'">checkPackageAccess</error>(name.substring(0, i)); |
| return null; |
| } |
| }, new <error descr="Cannot resolve symbol 'AccessControlContext'">AccessControlContext</error>(new <error descr="Cannot resolve symbol 'ProtectionDomain'">ProtectionDomain</error>[] {pd})); |
| } |
| } |
| domains.add<error descr="'add(java.lang.Object)' in 'java.util.Set' cannot be applied to '(ProtectionDomain)'">(pd)</error>; |
| } |
| |
| /** |
| * Finds the specified class. This method should be overridden |
| * by class loader implementations that follow the new delegation model |
| * for loading classes, and will be called by the <code>loadClass</code> |
| * method after checking the parent class loader for the requested class. |
| * The default implementation throws <code>ClassNotFoundException</code>. |
| * |
| * @param name the name of the class |
| * @return the resulting <code>Class</code> object |
| * @exception ClassNotFoundException if the class could not be found |
| * @since 1.2 |
| */ |
| protected Class findClass(String name) throws ClassNotFoundException { |
| throw new ClassNotFoundException(name); |
| } |
| |
| /** |
| * Converts an array of bytes into an instance of class |
| * <code>Class</code>. Before the Class can be used it must be |
| * resolved. This method is deprecated in favor of the version |
| * that takes the class name as its first argument, and is more |
| * secure. |
| * |
| * @param b the bytes that make up the class data. The bytes in |
| * positions <code>off</code> through <code>off+len-1</code> |
| * should have the format of a valid class file as defined |
| * by the |
| * <a href="http://java.sun.com/docs/books/vmspec/">Java |
| * Virtual Machine Specification</a>. |
| * @param off the start offset in <code>b</code> of the class data |
| * @param len the length of the class data |
| * @return the <code>Class</code> object that was created from the |
| * specified class data |
| * @exception ClassFormatError if the data did not contain a valid class |
| * @exception IndexOutOfBoundsException if either <code>off</code> or |
| * <code>len</code> is negative, or if |
| * <code>off+len</code> is greater than <code>b.length</code>. |
| * @see ClassLoader#loadClass(java.lang.String, boolean) |
| * @see ClassLoader#resolveClass(java.lang.Class) |
| * @deprecated Replaced by defineClass(java.lang.String, byte[], int, int) |
| */ |
| protected final Class defineClass(byte[] b, int off, int len) |
| throws <error descr="Cannot resolve symbol 'ClassFormatError'">ClassFormatError</error> |
| { |
| return defineClass(null, b, off, len, null); |
| } |
| |
| /** |
| * Converts an array of bytes into an instance of class <code>Class</code>. |
| * Before the Class can be used it must be resolved. |
| * <p> |
| * This method assigns a default <code>ProtectionDomain</code> to |
| * the newly defined class. The <code>ProtectionDomain</code> |
| * contains the set of permissions granted when |
| * a call to <code>Policy.getPolicy().getPermissions()</code> is made with |
| * a code source of <code>null,null</code>. The default domain is |
| * created on the first invocation of <code>defineClass</code>, and |
| * re-used on subsequent calls. |
| * <p> |
| * To assign a specific <code>ProtectionDomain</code> to the class, |
| * use the <code>defineClass</code> method that takes a |
| * <code>ProtectionDomain</code> as one of its arguments. |
| * |
| * @param name the expected name of the class, or <code>null</code> |
| * if not known, using '.' and not '/' as the separator |
| * and without a trailing ".class" suffix. |
| * @param b the bytes that make up the class data. The bytes in |
| * positions <code>off</code> through <code>off+len-1</code> |
| * should have the format of a valid class file as defined |
| * by the |
| * <a href="http://java.sun.com/docs/books/vmspec/">Java |
| * Virtual Machine Specification</a>. |
| * @param off the start offset in <code>b</code> of the class data |
| * @param len the length of the class data |
| * @return the <code>Class</code> object that was created from the |
| * specified class data |
| * @exception ClassFormatError if the data did not contain a valid class |
| * @exception IndexOutOfBoundsException if either <code>off</code> or |
| * <code>len</code> is negative, or if |
| * <code>off+len</code> is greater than <code>b.length</code>. |
| * @exception SecurityException if an attempt is made to add this class |
| * to a package that contains classes that were signed by |
| * a different set of certificates than this class (which |
| * is unsigned), or if the class name begins with "java.". |
| * |
| * @see ClassLoader#loadClass(java.lang.String, boolean) |
| * @see ClassLoader#resolveClass(java.lang.Class) |
| * @see java.security.ProtectionDomain |
| * @see java.security.Policy |
| * @see java.security.CodeSource |
| * @see java.security.SecureClassLoader |
| * @since JDK1.1 |
| */ |
| protected final Class defineClass(String name, byte[] b, int off, int len) |
| throws <error descr="Cannot resolve symbol 'ClassFormatError'">ClassFormatError</error> |
| { |
| return defineClass(name, b, off, len, null); |
| } |
| |
| /** |
| * Converts an array of bytes into an instance of class Class, |
| * with an optional ProtectionDomain. If the domain is <code>null</code>, |
| * then a default domain will be assigned to the class as specified |
| * in the documentation for {@link #defineClass(String,byte[],int,int)}. |
| * Before the class can be used it must be resolved. |
| * |
| * <p>The first class defined in a package determines the exact set of |
| * certificates that all subsequent classes defined in that package must |
| * contain. The set of certificates for a class is obtained from the |
| * <code>CodeSource</code> within the <code>ProtectionDomain</code> of |
| * the class. Any classes added to that package must contain |
| * the same set of certificates or a <code>SecurityException</code> |
| * will be thrown. Note that if the <code>name</code> argument is |
| * null, this check is not performed. You should always pass in the |
| * name of the class you are defining as well as the bytes. This |
| * ensures that the class you are defining is indeed the class |
| * you think it is. |
| * |
| * <p>The specified class name cannot begin with "java.", since all |
| * classes in the java.* packages can only be defined by the bootstrap |
| * class loader. If the name parameter is not <TT>null</TT>, it |
| * must be equal to the name of the class specified by the byte |
| * array b, otherwise a <TT>ClassFormatError</TT> is raised. |
| * |
| * @param name the expected name of the class, or <code>null</code> |
| * if not known, using '.' and not '/' as the separator |
| * and without a trailing ".class" suffix. |
| * @param b the bytes that make up the class data. The bytes in |
| * positions <code>off</code> through <code>off+len-1</code> |
| * should have the format of a valid class file as defined |
| * by the |
| * <a href="http://java.sun.com/docs/books/vmspec/">Java |
| * Virtual Machine Specification</a>. |
| * @param off the start offset in <code>b</code> of the class data |
| * @param len the length of the class data |
| * @param protectionDomain the ProtectionDomain of the class |
| * @return the <code>Class</code> object created from the data, |
| * and optional ProtectionDomain. |
| * @exception ClassFormatError if the data did not contain a valid class |
| * @exception IndexOutOfBoundsException if either <code>off</code> or |
| * <code>len</code> is negative, or if |
| * <code>off+len</code> is greater than <code>b.length</code>. |
| * @exception SecurityException if an attempt is made to add this class |
| * to a package that contains classes that were signed by |
| * a different set of certificates than this class, or if |
| * the class name begins with "java.". |
| */ |
| protected final Class defineClass(String name, byte[] b, int off, int len, |
| <error descr="Cannot resolve symbol 'ProtectionDomain'">ProtectionDomain</error> protectionDomain) |
| throws <error descr="Cannot resolve symbol 'ClassFormatError'">ClassFormatError</error> |
| { |
| check(); |
| if ((name != null) && name.startsWith("java.")) { |
| throw new <error descr="Cannot resolve symbol 'SecurityException'">SecurityException</error>("Prohibited package name: " + |
| name.substring(0, name.lastIndexOf('.'))); |
| } |
| if (protectionDomain == null) { |
| protectionDomain = getDefaultDomain(); |
| } |
| |
| if (name != null) |
| checkCerts(name, protectionDomain.<error descr="Cannot resolve method 'getCodeSource()'">getCodeSource</error>()); |
| |
| Class c = null; |
| |
| try |
| { |
| c = defineClass0(name, b, off, len, protectionDomain); |
| } |
| catch (<error descr="Cannot resolve symbol 'ClassFormatError'">ClassFormatError</error> cfe) |
| { |
| // Class format error - try to transform the bytecode and |
| // define the class again |
| // |
| Object[] transformers = <error descr="Cannot resolve symbol 'ClassFileTransformer'">ClassFileTransformer</error>.getTransformers(); |
| |
| for (int i=0; transformers != null && i < transformers.length; i++) |
| { |
| try |
| { |
| // Transform byte code using transformer |
| byte[] tb = ((<error descr="Cannot resolve symbol 'ClassFileTransformer'">ClassFileTransformer</error>) transformers[i]).transform(b, off, len); |
| c = defineClass0(name, tb, 0, tb.length, protectionDomain); |
| break; |
| } |
| catch (<error descr="Cannot resolve symbol 'ClassFormatError'">ClassFormatError</error> cfe2) |
| { |
| // If ClassFormatError occurs, try next transformer |
| } |
| } |
| |
| // Rethrow original ClassFormatError if unable to transform |
| // bytecode to well-formed |
| // |
| if (c == null) |
| throw <error descr="Incompatible types. Found: 'ClassFormatError', required: 'java.lang.Throwable'">cfe</error>; |
| } |
| |
| if (protectionDomain.<error descr="Cannot resolve method 'getCodeSource()'">getCodeSource</error>() != null) { |
| java.security.<error descr="Cannot resolve symbol 'cert'">cert</error>.Certificate certs[] = |
| protectionDomain.<error descr="Cannot resolve method 'getCodeSource()'">getCodeSource</error>().getCertificates(); |
| if (certs != null) |
| setSigners<error descr="'setSigners(java.lang.Class, java.lang.Object[])' in 'ClassLoader' cannot be applied to '(java.lang.Class, java.security.cert.Certificate[])'">(c, certs)</error>; |
| } |
| return c; |
| } |
| |
| private synchronized void checkCerts(String name, <error descr="Cannot resolve symbol 'CodeSource'">CodeSource</error> cs) |
| { |
| int i = name.lastIndexOf('.'); |
| String pname = (i == -1) ? "" : name.substring(0,i); |
| java.security.<error descr="Cannot resolve symbol 'cert'">cert</error>.Certificate[] pcerts = |
| (java.security.<error descr="Cannot resolve symbol 'cert'">cert</error>.Certificate[]) package2certs.get(pname); |
| if (pcerts == null) { |
| // first class in this package gets to define which |
| // certificates must be the same for all other classes |
| // in this package |
| if (cs != null) { |
| pcerts = cs.<error descr="Cannot resolve method 'getCertificates()'">getCertificates</error>(); |
| } |
| if (pcerts == null) { |
| if (nocerts == null) |
| nocerts = new java.security.<error descr="Cannot resolve symbol 'cert'">cert</error>.Certificate[0]; |
| pcerts = nocerts; |
| } |
| package2certs.put(pname, pcerts); |
| } else { |
| java.security.<error descr="Cannot resolve symbol 'cert'">cert</error>.Certificate[] certs = null; |
| if (cs != null) { |
| certs = cs.<error descr="Cannot resolve method 'getCertificates()'">getCertificates</error>(); |
| } |
| |
| if (!compareCerts(pcerts,certs)) { |
| throw new <error descr="Cannot resolve symbol 'SecurityException'">SecurityException</error>("class \""+ name+ |
| "\"'s signer information does not match signer information of other classes in the same package"); |
| } |
| } |
| } |
| |
| /** |
| * check to make sure the certs for the new class (certs) are |
| * the same as the certs for the first class inserted |
| * in the package (pcerts) |
| */ |
| private boolean compareCerts(java.security.<error descr="Cannot resolve symbol 'cert'">cert</error>.Certificate[] pcerts, |
| java.security.<error descr="Cannot resolve symbol 'cert'">cert</error>.Certificate[] certs) |
| { |
| // certs can be null, indicating no certs. |
| if ((certs == null) || (certs.length == 0)) { |
| return pcerts.length == 0; |
| } |
| |
| // the length must be the same at this point |
| if (certs.length != pcerts.length) |
| return false; |
| |
| // go through and make sure all the certs in one array |
| // are in the other and vice-versa. |
| boolean match; |
| for (int i=0; i < certs.length; i++) { |
| match = false; |
| for (int j=0; j < pcerts.length; j++) { |
| if (certs[i].<error descr="Cannot resolve method 'equals(java.security.cert.Certificate)'">equals</error>(pcerts[j])) { |
| match = true; |
| break; |
| } |
| } |
| if (!match) return false; |
| } |
| |
| // now do the same for pcerts |
| for (int i=0; i < pcerts.length; i++) { |
| match = false; |
| for (int j=0; j < certs.length; j++) { |
| if (pcerts[i].<error descr="Cannot resolve method 'equals(java.security.cert.Certificate)'">equals</error>(certs[j])) { |
| match = true; |
| break; |
| } |
| } |
| if (!match) return false; |
| } |
| |
| return true; |
| } |
| |
| /** |
| * Links the specified class. |
| * This (misleadingly named) method may be used by a class loader to |
| * link a class. If the class <code>c</code> has already been linked, |
| * then this method simply returns. Otherwise, the class is linked |
| * as described in the "Execution" chapter of the <i>Java Language |
| * Specification</i>. |
| * |
| * @param c the class to link |
| * @exception NullPointerException if <code>c</code> is <code>null</code>. |
| * @see java.lang.ClassLoader#defineClass(java.lang.String,byte[],int,int) |
| */ |
| protected final void resolveClass(Class c) { |
| check(); |
| resolveClass0(c); |
| } |
| |
| /** |
| * Finds a class with the specified name, loading it if necessary.<p> |
| * |
| * Prior to the Java 2 SDK, this method loads a class from the local file |
| * system in a platform-dependent manner, and returns a class object |
| * that has no associated class loader.<p> |
| * |
| * Since the Java 2 SDK v1.2, this method loads the class through the |
| * system class loader(see {@link #getSystemClassLoader()}). Class objects |
| * returned might have <code>ClassLoader</code>s associated with them. |
| * Subclasses of <code>ClassLoader</code> need not usually call this |
| * method, because most class loaders need to override just {@link |
| * #findClass(String)}.<p> |
| * |
| * @param name the name of the class that is to be found |
| * @return the <code>Class</code> object for the specified |
| * <code>name</code> |
| * @exception ClassNotFoundException if the class could not be found |
| * @see #ClassLoader(ClassLoader) |
| * @see #getParent() |
| */ |
| protected final Class findSystemClass(String name) |
| throws ClassNotFoundException |
| { |
| check(); |
| ClassLoader system = getSystemClassLoader(); |
| if (system == null) { |
| return findBootstrapClass(name); |
| } |
| return system.loadClass(name); |
| } |
| |
| /** |
| * Returns the parent class loader for delegation. Some implementations |
| * may use <code>null</code> to represent the bootstrap class |
| * loader. This method will return <code>null</code> in such |
| * implementations if this class loader's parent is the bootstrap |
| * class loader. |
| * <p> |
| * If a security manager is present, and the caller's class loader is |
| * not null and is not an ancestor of this class loader, then |
| * this method calls the security manager's <code>checkPermission</code> |
| * method with a <code>RuntimePermission("getClassLoader")</code> |
| * permission to ensure it's ok to access the parent class loader. |
| * If not, a <code>SecurityException</code> will be thrown. |
| * |
| * @return the parent <code>ClassLoader</code> |
| * @throws SecurityException |
| * if a security manager exists and its |
| * <code>checkPermission</code> method doesn't allow |
| * access to this class loader's parent class loader. |
| * |
| * @see SecurityManager#checkPermission |
| * @see java.lang.RuntimePermission |
| * |
| * @since 1.2 |
| */ |
| public final ClassLoader getParent() { |
| if (parent == null) |
| return null; |
| <error descr="Cannot resolve symbol 'SecurityManager'">SecurityManager</error> sm = System.getSecurityManager(); |
| if (sm != null) { |
| ClassLoader ccl = getCallerClassLoader(); |
| if (ccl != null && !isAncestor(ccl)) { |
| sm.<error descr="Cannot resolve method 'checkPermission(RuntimePermission)'">checkPermission</error>(getGetClassLoaderPerm()); |
| } |
| } |
| return parent; |
| } |
| |
| /** |
| * Sets the signers of a class. This should be called after defining a |
| * class. |
| * |
| * @param c the <code>Class</code> object |
| * @param signers the signers for the class |
| * @since JDK1.1 |
| */ |
| protected final void setSigners(Class c, Object[] signers) { |
| check(); |
| c.<error descr="'setSigners(java.lang.Object[])' is not public in 'java.lang.Class'. Cannot be accessed from outside package">setSigners</error>(signers); |
| } |
| |
| private Class findBootstrapClass0(String name) |
| throws ClassNotFoundException { |
| check(); |
| return findBootstrapClass(name); |
| } |
| |
| private native Class defineClass0(String name, byte[] b, int off, int len, |
| <error descr="Cannot resolve symbol 'ProtectionDomain'">ProtectionDomain</error> pd); |
| private native void resolveClass0(Class c); |
| private native Class findBootstrapClass(String name) |
| throws ClassNotFoundException; |
| |
| /* |
| * Check to make sure the class loader has been initialized. |
| */ |
| private void check() { |
| if (!initialized) { |
| throw new <error descr="Cannot resolve symbol 'SecurityException'">SecurityException</error>("ClassLoader object not initialized"); |
| } |
| } |
| |
| /** |
| * Finds the class with the given name if it had been previously loaded |
| * through this class loader. |
| * |
| * @param name the class name |
| * @return the <code>Class</code> object, or <code>null</code> if |
| * the class has not been loaded |
| * @since JDK1.1 |
| */ |
| protected native final Class findLoadedClass(String name); |
| |
| /** |
| * Finds the resource with the given name. A resource is some data |
| * (images, audio, text, etc) that can be accessed by class code in a way |
| * that is independent of the location of the code.<p> |
| * |
| * The name of a resource is a "/"-separated path name that identifies |
| * the resource.<p> |
| * |
| * This method will first search the parent class loader for the resource; |
| * if the parent is <code>null</code> the path of the class loader |
| * built-in to the virtual machine is searched. That failing, this method |
| * will call <code>findResource</code> to find the resource.<p> |
| * |
| * @param name resource name |
| * @return a URL for reading the resource, or <code>null</code> if |
| * the resource could not be found or the caller doesn't have |
| * adequate privileges to get the resource. |
| * @since JDK1.1 |
| * @see #findResource(String) |
| */ |
| public URL getResource(String name) { |
| URL url; |
| if (parent != null) { |
| url = parent.getResource(name); |
| } else { |
| url = getBootstrapResource(name); |
| } |
| if (url == null) { |
| url = findResource(name); |
| } |
| return url; |
| } |
| |
| /** |
| * Finds all the resources with the given name. A resource is some data |
| * (images, audio, text, etc) that can be accessed by class code in a way |
| * that is independent of the location of the code.<p> |
| * |
| * The name of a resource is a "/"-separated path name that identifies the |
| * resource.<p> |
| * |
| * The search order is described in the documentation for {@link |
| * #getResource(String)}.<p> |
| * |
| * @param name resource name |
| * @return an enumeration of URL to the resource. If no resources could |
| * be found, the enumeration will be empty. Resources that the |
| * doesn't have access to will not be in the enumeration. |
| * @throws IOException if I/O errors occur |
| * @since 1.2 |
| * @see #getResource |
| * @see #findResources |
| */ |
| public final Enumeration getResources(String name) throws IOException { |
| Enumeration[] tmp = new Enumeration[2]; |
| if (parent != null) { |
| tmp[0] = parent.getResources(name); |
| } else { |
| tmp[0] = getBootstrapResources(name); |
| } |
| tmp[1] = findResources(name); |
| |
| return new <error descr="Cannot resolve symbol 'CompoundEnumeration'">CompoundEnumeration</error>(tmp); |
| } |
| |
| /** |
| * Returns an Enumeration of URLs representing all the resources with |
| * the given name. Class loader implementations should override this |
| * method to specify where to load resources from. |
| * |
| * @param name the resource name |
| * @return an Enumeration of URLs for the resources |
| * @throws IOException if I/O errors occur |
| * @since 1.2 |
| */ |
| protected Enumeration findResources(String name) throws IOException { |
| return new <error descr="Cannot resolve symbol 'CompoundEnumeration'">CompoundEnumeration</error>(new Enumeration[0]); |
| } |
| |
| /** |
| * Finds the resource with the given name. Class loader |
| * implementations should override this method to specify where to |
| * find resources. |
| * |
| * @param name the resource name |
| * @return a URL for reading the resource, or <code>null</code> |
| * if the resource could not be found |
| * @since 1.2 |
| */ |
| protected URL findResource(String name) { |
| return null; |
| } |
| |
| /** |
| * Find a resource of the specified name from the search path used to load |
| * classes.<p> |
| * |
| * In JDK1.1, the search path used is that of the virtual machine's |
| * built-in class loader.<p> |
| * |
| * Since the Java 2 SDK v1.2, this method locates the resource through the system class |
| * loader (see {@link #getSystemClassLoader()}). |
| * |
| * @param name the resource name |
| * @return a URL for reading the resource, or <code>null</code> if |
| * the resource could not be found |
| * @since JDK1.1 |
| */ |
| public static URL getSystemResource(String name) { |
| ClassLoader system = getSystemClassLoader(); |
| if (system == null) { |
| return getBootstrapResource(name); |
| } |
| return system.getResource(name); |
| } |
| |
| /** |
| * Find resources from the VM's built-in classloader. |
| */ |
| private static URL getBootstrapResource(String name) { |
| <error descr="Cannot resolve symbol 'URLClassPath'">URLClassPath</error> ucp = getBootstrapClassPath(); |
| <error descr="Cannot resolve symbol 'Resource'">Resource</error> res = ucp.<error descr="Cannot resolve method 'getResource(java.lang.String)'">getResource</error>(name); |
| return res != null ? res.<error descr="Cannot resolve method 'getURL()'">getURL</error>() : null; |
| } |
| |
| /** |
| * Finds all resources of the specified name from the search path used to |
| * load classes. The resources thus found are returned as an |
| * <code>Enumeration</code> of <code>URL</code> objects. <p> |
| * |
| * The search order is described in the documentation for {@link |
| * #getSystemResource(String)}. <p> |
| * |
| * @param name the resource name |
| * @return an enumeration of resource URLs |
| * @throws IOException if I/O errors occur |
| * @since 1.2 |
| */ |
| public static Enumeration getSystemResources(String name) |
| throws IOException |
| { |
| ClassLoader system = getSystemClassLoader(); |
| if (system == null) { |
| return getBootstrapResources(name); |
| } |
| return system.getResources(name); |
| } |
| |
| /** |
| * Find resources from the VM's built-in classloader. |
| */ |
| private static Enumeration getBootstrapResources(String name) |
| throws IOException |
| { |
| final Enumeration e = getBootstrapClassPath().<error descr="Cannot resolve method 'getResources(java.lang.String)'">getResources</error>(name); |
| return new Enumeration () { |
| public Object nextElement() { |
| return ((<error descr="Cannot resolve symbol 'Resource'">Resource</error>)e.nextElement()).getURL(); |
| } |
| public boolean hasMoreElements() { |
| return e.hasMoreElements(); |
| } |
| }; |
| } |
| |
| /* |
| * Returns the URLClassPath that is used for finding system resources. |
| */ |
| static <error descr="Cannot resolve symbol 'URLClassPath'">URLClassPath</error> getBootstrapClassPath() { |
| if (bootstrapClassPath == null) { |
| bootstrapClassPath = <error descr="Cannot resolve symbol 'sun'">sun</error>.misc.Launcher.getBootstrapClassPath(); |
| } |
| return bootstrapClassPath; |
| } |
| |
| private static <error descr="Cannot resolve symbol 'URLClassPath'">URLClassPath</error> bootstrapClassPath; |
| |
| /** |
| * Returns an input stream for reading the specified resource. |
| * |
| * The search order is described in the documentation for {@link |
| * #getResource(String)}.<p> |
| * |
| * @param name the resource name |
| * @return an input stream for reading the resource, or <code>null</code> |
| * if the resource could not be found |
| * @since JDK1.1 |
| */ |
| public InputStream getResourceAsStream(String name) { |
| URL url = getResource(name); |
| try { |
| return url != null ? url.openStream() : null; |
| } catch (IOException e) { |
| return null; |
| } |
| } |
| |
| /** |
| * Open for reading, a resource of the specified name from the search path |
| * used to load classes.<p> |
| * |
| * The search order is described in the documentation for {@link |
| * #getSystemResource(String)}. <p> |
| * |
| * @param name the resource name |
| * @return an input stream for reading the resource, or <code>null</code> |
| * if the resource could not be found |
| * @since JDK1.1 |
| */ |
| public static InputStream getSystemResourceAsStream(String name) { |
| URL url = getSystemResource(name); |
| try { |
| return url != null ? url.openStream() : null; |
| } catch (IOException e) { |
| return null; |
| } |
| } |
| |
| /** |
| * Returns the system class loader for delegation. This is the default |
| * delegation parent for new <code>ClassLoader</code> instances, and |
| * is typically the class loader used to start the application. |
| * <p> |
| * This method is first invoked early in the runtime's startup |
| * sequence, at which point it creates the system class loader |
| * and sets it as the context class loader of the invoking |
| * <tt>Thread</tt>. |
| * <p> |
| * The default system class loader is an implementation-dependent |
| * instance of this class. |
| * <p> |
| * If the system property <tt>java.system.class.loader</tt> is |
| * defined when this method is first invoked then the value of that |
| * property is taken to be the name of a class that will be returned as |
| * the system class loader. The class is loaded using the default system |
| * class loader and must define a public constructor that takes a single |
| * parameter of type <tt>ClassLoader</tt> which is used |
| * as the delegation parent. An instance is then created using this |
| * constructor with the default system class loader as the parameter. |
| * The resulting class loader is defined to be the system class loader. |
| * <p> |
| * If a security manager is present, and the caller's class loader is |
| * not null and the caller's class loader is not the same as or an ancestor of |
| * the system class loader, then |
| * this method calls the security manager's <code>checkPermission</code> |
| * method with a <code>RuntimePermission("getClassLoader")</code> |
| * permission to ensure it's ok to access the system class loader. |
| * If not, a <code>SecurityException</code> will be thrown. |
| * |
| * @return the system <code>ClassLoader</code> for delegation, or |
| * <code>null</code> if none |
| * @throws SecurityException |
| * if a security manager exists and its |
| * <code>checkPermission</code> method doesn't allow |
| * access to the system class loader. |
| * @throws IllegalStateException |
| * if invoked recursively during the construction |
| * of the class loader specified by the |
| * <code>java.system.class.loader</code> property. |
| * @throws Error |
| * if the system property <tt>java.system.class.loader</tt> |
| * is defined but the named class could not be loaded, the |
| * provider class does not define the required constructor, or an |
| * exception is thrown by that constructor when it is invoked. The |
| * underlying cause of the error can be retrieved via the |
| * {@link Throwable#getCause()} method. |
| * @see SecurityManager#checkPermission |
| * @see java.lang.RuntimePermission |
| * @revised 1.4 |
| */ |
| public static ClassLoader getSystemClassLoader() { |
| initSystemClassLoader(); |
| if (scl == null) { |
| return null; |
| } |
| <error descr="Cannot resolve symbol 'SecurityManager'">SecurityManager</error> sm = System.getSecurityManager(); |
| if (sm != null) { |
| ClassLoader ccl = getCallerClassLoader(); |
| if (ccl != null && ccl != scl && !scl.isAncestor(ccl)) { |
| sm.<error descr="Cannot resolve method 'checkPermission(RuntimePermission)'">checkPermission</error>(getGetClassLoaderPerm()); |
| } |
| } |
| return scl; |
| } |
| |
| private static synchronized void initSystemClassLoader() { |
| if (!sclSet) { |
| if (scl != null) |
| throw new IllegalStateException("recursive call"); |
| <error descr="Cannot resolve symbol 'sun'">sun</error>.misc.Launcher l = <error descr="Cannot resolve symbol 'sun'">sun</error>.misc.Launcher.getLauncher(); |
| if (l != null) { |
| Throwable oops = null; |
| scl = l.<error descr="Cannot resolve method 'getClassLoader()'">getClassLoader</error>(); |
| try { |
| <error descr="Cannot resolve symbol 'PrivilegedExceptionAction'">PrivilegedExceptionAction</error> a; |
| <error descr="Incompatible types. Found: 'SystemClassLoaderAction', required: 'PrivilegedExceptionAction'">a = new SystemClassLoaderAction(scl)</error>; |
| scl = (ClassLoader) <error descr="Cannot resolve symbol 'AccessController'">AccessController</error>.doPrivileged(a); |
| } catch (<error descr="Cannot resolve symbol 'PrivilegedActionException'">PrivilegedActionException</error> pae) { |
| oops = pae.<error descr="Cannot resolve method 'getCause()'">getCause</error>(); |
| if (oops instanceof <error descr="Cannot resolve symbol 'InvocationTargetException'">InvocationTargetException</error>) { |
| oops = oops.getCause(); |
| } |
| } |
| if (oops != null) { |
| if (oops instanceof Error) { |
| throw (Error) oops; |
| } else { |
| // wrap the exception |
| throw new Error(oops); |
| } |
| } |
| } |
| sclSet = true; |
| } |
| } |
| |
| // Returns true if the specified class loader can be found |
| // in this class loader's delegation chain. |
| boolean isAncestor(ClassLoader cl) { |
| ClassLoader acl = this; |
| do { |
| acl = acl.parent; |
| if (cl == acl) { |
| return true; |
| } |
| } while (acl != null); |
| return false; |
| } |
| |
| // Returns the caller's class loader, or null if none. |
| // NOTE this must always be called when there is exactly one |
| // intervening frame from the core libraries on the stack between |
| // this method's invocation and the desired caller. |
| static ClassLoader getCallerClassLoader() { |
| // NOTE use of more generic Reflection.getCallerClass() |
| Class caller = <error descr="Cannot resolve symbol 'Reflection'">Reflection</error>.getCallerClass(3); |
| // This can be null if the VM is requesting it |
| if (caller == null) { |
| return null; |
| } |
| // Circumvent security check since this is package-private |
| return caller.<error descr="'getClassLoader0()' is not public in 'java.lang.Class'. Cannot be accessed from outside package">getClassLoader0</error>(); |
| } |
| |
| // The class loader for the system |
| private static ClassLoader scl; |
| |
| // Set to true once the system class loader has been set |
| private static boolean sclSet; |
| |
| // Permission to access system or parent class loader |
| private static <error descr="Cannot resolve symbol 'RuntimePermission'">RuntimePermission</error> getClassLoaderPerm = null; |
| |
| static <error descr="Cannot resolve symbol 'RuntimePermission'">RuntimePermission</error> getGetClassLoaderPerm() |
| { |
| if (getClassLoaderPerm == null) |
| getClassLoaderPerm = new <error descr="Cannot resolve symbol 'RuntimePermission'">RuntimePermission</error>("getClassLoader"); |
| return getClassLoaderPerm; |
| } |
| |
| /** |
| * Defines a package by name in this ClassLoader. This allows class |
| * loaders to define the packages for their classes. Packages must be |
| * created before the class is defined, and package names must be |
| * unique within a class loader and cannot be redefined or changed |
| * once created. |
| * |
| * @param name the package name |
| * @param specTitle the specification title |
| * @param specVersion the specification version |
| * @param specVendor the specification vendor |
| * @param implTitle the implementation title |
| * @param implVersion the implementation version |
| * @param implVendor the implementation vendor |
| * @param sealBase If not null, then this package is sealed with |
| * respect to the given code source URL. Otherwise, |
| * the package is not sealed. |
| * @return the newly defined <code>Package</code> object |
| * @exception IllegalArgumentException if package name duplicates an |
| * existing package either in this class loader or one of |
| * its ancestors |
| * @since 1.2 |
| */ |
| protected <error descr="Cannot resolve symbol 'Package'">Package</error> definePackage(String name, String specTitle, |
| String specVersion, String specVendor, |
| String implTitle, String implVersion, |
| String implVendor, URL sealBase) |
| throws IllegalArgumentException |
| { |
| synchronized (packages) { |
| <error descr="Cannot resolve symbol 'Package'">Package</error> pkg = getPackage(name); |
| if (pkg != null) { |
| throw new IllegalArgumentException(name); |
| } |
| pkg = new <error descr="Cannot resolve symbol 'Package'">Package</error>(name, specTitle, specVersion, specVendor, |
| implTitle, implVersion, implVendor, |
| sealBase); |
| packages.put<error descr="'put(java.lang.Object, java.lang.Object)' in 'java.util.HashMap' cannot be applied to '(java.lang.String, Package)'">(name, pkg)</error>; |
| return pkg; |
| } |
| } |
| |
| /** |
| * Returns a Package that has been defined by this class loader or any |
| * of its ancestors. |
| * |
| * @param name the package name |
| * @return the Package corresponding to the given name, or null if not |
| * found |
| * @since 1.2 |
| */ |
| protected <error descr="Cannot resolve symbol 'Package'">Package</error> getPackage(String name) { |
| synchronized (packages) { |
| <error descr="Cannot resolve symbol 'Package'">Package</error> pkg = (<error descr="Cannot resolve symbol 'Package'">Package</error>)packages.get(name); |
| if (pkg == null) { |
| if (parent != null) { |
| pkg = parent.getPackage(name); |
| } else { |
| pkg = <error descr="Cannot resolve symbol 'Package'">Package</error>.getSystemPackage(name); |
| } |
| if (pkg != null) { |
| packages.put<error descr="'put(java.lang.Object, java.lang.Object)' in 'java.util.HashMap' cannot be applied to '(java.lang.String, Package)'">(name, pkg)</error>; |
| } |
| } |
| return pkg; |
| } |
| } |
| |
| /** |
| * Returns all of the Packages defined by this class loader and its |
| * ancestors. |
| * |
| * @return the array of <code>Package</code> objects defined by this |
| * <code>ClassLoader</code> |
| * @since 1.2 |
| */ |
| protected <error descr="Cannot resolve symbol 'Package'">Package</error>[] getPackages() { |
| Map map; |
| synchronized (packages) { |
| map = (Map)packages.clone(); |
| } |
| <error descr="Cannot resolve symbol 'Package'">Package</error>[] pkgs; |
| if (parent != null) { |
| pkgs = parent.getPackages(); |
| } else { |
| pkgs = <error descr="Cannot resolve symbol 'Package'">Package</error>.getSystemPackages(); |
| } |
| if (pkgs != null) { |
| for (int i = 0; i < pkgs.length; i++) { |
| String pkgName = pkgs[i].<error descr="Cannot resolve method 'getName()'">getName</error>(); |
| if (map.get(pkgName) == null) { |
| map.put<error descr="'put(java.lang.Object, java.lang.Object)' in 'java.util.Map' cannot be applied to '(java.lang.String, Package)'">(pkgName, pkgs[i])</error>; |
| } |
| } |
| } |
| return (<error descr="Cannot resolve symbol 'Package'">Package</error>[])map.values().toArray(new <error descr="Cannot resolve symbol 'Package'">Package</error>[map.size()]); |
| } |
| |
| /** |
| * Returns the absolute path name of a native library. The VM |
| * invokes this method to locate the native libraries that belong |
| * to classes loaded with this class loader. If this method returns |
| * <code>null</code>, the VM searches the library along the path |
| * specified as the <code>java.library.path</code> property. |
| * |
| * @param libname the library name |
| * @return the absolute path of the native library |
| * @see java.lang.System#loadLibrary(java.lang.String) |
| * @see java.lang.System#mapLibraryName(java.lang.String) |
| * @since 1.2 |
| */ |
| protected String findLibrary(String libname) { |
| return null; |
| } |
| |
| /** |
| * The inner class NativeLibrary denotes a loaded native library |
| * instance. Every classloader contains a vector of loaded native |
| * libraries in the private field <code>nativeLibraries</code>. |
| * The native libraries loaded into the system are entered into |
| * the <code>systemNativeLibraries</code> vector. |
| * |
| * Every native library reuqires a particular version of JNI. This |
| * is denoted by the private jniVersion field. This field is set |
| * by the VM when it loads the library, and used by the VM to pass |
| * the correct version of JNI to the native methods. |
| * |
| * @version 1.162, 03/19/02 |
| * @see java.lang.ClassLoader |
| * @since 1.2 |
| */ |
| static class NativeLibrary { |
| /* opaque handle to native library, used in native code. */ |
| long handle; |
| /* the version of JNI environment the native library requires. */ |
| private int jniVersion; |
| /* the class from which the library is loaded, also indicates |
| the loader this native library belongs. */ |
| private Class fromClass; |
| /* the canonicalized name of the native library. */ |
| String name; |
| |
| native void load(String name); |
| native long find(String name); |
| native void unload(); |
| |
| public NativeLibrary(Class fromClass, String name) { |
| this.name = name; |
| this.fromClass = fromClass; |
| } |
| |
| protected void finalize() { |
| synchronized (loadedLibraryNames) { |
| if (fromClass.getClassLoader() != null && handle != 0) { |
| /* remove the native library name */ |
| int size = loadedLibraryNames.<error descr="Cannot resolve method 'size()'">size</error>(); |
| for (int i = 0; i < size; i++) { |
| if (name.equals(loadedLibraryNames.<error descr="Cannot resolve method 'elementAt(int)'">elementAt</error>(i))) { |
| loadedLibraryNames.<error descr="Cannot resolve method 'removeElementAt(int)'">removeElementAt</error>(i); |
| break; |
| } |
| } |
| /* unload the library. */ |
| ClassLoader.nativeLibraryContext.<error descr="Cannot resolve method 'push(ClassLoader.NativeLibrary)'">push</error>(this); |
| try { |
| unload(); |
| } finally { |
| ClassLoader.nativeLibraryContext.<error descr="Cannot resolve method 'pop()'">pop</error>(); |
| } |
| } |
| } |
| } |
| /* Called in the VM to determine the context class in |
| JNI_Load/JNI_Unload */ |
| static Class getFromClass() { |
| return ((NativeLibrary) |
| (ClassLoader.nativeLibraryContext.<error descr="Cannot resolve method 'peek()'">peek</error>())).fromClass; |
| } |
| } |
| |
| /* the "default" domain. Set as the default ProtectionDomain |
| * on newly created classses. |
| */ |
| private <error descr="Cannot resolve symbol 'ProtectionDomain'">ProtectionDomain</error> defaultDomain = null; |
| |
| /* |
| * returns (and initializes) the default domain. |
| */ |
| |
| private synchronized <error descr="Cannot resolve symbol 'ProtectionDomain'">ProtectionDomain</error> getDefaultDomain() { |
| if (defaultDomain == null) { |
| <error descr="Cannot resolve symbol 'CodeSource'">CodeSource</error> cs = new <error descr="Cannot resolve symbol 'CodeSource'">CodeSource</error>(null, null); |
| defaultDomain = new <error descr="Cannot resolve symbol 'ProtectionDomain'">ProtectionDomain</error>(cs, null, this, null); |
| } |
| return defaultDomain; |
| } |
| |
| /* All native library names we've loaded. */ |
| private static <error descr="Cannot resolve symbol 'Vector'">Vector</error> loadedLibraryNames = new <error descr="Cannot resolve symbol 'Vector'">Vector</error>(); |
| /* Native libraries belonging to system classes. */ |
| private static <error descr="Cannot resolve symbol 'Vector'">Vector</error> systemNativeLibraries = new <error descr="Cannot resolve symbol 'Vector'">Vector</error>(); |
| /* Native libraries associated with the class loader. */ |
| private <error descr="Cannot resolve symbol 'Vector'">Vector</error> nativeLibraries = new <error descr="Cannot resolve symbol 'Vector'">Vector</error>(); |
| |
| /* native libraries being loaded/unloaded. */ |
| private static <error descr="Cannot resolve symbol 'Stack'">Stack</error> nativeLibraryContext = new <error descr="Cannot resolve symbol 'Stack'">Stack</error>(); |
| |
| /* The paths searched for libraries */ |
| static private String usr_paths[]; |
| static private String sys_paths[]; |
| |
| private static String[] initializePath(String propname) { |
| String ldpath = System.getProperty(propname, ""); |
| String ps = File.pathSeparator; |
| int ldlen = ldpath.length(); |
| int i, j, n; |
| // Count the separators in the path |
| i = ldpath.indexOf(ps); |
| n = 0; |
| while (i >= 0) { |
| n++; |
| i = ldpath.indexOf(ps, i+1); |
| } |
| |
| // allocate the array of paths - n :'s = n + 1 path elements |
| String[] paths = new String[n + 1]; |
| |
| // Fill the array with paths from the ldpath |
| n = i = 0; |
| j = ldpath.indexOf(ps); |
| while (j >= 0) { |
| if (j - i > 0) { |
| paths[n++] = ldpath.substring(i, j); |
| } else if (j - i == 0) { |
| paths[n++] = "."; |
| } |
| i = j + 1; |
| j = ldpath.indexOf(ps, i); |
| } |
| paths[n] = ldpath.substring(i, ldlen); |
| return paths; |
| } |
| |
| |
| /* Called in the java.lang.Runtime class to implement load |
| * and loadLibrary. |
| */ |
| static void loadLibrary(Class fromClass, String name, |
| boolean isAbsolute) { |
| <error descr="Incompatible types. Found: 'java.lang.ClassLoader', required: 'ClassLoader'">ClassLoader loader = |
| (fromClass == null) ? null : fromClass.getClassLoader();</error> |
| if (sys_paths == null) { |
| usr_paths = initializePath("java.library.path"); |
| sys_paths = initializePath("sun.boot.library.path"); |
| } |
| if (isAbsolute) { |
| if (loadLibrary0(fromClass, new File(name))) { |
| return; |
| } |
| throw new <error descr="Cannot resolve symbol 'UnsatisfiedLinkError'">UnsatisfiedLinkError</error>("Can't load library: " + name); |
| } |
| if (loader != null) { |
| String libfilename = loader.findLibrary(name); |
| if (libfilename != null) { |
| File libfile = new File(libfilename); |
| if (!libfile.isAbsolute()) { |
| throw new <error descr="Cannot resolve symbol 'UnsatisfiedLinkError'">UnsatisfiedLinkError</error>( |
| "ClassLoader.findLibrary failed to return an absolute path: " + libfilename); |
| } |
| if (loadLibrary0(fromClass, libfile)) { |
| return; |
| } |
| throw new <error descr="Cannot resolve symbol 'UnsatisfiedLinkError'">UnsatisfiedLinkError</error> ("Can't load " + libfilename); |
| } |
| } |
| for (int i = 0 ; i < sys_paths.length ; i++) { |
| File libfile = new File(sys_paths[i], System.mapLibraryName(name)); |
| if (loadLibrary0(fromClass, libfile)) { |
| return; |
| } |
| } |
| if (loader != null) { |
| for (int i = 0 ; i < usr_paths.length ; i++) { |
| File libfile = new File(usr_paths[i], |
| System.mapLibraryName(name)); |
| if (loadLibrary0(fromClass, libfile)) { |
| return; |
| } |
| } |
| } |
| // Oops, it failed |
| throw new <error descr="Cannot resolve symbol 'UnsatisfiedLinkError'">UnsatisfiedLinkError</error>("no " + name + " in java.library.path"); |
| } |
| |
| private static boolean loadLibrary0(Class fromClass, final File file) { |
| Boolean exists = (Boolean) |
| <error descr="Cannot resolve symbol 'AccessController'">AccessController</error>.doPrivileged(new <error descr="Cannot resolve symbol 'PrivilegedAction'">PrivilegedAction</error>() { |
| public Object run() { |
| return new Boolean(file.exists()); |
| } |
| }); |
| if (!exists.booleanValue()) { |
| return false; |
| } |
| String name; |
| try { |
| name = file.getCanonicalPath(); |
| } catch (IOException e) { |
| return false; |
| } |
| <error descr="Incompatible types. Found: 'java.lang.ClassLoader', required: 'ClassLoader'">ClassLoader loader = |
| (fromClass == null) ? null : fromClass.getClassLoader();</error> |
| <error descr="Cannot resolve symbol 'Vector'">Vector</error> libs = |
| loader != null ? loader.nativeLibraries : systemNativeLibraries; |
| synchronized (libs) { |
| int size = libs.<error descr="Cannot resolve method 'size()'">size</error>(); |
| for (int i = 0; i < size; i++) { |
| NativeLibrary lib = (NativeLibrary)libs.<error descr="Cannot resolve method 'elementAt(int)'">elementAt</error>(i); |
| if (name.equals(lib.name)) { |
| return true; |
| } |
| } |
| |
| synchronized (loadedLibraryNames) { |
| if (loadedLibraryNames.<error descr="Cannot resolve method 'contains(java.lang.String)'">contains</error>(name)) { |
| throw new <error descr="Cannot resolve symbol 'UnsatisfiedLinkError'">UnsatisfiedLinkError</error> |
| ("Native Library " + |
| name + |
| " already loaded in another classloader"); |
| } |
| /* If the library is being loaded (must be by |
| * the same thread, because Runtime.load and |
| * Runtime.loadLibrary are synchronous). The |
| * reason is can occur is that the JNI_OnLoad |
| * function can cause another loadLibrary call. |
| * |
| * Thus we can use a static stack to hold the list |
| * of libraries we are loading. |
| * |
| * If there is a pending load operation for the |
| * library, we immediately return success; otherwise, |
| * we raise UnsatisfiedLinkError. |
| */ |
| int n = nativeLibraryContext.<error descr="Cannot resolve method 'size()'">size</error>(); |
| for (int i = 0; i < n; i++) { |
| NativeLibrary lib = (NativeLibrary) |
| nativeLibraryContext.<error descr="Cannot resolve method 'elementAt(int)'">elementAt</error>(i); |
| if (name.equals(lib.name)) { |
| if (<error descr="Operator '==' cannot be applied to 'ClassLoader', 'java.lang.ClassLoader'">loader == lib.fromClass.getClassLoader()</error>) { |
| return true; |
| } else { |
| throw new <error descr="Cannot resolve symbol 'UnsatisfiedLinkError'">UnsatisfiedLinkError</error> |
| ("Native Library " + |
| name + |
| " is being loaded in another classloader"); |
| } |
| } |
| } |
| NativeLibrary lib = new NativeLibrary(fromClass, name); |
| nativeLibraryContext.<error descr="Cannot resolve method 'push(ClassLoader.NativeLibrary)'">push</error>(lib); |
| try { |
| lib.load(name); |
| } finally { |
| nativeLibraryContext.<error descr="Cannot resolve method 'pop()'">pop</error>(); |
| } |
| if (lib.handle != 0) { |
| loadedLibraryNames.<error descr="Cannot resolve method 'addElement(java.lang.String)'">addElement</error>(name); |
| libs.<error descr="Cannot resolve method 'addElement(ClassLoader.NativeLibrary)'">addElement</error>(lib); |
| return true; |
| } |
| return false; |
| } |
| } |
| } |
| |
| /* Called in the VM class linking code. */ |
| static long findNative(ClassLoader loader, String name) { |
| <error descr="Cannot resolve symbol 'Vector'">Vector</error> libs = |
| loader != null ? loader.nativeLibraries : systemNativeLibraries; |
| synchronized (libs) { |
| int size = libs.<error descr="Cannot resolve method 'size()'">size</error>(); |
| for (int i = 0; i < size; i++) { |
| NativeLibrary lib = (NativeLibrary)libs.<error descr="Cannot resolve method 'elementAt(int)'">elementAt</error>(i); |
| long entry = lib.find(name); |
| if (entry != 0) |
| return entry; |
| } |
| } |
| return 0; |
| } |
| |
| /* |
| * The default toggle for assertion checking. |
| */ |
| private boolean defaultAssertionStatus = false; |
| |
| /* |
| * Maps String packageName to Boolean package default assertion status |
| * Note that the default package is placed under a null map key. |
| * If this field is null then we are delegating assertion status queries |
| * to the VM, i.e., none of this ClassLoader's assertion status |
| * modification methods have been called. |
| */ |
| private Map packageAssertionStatus = null; |
| |
| /* |
| * Maps String fullyQualifiedClassName to Boolean assertionStatus |
| * If this field is null then we are delegating assertion status queries |
| * to the VM, i.e., none of this ClassLoader's assertion status |
| * modification methods have been called. |
| */ |
| Map classAssertionStatus = null; |
| |
| /** |
| * Sets the default assertion status for this class loader. This setting |
| * determines whether classes loaded by this class loader and initialized |
| * in the future will have assertions enabled or disabled by default. |
| * This setting may be overridden on a per-package or per-class basis by |
| * invoking {@link #setPackageAssertionStatus(String,boolean)} or {@link |
| * #setClassAssertionStatus(String,boolean)}. |
| * |
| * @param enabled <tt>true</tt> if classes loaded by this class loader |
| * will henceforth have assertions enabled by default, |
| * <tt>false</tt> if they will have assertions disabled by default. |
| * @since 1.4 |
| */ |
| public synchronized void setDefaultAssertionStatus(boolean enabled) { |
| if (classAssertionStatus == null) |
| initializeJavaAssertionMaps(); |
| |
| defaultAssertionStatus = enabled; |
| } |
| |
| /** |
| * Sets the package default assertion status for the named |
| * package. The package default assertion status determines the |
| * assertion status for classes initialized in the future that belong |
| * to the named package or any of its "subpackages." |
| * <p> |
| * A subpackage of a package named p is any package whose name |
| * begins with "p." . For example, <tt>javax.swing.text</tt> is |
| * a subpackage of <tt>javax.swing</tt>, and both <tt>java.util</tt> |
| * and <tt>java.lang.reflect</tt> are subpackages of <tt>java</tt>. |
| * <p> |
| * In the event that multiple package defaults apply to a given |
| * class, the package default pertaining to the most specific package |
| * takes precedence over the others. For example, if |
| * <tt>javax.lang</tt> and <tt>javax.lang.reflect</tt> both have |
| * package defaults associated with them, the latter package |
| * default applies to classes in <tt>javax.lang.reflect</tt>. |
| * <p> |
| * Package defaults take precedence over the class loader's default |
| * assertion status, and may be overridden on a per-class basis by |
| * invoking {@link #setClassAssertionStatus(String,boolean)}. |
| * |
| * @param packageName the name of the package whose package default |
| * assertion status is to be set. A null value |
| * indicates the unnamed package that is "current" |
| * (JLS 7.4.2). |
| * @param enabled <tt>true</tt> if classes loaded by this classloader |
| * and belonging to the named package or any of its subpackages |
| * will have assertions enabled by default, <tt>false</tt> if they |
| * will have assertions disabled by default. |
| * @since 1.4 |
| */ |
| public synchronized void setPackageAssertionStatus(String packageName, |
| boolean enabled) |
| { |
| if (packageAssertionStatus == null) |
| initializeJavaAssertionMaps(); |
| |
| packageAssertionStatus.put(packageName, Boolean.valueOf(enabled)); |
| } |
| |
| /** |
| * Sets the desired assertion status for the named top-level class in |
| * this class loader and any nested classes contained therein. |
| * This setting takes precedence over the class loader's default |
| * assertion status, and over any applicable per-package default. |
| * This method has no effect if the named class has already been |
| * initialized. (Once a class is initialized, its assertion status cannot |
| * change.) |
| * <p> |
| * If the named class is not a top-level class, this call will have no |
| * effect on the actual assertion status of any class, and its return |
| * value is undefined. |
| * |
| * @param className the fully qualified class name of the top-level class |
| * whose assertion status is to be set. |
| * @param enabled <tt>true</tt> if the named class is to have assertions |
| * enabled when (and if) it is initialized, <tt>false</tt> if the |
| * class is to have assertions disabled. |
| * @since 1.4 |
| */ |
| public synchronized void setClassAssertionStatus(String className, |
| boolean enabled) |
| { |
| if (classAssertionStatus == null) |
| initializeJavaAssertionMaps(); |
| |
| classAssertionStatus.put(className, Boolean.valueOf(enabled)); |
| } |
| |
| /** |
| * Sets the default assertion status for this class loader to |
| * <tt>false</tt> and discards any package defaults or class assertion |
| * status settings associated with the class loader. This call is |
| * provided so that class loaders can be made to ignore any command line |
| * or persistent assertion status settings and "start with a clean slate." |
| * |
| * @since 1.4 |
| */ |
| public synchronized void clearAssertionStatus() { |
| /* |
| * Whether or not "Java assertion maps" are initialized, set |
| * them to empty maps, effectively ignoring any present settings. |
| */ |
| classAssertionStatus = new HashMap(); |
| packageAssertionStatus = new HashMap(); |
| |
| defaultAssertionStatus = false; |
| } |
| |
| /** |
| * Returns the assertion status that would be assigned to the specified |
| * class if it were to be initialized at the time this method is invoked. |
| * If the named class has had its assertion status set, the most recent |
| * setting will be returned; otherwise, if any package default assertion |
| * status pertains to this class, the most recent setting for the most |
| * specific pertinent package default assertion status is returned; |
| * otherwise, this class loader's default assertion status is returned. |
| * |
| * @param className the fully qualified class name of the class whose |
| * desired assertion status is being queried. |
| * @return the desired assertion status of the specified class. |
| * @see #setClassAssertionStatus(String,boolean) |
| * @see #setPackageAssertionStatus(String,boolean) |
| * @see #setDefaultAssertionStatus(boolean) |
| * @since 1.4 |
| */ |
| synchronized boolean desiredAssertionStatus(String className) { |
| Boolean result; |
| |
| // assert classAssertionStatus != null; |
| // assert packageAssertionStatus != null; |
| |
| // Check for a class entry |
| result = (Boolean)classAssertionStatus.get(className); |
| if (result != null) |
| return result.booleanValue(); |
| |
| // Check for most specific package entry |
| int dotIndex = className.lastIndexOf("."); |
| if (dotIndex < 0) { // default package |
| result = (Boolean)packageAssertionStatus.get(null); |
| if (result != null) |
| return result.booleanValue(); |
| } |
| while(dotIndex > 0) { |
| className = className.substring(0, dotIndex); |
| result = (Boolean)packageAssertionStatus.get(className); |
| if (result != null) |
| return result.booleanValue(); |
| dotIndex = className.lastIndexOf(".", dotIndex-1); |
| } |
| |
| // Return the classloader default |
| return defaultAssertionStatus; |
| } |
| |
| // Set up the assertions with information provided by the VM. |
| private void initializeJavaAssertionMaps() { |
| // assert Thread.holdsLock(this); |
| |
| classAssertionStatus = new HashMap(); |
| packageAssertionStatus = new HashMap(); |
| <error descr="Cannot resolve symbol 'AssertionStatusDirectives'">AssertionStatusDirectives</error> directives = retrieveDirectives(); |
| |
| for(int i=0; i<directives.<error descr="Cannot resolve symbol 'classes'">classes</error>.length; i++) |
| classAssertionStatus.put(directives.<error descr="Cannot resolve symbol 'classes'">classes</error>[i], |
| Boolean.valueOf(directives.<error descr="Cannot resolve symbol 'classEnabled'">classEnabled</error>[i])); |
| |
| for(int i=0; i<directives.<error descr="Cannot resolve symbol 'packages'">packages</error>.length; i++) |
| packageAssertionStatus.put(directives.<error descr="Cannot resolve symbol 'packages'">packages</error>[i], |
| Boolean.valueOf(directives.<error descr="Cannot resolve symbol 'packageEnabled'">packageEnabled</error>[i])); |
| |
| defaultAssertionStatus = directives.<error descr="Cannot resolve symbol 'deflt'">deflt</error>; |
| } |
| |
| // Retrieves the assertion directives from the VM. |
| private static native <error descr="Cannot resolve symbol 'AssertionStatusDirectives'">AssertionStatusDirectives</error> retrieveDirectives(); |
| |
| } |
| |
| |
| class SystemClassLoaderAction implements <error descr="Cannot resolve symbol 'PrivilegedExceptionAction'">PrivilegedExceptionAction</error> { |
| private ClassLoader parent; |
| |
| SystemClassLoaderAction(ClassLoader parent) { |
| this.parent = parent; |
| } |
| |
| public Object run() throws Exception { |
| ClassLoader sys; |
| <error descr="Cannot resolve symbol 'Constructor'">Constructor</error> ctor; |
| Class c; |
| Class cp[] = { ClassLoader.class }; |
| Object params[] = { parent }; |
| |
| String cls = System.getProperty("java.system.class.loader"); |
| if (cls == null) { |
| return parent; |
| } |
| |
| c = Class.forName<error descr="'forName(java.lang.String, boolean, java.lang.ClassLoader)' in 'java.lang.Class' cannot be applied to '(java.lang.String, boolean, ClassLoader)'">(cls, true, parent)</error>; |
| ctor = c.getDeclaredConstructor(cp); |
| sys = (ClassLoader) ctor.<error descr="Cannot resolve method 'newInstance(java.lang.Object[])'">newInstance</error>(params); |
| Thread.currentThread().setContextClassLoader<error descr="'setContextClassLoader(java.lang.ClassLoader)' in 'java.lang.Thread' cannot be applied to '(ClassLoader)'">(sys)</error>; |
| return sys; |
| } |
| } |