classloader.java

来自「This is a resource based on j2me embedde」· Java 代码 · 共 1,855 行 · 第 1/5 页

JAVA
1,855
字号
/* * @(#)ClassLoader.java	1.163 06/10/10 * * Copyright  1990-2008 Sun Microsystems, Inc. All Rights Reserved.   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER   *    * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License version   * 2 only, as published by the Free Software Foundation.    *    * This program is distributed in the hope that it will be useful, but   * WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   * General Public License version 2 for more details (a copy is   * included at /legal/license.txt).    *    * You should have received a copy of the GNU General Public License   * version 2 along with this work; if not, write to the Free Software   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA   * 02110-1301 USA    *    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa   * Clara, CA 95054 or visit www.sun.com if you need additional   * information or have any questions.  * */package java.lang;import java.io.InputStream;import java.io.IOException;import java.io.File;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationTargetException;import java.net.MalformedURLException;import java.net.URL;import java.security.AccessController;import java.security.AccessControlContext;import java.security.CodeSource;import java.security.Policy;import java.security.PrivilegedAction;import java.security.PrivilegedActionException;import java.security.PrivilegedExceptionAction;import java.security.ProtectionDomain;import java.util.Enumeration;import java.util.Hashtable;import java.util.HashMap;import java.util.HashSet;import java.util.Set;import java.util.Stack;import java.util.Map;import java.util.Vector;import sun.misc.ClassFileTransformer;import sun.misc.CompoundEnumeration;import sun.misc.Resource;import sun.misc.URLClassPath;import sun.security.util.SecurityConstants;import sun.misc.CVM;//import sun.misc.Launcher;/** * A class loader is an object that is responsible for loading classes. The * class <tt>ClassLoader</tt> 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 {@link Class <tt>Class</tt>} object contains a {@link * Class#getClassLoader() reference} to the <tt>ClassLoader</tt> that defined * it. * * <p> <tt>Class</tt> 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 <tt>ClassLoader</tt> 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 <tt>ClassLoader</tt> class uses a delegation model to search for * classes and resources.  Each instance of <tt>ClassLoader</tt> has an * associated parent class loader.  When requested to find a class or * resource, a <tt>ClassLoader</tt> 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 <tt>ClassLoader</tt> 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 * <tt>CLASSPATH</tt> 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 {@link #defineClass(String, byte[], int, int) * <tt>defineClass</tt>} converts an array of bytes into an instance of class * <tt>Class</tt>. Instances of this newly defined class can be created using * {@link Class#newInstance <tt>Class.newInstance</tt>}. * * <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 invokes the {@link #loadClass <tt>loadClass</tt>} 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&nbsp;= new NetworkClassLoader(host,&nbsp;port); *   Object main&nbsp;= loader.loadClass("Main", true).newInstance(); *	 &nbsp;.&nbsp;.&nbsp;. * </pre></blockquote> * * <p> The network class loader subclass must define the methods {@link * #findClass <tt>findClass</tt>} and <tt>loadClassData</tt> to load a class * from the network.  Once it has downloaded the bytes that make up the class, * it should use the method {@link #defineClass <tt>defineClass</tt>} to * create a class instance.  A sample implementation is: * * <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 *             &nbsp;.&nbsp;.&nbsp;. *         } *     } * </pre></blockquote> * * @version  1.163, 10/10/06 * @see      #resolveClass(Class) * @since    1.0 */public abstract class ClassLoader {    /* No need to do this if ROMized    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.cert.Certificate[] nocerts;    /*     * The global root that points to this ClassLoader and will be stored     * in the CVMcbClassLoader() field of every class loaded by this     * ClassLoader. This way we don't need to allocate a separate global root     * for each class loaded, and it also makes checking if two classes     * have the same class loader a lot easier because we can just compare     * the two CVMcbClassLoader() fields rather than having to become     * gcsafe and compare what the two CVMcbClassLoader() fields refer to.     * The global root is allocated by classcreate.c the first time     * this ClassLoader loads a class.     */    private int loaderGlobalRoot;    // 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 Vector classes = new Vector();    // The initiating protection domains for all classes loaded by this loader    private Set domains = new HashSet();    // Invoked by the VM to record every loaded class with this loader.    void addClass(Class c) {	if (CVM.checkDebugFlags(CVM.DEBUGFLAG_TRACE_CLASSLOADING) != 0) {	    System.err.println("CL: addClass() called for <" + 			       c + "," + this + ">");	}        classes.addElement(c);    }    // Invoked by the VM to remove a loaded class.  Used by JVMTI code    private void removeClass(Class c) {	if (CVM.checkDebugFlags(CVM.DEBUGFLAG_TRACE_CLASSLOADING) != 0) {	    System.err.println("CL: removeClass() called for <" + 			       c + "," + this + ">");	}	classes.removeElement(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 {@link     * SecurityManager#checkCreateClassLoader()     * <tt>checkCreateClassLoader</tt>} method is invoked.  This may result in     * a security exception.  </p>     *     * @param  parent     *         The parent class loader     *     * @throws  SecurityException     *          If a security manager exists and its     *          <tt>checkCreateClassLoader</tt> method doesn't allow creation     *          of a new class loader.     *     * @since  1.2     */    protected ClassLoader(ClassLoader parent) {	SecurityManager security = System.getSecurityManager();	if (security != null) {	    security.checkCreateClassLoader();	}	InitializeLoaderGlobalRoot();	this.parent = parent;	initialized = true;    }    /**     * Creates a new class loader using the <tt>ClassLoader</tt> returned by     * the method {@link #getSystemClassLoader()     * <tt>getSystemClassLoader()</tt>} as the parent class loader.     *     * <p> If there is a security manager, its {@link     * SecurityManager#checkCreateClassLoader()     * <tt>checkCreateClassLoader</tt>} method is invoked.  This may result in     * a security exception.  </p>     *     * @throws  SecurityException     *          If a security manager exists and its     *          <tt>checkCreateClassLoader</tt> method doesn't allow creation     *          of a new class loader.     */    protected ClassLoader() {	SecurityManager security = System.getSecurityManager();	if (security != null) {	    security.checkCreateClassLoader();	}	InitializeLoaderGlobalRoot();	this.parent = getSystemClassLoader();	initialized = true;    }    // -- Class --    /*     * Called by the constructor to setup the loaderGlobalRoot     * the ClassLoader instance.     */    private native void InitializeLoaderGlobalRoot();    /**     * 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 invoked by the Java virtual machine to resolve class     * references.  Invoking this method is equivalent to invoking {@link     * #loadClass(String, boolean) <tt>loadClass(name, false)</tt>}.  </p>     *     * @param  name     *         The name of the class     *     * @return  The resulting <tt>Class</tt> object     *     * @throws  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><p> Invoke {@link #findLoadedClass(String)} to check if the class     *   has already been loaded.  </p></li>     *     *   <li><p> Invoke the {@link #loadClass(String) <tt>loadClass</tt>} method     *   on the parent class loader.  If the parent is <tt>null</tt> the class     *   loader built-in to the virtual machine is used, instead.  </p></li>     *     *   <li><p> Invoke the {@link #findClass(String)} method to find the     *   class.  </p></li>     *     * </ol>     *     * <p> If the class was found using the above steps, and the     * <tt>resolve</tt> flag is true, this method will then invoke the {@link     * #resolveClass(Class)} method on the resulting <tt>Class</tt> object.     *     * <p> Subclasses of <tt>ClassLoader</tt> are encouraged to override {@link     * #findClass(String)}, rather than this method.  </p>     *     * @param  name     *         The name of the class     *     * @param  resolve     *         If <tt>true</tt> then resolve the class     *     * @return  The resulting <tt>Class</tt> object     *     * @throws  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 {		    check();		    c = loadBootstrapClassOrNull(name);		}	    } catch (ClassNotFoundException e) {		c = null;	    }	    if (c == null){	        // If still not found, then invoke findClass in order	        // to find the class.	        c = findClass(name);	    } else {		/* this is an initiating loader, so add to the loader cache */		c.addToLoaderCache(this);	    }	}	if (resolve) {	    resolveClass(c);	}	return c;    }    // This method is invoked by the virtual machine to load a class.    private synchronized Class loadClassInternal(String name)	throws ClassNotFoundException    {	return loadClass(name);    }    private void checkPackageAccess(Class cls, ProtectionDomain pd) {	final SecurityManager sm = System.getSecurityManager();	if (sm != null) {	    final String name = cls.getName();

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?