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 = new NetworkClassLoader(host, port); * Object main = loader.loadClass("Main", true).newInstance(); * . . . * </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 * . . . * } * } * </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 + -
显示快捷键?