Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/java/lang/ClassLoader.java
38829 views
/*1* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/24package java.lang;2526import java.io.InputStream;27import java.io.IOException;28import java.io.File;29import java.lang.reflect.Constructor;30import java.lang.reflect.InvocationTargetException;31import java.net.MalformedURLException;32import java.net.URL;33import java.security.AccessController;34import java.security.AccessControlContext;35import java.security.CodeSource;36import java.security.Policy;37import java.security.PrivilegedAction;38import java.security.PrivilegedActionException;39import java.security.PrivilegedExceptionAction;40import java.security.ProtectionDomain;41import java.security.cert.Certificate;42import java.util.Collections;43import java.util.Enumeration;44import java.util.HashMap;45import java.util.HashSet;46import java.util.Set;47import java.util.Stack;48import java.util.Map;49import java.util.Vector;50import java.util.Hashtable;51import java.util.WeakHashMap;52import java.util.concurrent.ConcurrentHashMap;53import sun.misc.CompoundEnumeration;54import sun.misc.Resource;55import sun.misc.URLClassPath;56import sun.misc.VM;57import sun.reflect.CallerSensitive;58import sun.reflect.Reflection;59import sun.reflect.misc.ReflectUtil;60import sun.security.util.SecurityConstants;6162/**63* A class loader is an object that is responsible for loading classes. The64* class <tt>ClassLoader</tt> is an abstract class. Given the <a65* href="#name">binary name</a> of a class, a class loader should attempt to66* locate or generate data that constitutes a definition for the class. A67* typical strategy is to transform the name into a file name and then read a68* "class file" of that name from a file system.69*70* <p> Every {@link Class <tt>Class</tt>} object contains a {@link71* Class#getClassLoader() reference} to the <tt>ClassLoader</tt> that defined72* it.73*74* <p> <tt>Class</tt> objects for array classes are not created by class75* loaders, but are created automatically as required by the Java runtime.76* The class loader for an array class, as returned by {@link77* Class#getClassLoader()} is the same as the class loader for its element78* type; if the element type is a primitive type, then the array class has no79* class loader.80*81* <p> Applications implement subclasses of <tt>ClassLoader</tt> in order to82* extend the manner in which the Java virtual machine dynamically loads83* classes.84*85* <p> Class loaders may typically be used by security managers to indicate86* security domains.87*88* <p> The <tt>ClassLoader</tt> class uses a delegation model to search for89* classes and resources. Each instance of <tt>ClassLoader</tt> has an90* associated parent class loader. When requested to find a class or91* resource, a <tt>ClassLoader</tt> instance will delegate the search for the92* class or resource to its parent class loader before attempting to find the93* class or resource itself. The virtual machine's built-in class loader,94* called the "bootstrap class loader", does not itself have a parent but may95* serve as the parent of a <tt>ClassLoader</tt> instance.96*97* <p> Class loaders that support concurrent loading of classes are known as98* <em>parallel capable</em> class loaders and are required to register99* themselves at their class initialization time by invoking the100* {@link101* #registerAsParallelCapable <tt>ClassLoader.registerAsParallelCapable</tt>}102* method. Note that the <tt>ClassLoader</tt> class is registered as parallel103* capable by default. However, its subclasses still need to register themselves104* if they are parallel capable. <br>105* In environments in which the delegation model is not strictly106* hierarchical, class loaders need to be parallel capable, otherwise class107* loading can lead to deadlocks because the loader lock is held for the108* duration of the class loading process (see {@link #loadClass109* <tt>loadClass</tt>} methods).110*111* <p> Normally, the Java virtual machine loads classes from the local file112* system in a platform-dependent manner. For example, on UNIX systems, the113* virtual machine loads classes from the directory defined by the114* <tt>CLASSPATH</tt> environment variable.115*116* <p> However, some classes may not originate from a file; they may originate117* from other sources, such as the network, or they could be constructed by an118* application. The method {@link #defineClass(String, byte[], int, int)119* <tt>defineClass</tt>} converts an array of bytes into an instance of class120* <tt>Class</tt>. Instances of this newly defined class can be created using121* {@link Class#newInstance <tt>Class.newInstance</tt>}.122*123* <p> The methods and constructors of objects created by a class loader may124* reference other classes. To determine the class(es) referred to, the Java125* virtual machine invokes the {@link #loadClass <tt>loadClass</tt>} method of126* the class loader that originally created the class.127*128* <p> For example, an application could create a network class loader to129* download class files from a server. Sample code might look like:130*131* <blockquote><pre>132* ClassLoader loader = new NetworkClassLoader(host, port);133* Object main = loader.loadClass("Main", true).newInstance();134* . . .135* </pre></blockquote>136*137* <p> The network class loader subclass must define the methods {@link138* #findClass <tt>findClass</tt>} and <tt>loadClassData</tt> to load a class139* from the network. Once it has downloaded the bytes that make up the class,140* it should use the method {@link #defineClass <tt>defineClass</tt>} to141* create a class instance. A sample implementation is:142*143* <blockquote><pre>144* class NetworkClassLoader extends ClassLoader {145* String host;146* int port;147*148* public Class findClass(String name) {149* byte[] b = loadClassData(name);150* return defineClass(name, b, 0, b.length);151* }152*153* private byte[] loadClassData(String name) {154* // load the class data from the connection155* . . .156* }157* }158* </pre></blockquote>159*160* <h3> <a name="name">Binary names</a> </h3>161*162* <p> Any class name provided as a {@link String} parameter to methods in163* <tt>ClassLoader</tt> must be a binary name as defined by164* <cite>The Java™ Language Specification</cite>.165*166* <p> Examples of valid class names include:167* <blockquote><pre>168* "java.lang.String"169* "javax.swing.JSpinner$DefaultEditor"170* "java.security.KeyStore$Builder$FileBuilder$1"171* "java.net.URLClassLoader$3$1"172* </pre></blockquote>173*174* @see #resolveClass(Class)175* @since 1.0176*/177public abstract class ClassLoader {178179private static native void registerNatives();180static {181registerNatives();182}183184// The parent class loader for delegation185// Note: VM hardcoded the offset of this field, thus all new fields186// must be added *after* it.187private final ClassLoader parent;188189/**190* Encapsulates the set of parallel capable loader types.191*/192private static class ParallelLoaders {193private ParallelLoaders() {}194195// the set of parallel capable loader types196private static final Set<Class<? extends ClassLoader>> loaderTypes =197Collections.newSetFromMap(198new WeakHashMap<Class<? extends ClassLoader>, Boolean>());199static {200synchronized (loaderTypes) { loaderTypes.add(ClassLoader.class); }201}202203/**204* Registers the given class loader type as parallel capabale.205* Returns {@code true} is successfully registered; {@code false} if206* loader's super class is not registered.207*/208static boolean register(Class<? extends ClassLoader> c) {209synchronized (loaderTypes) {210if (loaderTypes.contains(c.getSuperclass())) {211// register the class loader as parallel capable212// if and only if all of its super classes are.213// Note: given current classloading sequence, if214// the immediate super class is parallel capable,215// all the super classes higher up must be too.216loaderTypes.add(c);217return true;218} else {219return false;220}221}222}223224/**225* Returns {@code true} if the given class loader type is226* registered as parallel capable.227*/228static boolean isRegistered(Class<? extends ClassLoader> c) {229synchronized (loaderTypes) {230return loaderTypes.contains(c);231}232}233}234235// Maps class name to the corresponding lock object when the current236// class loader is parallel capable.237// Note: VM also uses this field to decide if the current class loader238// is parallel capable and the appropriate lock object for class loading.239private final ConcurrentHashMap<String, Object> parallelLockMap;240241// Hashtable that maps packages to certs242private final Map <String, Certificate[]> package2certs;243244// Shared among all packages with unsigned classes245private static final Certificate[] nocerts = new Certificate[0];246247// The classes loaded by this class loader. The only purpose of this table248// is to keep the classes from being GC'ed until the loader is GC'ed.249private final Vector<Class<?>> classes = new Vector<>();250251// The "default" domain. Set as the default ProtectionDomain on newly252// created classes.253private final ProtectionDomain defaultDomain =254new ProtectionDomain(new CodeSource(null, (Certificate[]) null),255null, this, null);256257// Invoked by the VM to record every loaded class with this loader.258void addClass(Class<?> c) {259classes.addElement(c);260}261262// The packages defined in this class loader. Each package name is mapped263// to its corresponding Package object.264// @GuardedBy("itself")265private final HashMap<String, Package> packages = new HashMap<>();266267private static Void checkCreateClassLoader() {268SecurityManager security = System.getSecurityManager();269if (security != null) {270security.checkCreateClassLoader();271}272return null;273}274275private ClassLoader(Void unused, ClassLoader parent) {276this.parent = parent;277if (ParallelLoaders.isRegistered(this.getClass())) {278parallelLockMap = new ConcurrentHashMap<>();279package2certs = new ConcurrentHashMap<>();280assertionLock = new Object();281} else {282// no finer-grained lock; lock on the classloader instance283parallelLockMap = null;284package2certs = new Hashtable<>();285assertionLock = this;286}287}288289/**290* Creates a new class loader using the specified parent class loader for291* delegation.292*293* <p> If there is a security manager, its {@link294* SecurityManager#checkCreateClassLoader()295* <tt>checkCreateClassLoader</tt>} method is invoked. This may result in296* a security exception. </p>297*298* @param parent299* The parent class loader300*301* @throws SecurityException302* If a security manager exists and its303* <tt>checkCreateClassLoader</tt> method doesn't allow creation304* of a new class loader.305*306* @since 1.2307*/308protected ClassLoader(ClassLoader parent) {309this(checkCreateClassLoader(), parent);310}311312/**313* Creates a new class loader using the <tt>ClassLoader</tt> returned by314* the method {@link #getSystemClassLoader()315* <tt>getSystemClassLoader()</tt>} as the parent class loader.316*317* <p> If there is a security manager, its {@link318* SecurityManager#checkCreateClassLoader()319* <tt>checkCreateClassLoader</tt>} method is invoked. This may result in320* a security exception. </p>321*322* @throws SecurityException323* If a security manager exists and its324* <tt>checkCreateClassLoader</tt> method doesn't allow creation325* of a new class loader.326*/327protected ClassLoader() {328this(checkCreateClassLoader(), getSystemClassLoader());329}330331// -- Class --332333/**334* Loads the class with the specified <a href="#name">binary name</a>.335* This method searches for classes in the same manner as the {@link336* #loadClass(String, boolean)} method. It is invoked by the Java virtual337* machine to resolve class references. Invoking this method is equivalent338* to invoking {@link #loadClass(String, boolean) <tt>loadClass(name,339* false)</tt>}.340*341* @param name342* The <a href="#name">binary name</a> of the class343*344* @return The resulting <tt>Class</tt> object345*346* @throws ClassNotFoundException347* If the class was not found348*/349public Class<?> loadClass(String name) throws ClassNotFoundException {350return loadClass(name, false);351}352353/**354* Loads the class with the specified <a href="#name">binary name</a>. The355* default implementation of this method searches for classes in the356* following order:357*358* <ol>359*360* <li><p> Invoke {@link #findLoadedClass(String)} to check if the class361* has already been loaded. </p></li>362*363* <li><p> Invoke the {@link #loadClass(String) <tt>loadClass</tt>} method364* on the parent class loader. If the parent is <tt>null</tt> the class365* loader built-in to the virtual machine is used, instead. </p></li>366*367* <li><p> Invoke the {@link #findClass(String)} method to find the368* class. </p></li>369*370* </ol>371*372* <p> If the class was found using the above steps, and the373* <tt>resolve</tt> flag is true, this method will then invoke the {@link374* #resolveClass(Class)} method on the resulting <tt>Class</tt> object.375*376* <p> Subclasses of <tt>ClassLoader</tt> are encouraged to override {@link377* #findClass(String)}, rather than this method. </p>378*379* <p> Unless overridden, this method synchronizes on the result of380* {@link #getClassLoadingLock <tt>getClassLoadingLock</tt>} method381* during the entire class loading process.382*383* @param name384* The <a href="#name">binary name</a> of the class385*386* @param resolve387* If <tt>true</tt> then resolve the class388*389* @return The resulting <tt>Class</tt> object390*391* @throws ClassNotFoundException392* If the class could not be found393*/394protected Class<?> loadClass(String name, boolean resolve)395throws ClassNotFoundException396{397synchronized (getClassLoadingLock(name)) {398// First, check if the class has already been loaded399Class<?> c = findLoadedClass(name);400if (c == null) {401long t0 = System.nanoTime();402try {403if (parent != null) {404c = parent.loadClass(name, false);405} else {406c = findBootstrapClassOrNull(name);407}408} catch (ClassNotFoundException e) {409// ClassNotFoundException thrown if class not found410// from the non-null parent class loader411}412413if (c == null) {414// If still not found, then invoke findClass in order415// to find the class.416long t1 = System.nanoTime();417c = findClass(name);418419// this is the defining class loader; record the stats420sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);421sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);422sun.misc.PerfCounter.getFindClasses().increment();423}424}425if (resolve) {426resolveClass(c);427}428return c;429}430}431432/**433* Returns the lock object for class loading operations.434* For backward compatibility, the default implementation of this method435* behaves as follows. If this ClassLoader object is registered as436* parallel capable, the method returns a dedicated object associated437* with the specified class name. Otherwise, the method returns this438* ClassLoader object.439*440* @param className441* The name of the to-be-loaded class442*443* @return the lock for class loading operations444*445* @throws NullPointerException446* If registered as parallel capable and <tt>className</tt> is null447*448* @see #loadClass(String, boolean)449*450* @since 1.7451*/452protected Object getClassLoadingLock(String className) {453Object lock = this;454if (parallelLockMap != null) {455Object newLock = new Object();456lock = parallelLockMap.putIfAbsent(className, newLock);457if (lock == null) {458lock = newLock;459}460}461return lock;462}463464// This method is invoked by the virtual machine to load a class.465private Class<?> loadClassInternal(String name)466throws ClassNotFoundException467{468// For backward compatibility, explicitly lock on 'this' when469// the current class loader is not parallel capable.470if (parallelLockMap == null) {471synchronized (this) {472return loadClass(name);473}474} else {475return loadClass(name);476}477}478479// Invoked by the VM after loading class with this loader.480private void checkPackageAccess(Class<?> cls, ProtectionDomain pd) {481final SecurityManager sm = System.getSecurityManager();482if (sm != null) {483if (ReflectUtil.isNonPublicProxyClass(cls)) {484for (Class<?> intf: cls.getInterfaces()) {485checkPackageAccess(intf, pd);486}487return;488}489490final String name = cls.getName();491final int i = name.lastIndexOf('.');492if (i != -1) {493AccessController.doPrivileged(new PrivilegedAction<Void>() {494public Void run() {495sm.checkPackageAccess(name.substring(0, i));496return null;497}498}, new AccessControlContext(new ProtectionDomain[] {pd}));499}500}501}502503/**504* Finds the class with the specified <a href="#name">binary name</a>.505* This method should be overridden by class loader implementations that506* follow the delegation model for loading classes, and will be invoked by507* the {@link #loadClass <tt>loadClass</tt>} method after checking the508* parent class loader for the requested class. The default implementation509* throws a <tt>ClassNotFoundException</tt>.510*511* @param name512* The <a href="#name">binary name</a> of the class513*514* @return The resulting <tt>Class</tt> object515*516* @throws ClassNotFoundException517* If the class could not be found518*519* @since 1.2520*/521protected Class<?> findClass(String name) throws ClassNotFoundException {522throw new ClassNotFoundException(name);523}524525/**526* Converts an array of bytes into an instance of class <tt>Class</tt>.527* Before the <tt>Class</tt> can be used it must be resolved. This method528* is deprecated in favor of the version that takes a <a529* href="#name">binary name</a> as its first argument, and is more secure.530*531* @param b532* The bytes that make up the class data. The bytes in positions533* <tt>off</tt> through <tt>off+len-1</tt> should have the format534* of a valid class file as defined by535* <cite>The Java™ Virtual Machine Specification</cite>.536*537* @param off538* The start offset in <tt>b</tt> of the class data539*540* @param len541* The length of the class data542*543* @return The <tt>Class</tt> object that was created from the specified544* class data545*546* @throws ClassFormatError547* If the data did not contain a valid class548*549* @throws IndexOutOfBoundsException550* If either <tt>off</tt> or <tt>len</tt> is negative, or if551* <tt>off+len</tt> is greater than <tt>b.length</tt>.552*553* @throws SecurityException554* If an attempt is made to add this class to a package that555* contains classes that were signed by a different set of556* certificates than this class, or if an attempt is made557* to define a class in a package with a fully-qualified name558* that starts with "{@code java.}".559*560* @see #loadClass(String, boolean)561* @see #resolveClass(Class)562*563* @deprecated Replaced by {@link #defineClass(String, byte[], int, int)564* defineClass(String, byte[], int, int)}565*/566@Deprecated567protected final Class<?> defineClass(byte[] b, int off, int len)568throws ClassFormatError569{570return defineClass(null, b, off, len, null);571}572573/**574* Converts an array of bytes into an instance of class <tt>Class</tt>.575* Before the <tt>Class</tt> can be used it must be resolved.576*577* <p> This method assigns a default {@link java.security.ProtectionDomain578* <tt>ProtectionDomain</tt>} to the newly defined class. The579* <tt>ProtectionDomain</tt> is effectively granted the same set of580* permissions returned when {@link581* java.security.Policy#getPermissions(java.security.CodeSource)582* <tt>Policy.getPolicy().getPermissions(new CodeSource(null, null))</tt>}583* is invoked. The default domain is created on the first invocation of584* {@link #defineClass(String, byte[], int, int) <tt>defineClass</tt>},585* and re-used on subsequent invocations.586*587* <p> To assign a specific <tt>ProtectionDomain</tt> to the class, use588* the {@link #defineClass(String, byte[], int, int,589* java.security.ProtectionDomain) <tt>defineClass</tt>} method that takes a590* <tt>ProtectionDomain</tt> as one of its arguments. </p>591*592* @param name593* The expected <a href="#name">binary name</a> of the class, or594* <tt>null</tt> if not known595*596* @param b597* The bytes that make up the class data. The bytes in positions598* <tt>off</tt> through <tt>off+len-1</tt> should have the format599* of a valid class file as defined by600* <cite>The Java™ Virtual Machine Specification</cite>.601*602* @param off603* The start offset in <tt>b</tt> of the class data604*605* @param len606* The length of the class data607*608* @return The <tt>Class</tt> object that was created from the specified609* class data.610*611* @throws ClassFormatError612* If the data did not contain a valid class613*614* @throws IndexOutOfBoundsException615* If either <tt>off</tt> or <tt>len</tt> is negative, or if616* <tt>off+len</tt> is greater than <tt>b.length</tt>.617*618* @throws SecurityException619* If an attempt is made to add this class to a package that620* contains classes that were signed by a different set of621* certificates than this class (which is unsigned), or if622* <tt>name</tt> begins with "<tt>java.</tt>".623*624* @see #loadClass(String, boolean)625* @see #resolveClass(Class)626* @see java.security.CodeSource627* @see java.security.SecureClassLoader628*629* @since 1.1630*/631protected final Class<?> defineClass(String name, byte[] b, int off, int len)632throws ClassFormatError633{634return defineClass(name, b, off, len, null);635}636637/* Determine protection domain, and check that:638- not define java.* class,639- signer of this class matches signers for the rest of the classes in640package.641*/642private ProtectionDomain preDefineClass(String name,643ProtectionDomain pd)644{645if (!checkName(name))646throw new NoClassDefFoundError("IllegalName: " + name);647648// Note: Checking logic in java.lang.invoke.MemberName.checkForTypeAlias649// relies on the fact that spoofing is impossible if a class has a name650// of the form "java.*"651if ((name != null) && name.startsWith("java.")) {652throw new SecurityException653("Prohibited package name: " +654name.substring(0, name.lastIndexOf('.')));655}656if (pd == null) {657pd = defaultDomain;658}659660if (name != null) checkCerts(name, pd.getCodeSource());661662return pd;663}664665private String defineClassSourceLocation(ProtectionDomain pd)666{667CodeSource cs = pd.getCodeSource();668String source = null;669if (cs != null && cs.getLocation() != null) {670source = cs.getLocation().toString();671}672return source;673}674675private void postDefineClass(Class<?> c, ProtectionDomain pd)676{677if (pd.getCodeSource() != null) {678Certificate certs[] = pd.getCodeSource().getCertificates();679if (certs != null)680setSigners(c, certs);681}682}683684/**685* Converts an array of bytes into an instance of class <tt>Class</tt>,686* with an optional <tt>ProtectionDomain</tt>. If the domain is687* <tt>null</tt>, then a default domain will be assigned to the class as688* specified in the documentation for {@link #defineClass(String, byte[],689* int, int)}. Before the class can be used it must be resolved.690*691* <p> The first class defined in a package determines the exact set of692* certificates that all subsequent classes defined in that package must693* contain. The set of certificates for a class is obtained from the694* {@link java.security.CodeSource <tt>CodeSource</tt>} within the695* <tt>ProtectionDomain</tt> of the class. Any classes added to that696* package must contain the same set of certificates or a697* <tt>SecurityException</tt> will be thrown. Note that if698* <tt>name</tt> is <tt>null</tt>, this check is not performed.699* You should always pass in the <a href="#name">binary name</a> of the700* class you are defining as well as the bytes. This ensures that the701* class you are defining is indeed the class you think it is.702*703* <p> The specified <tt>name</tt> cannot begin with "<tt>java.</tt>", since704* all classes in the "<tt>java.*</tt> packages can only be defined by the705* bootstrap class loader. If <tt>name</tt> is not <tt>null</tt>, it706* must be equal to the <a href="#name">binary name</a> of the class707* specified by the byte array "<tt>b</tt>", otherwise a {@link708* NoClassDefFoundError <tt>NoClassDefFoundError</tt>} will be thrown. </p>709*710* @param name711* The expected <a href="#name">binary name</a> of the class, or712* <tt>null</tt> if not known713*714* @param b715* The bytes that make up the class data. The bytes in positions716* <tt>off</tt> through <tt>off+len-1</tt> should have the format717* of a valid class file as defined by718* <cite>The Java™ Virtual Machine Specification</cite>.719*720* @param off721* The start offset in <tt>b</tt> of the class data722*723* @param len724* The length of the class data725*726* @param protectionDomain727* The ProtectionDomain of the class728*729* @return The <tt>Class</tt> object created from the data,730* and optional <tt>ProtectionDomain</tt>.731*732* @throws ClassFormatError733* If the data did not contain a valid class734*735* @throws NoClassDefFoundError736* If <tt>name</tt> is not equal to the <a href="#name">binary737* name</a> of the class specified by <tt>b</tt>738*739* @throws IndexOutOfBoundsException740* If either <tt>off</tt> or <tt>len</tt> is negative, or if741* <tt>off+len</tt> is greater than <tt>b.length</tt>.742*743* @throws SecurityException744* If an attempt is made to add this class to a package that745* contains classes that were signed by a different set of746* certificates than this class, or if <tt>name</tt> begins with747* "<tt>java.</tt>".748*/749protected final Class<?> defineClass(String name, byte[] b, int off, int len,750ProtectionDomain protectionDomain)751throws ClassFormatError752{753protectionDomain = preDefineClass(name, protectionDomain);754String source = defineClassSourceLocation(protectionDomain);755Class<?> c = defineClass1(name, b, off, len, protectionDomain, source);756postDefineClass(c, protectionDomain);757return c;758}759760/**761* Converts a {@link java.nio.ByteBuffer <tt>ByteBuffer</tt>}762* into an instance of class <tt>Class</tt>,763* with an optional <tt>ProtectionDomain</tt>. If the domain is764* <tt>null</tt>, then a default domain will be assigned to the class as765* specified in the documentation for {@link #defineClass(String, byte[],766* int, int)}. Before the class can be used it must be resolved.767*768* <p>The rules about the first class defined in a package determining the769* set of certificates for the package, and the restrictions on class names770* are identical to those specified in the documentation for {@link771* #defineClass(String, byte[], int, int, ProtectionDomain)}.772*773* <p> An invocation of this method of the form774* <i>cl</i><tt>.defineClass(</tt><i>name</i><tt>,</tt>775* <i>bBuffer</i><tt>,</tt> <i>pd</i><tt>)</tt> yields exactly the same776* result as the statements777*778*<p> <tt>779* ...<br>780* byte[] temp = new byte[bBuffer.{@link781* java.nio.ByteBuffer#remaining remaining}()];<br>782* bBuffer.{@link java.nio.ByteBuffer#get(byte[])783* get}(temp);<br>784* return {@link #defineClass(String, byte[], int, int, ProtectionDomain)785* cl.defineClass}(name, temp, 0,786* temp.length, pd);<br>787* </tt></p>788*789* @param name790* The expected <a href="#name">binary name</a>. of the class, or791* <tt>null</tt> if not known792*793* @param b794* The bytes that make up the class data. The bytes from positions795* <tt>b.position()</tt> through <tt>b.position() + b.limit() -1796* </tt> should have the format of a valid class file as defined by797* <cite>The Java™ Virtual Machine Specification</cite>.798*799* @param protectionDomain800* The ProtectionDomain of the class, or <tt>null</tt>.801*802* @return The <tt>Class</tt> object created from the data,803* and optional <tt>ProtectionDomain</tt>.804*805* @throws ClassFormatError806* If the data did not contain a valid class.807*808* @throws NoClassDefFoundError809* If <tt>name</tt> is not equal to the <a href="#name">binary810* name</a> of the class specified by <tt>b</tt>811*812* @throws SecurityException813* If an attempt is made to add this class to a package that814* contains classes that were signed by a different set of815* certificates than this class, or if <tt>name</tt> begins with816* "<tt>java.</tt>".817*818* @see #defineClass(String, byte[], int, int, ProtectionDomain)819*820* @since 1.5821*/822protected final Class<?> defineClass(String name, java.nio.ByteBuffer b,823ProtectionDomain protectionDomain)824throws ClassFormatError825{826int len = b.remaining();827828// Use byte[] if not a direct ByteBufer:829if (!b.isDirect()) {830if (b.hasArray()) {831return defineClass(name, b.array(),832b.position() + b.arrayOffset(), len,833protectionDomain);834} else {835// no array, or read-only array836byte[] tb = new byte[len];837b.get(tb); // get bytes out of byte buffer.838return defineClass(name, tb, 0, len, protectionDomain);839}840}841842protectionDomain = preDefineClass(name, protectionDomain);843String source = defineClassSourceLocation(protectionDomain);844Class<?> c = defineClass2(name, b, b.position(), len, protectionDomain, source);845postDefineClass(c, protectionDomain);846return c;847}848849private native Class<?> defineClass0(String name, byte[] b, int off, int len,850ProtectionDomain pd);851852private native Class<?> defineClass1(String name, byte[] b, int off, int len,853ProtectionDomain pd, String source);854855private native Class<?> defineClass2(String name, java.nio.ByteBuffer b,856int off, int len, ProtectionDomain pd,857String source);858859// true if the name is null or has the potential to be a valid binary name860private boolean checkName(String name) {861if ((name == null) || (name.length() == 0))862return true;863if ((name.indexOf('/') != -1)864|| (!VM.allowArraySyntax() && (name.charAt(0) == '[')))865return false;866return true;867}868869private void checkCerts(String name, CodeSource cs) {870int i = name.lastIndexOf('.');871String pname = (i == -1) ? "" : name.substring(0, i);872873Certificate[] certs = null;874if (cs != null) {875certs = cs.getCertificates();876}877Certificate[] pcerts = null;878if (parallelLockMap == null) {879synchronized (this) {880pcerts = package2certs.get(pname);881if (pcerts == null) {882package2certs.put(pname, (certs == null? nocerts:certs));883}884}885} else {886pcerts = ((ConcurrentHashMap<String, Certificate[]>)package2certs).887putIfAbsent(pname, (certs == null? nocerts:certs));888}889if (pcerts != null && !compareCerts(pcerts, certs)) {890throw new SecurityException("class \""+ name +891"\"'s signer information does not match signer information of other classes in the same package");892}893}894895/**896* check to make sure the certs for the new class (certs) are the same as897* the certs for the first class inserted in the package (pcerts)898*/899private boolean compareCerts(Certificate[] pcerts,900Certificate[] certs)901{902// certs can be null, indicating no certs.903if ((certs == null) || (certs.length == 0)) {904return pcerts.length == 0;905}906907// the length must be the same at this point908if (certs.length != pcerts.length)909return false;910911// go through and make sure all the certs in one array912// are in the other and vice-versa.913boolean match;914for (int i = 0; i < certs.length; i++) {915match = false;916for (int j = 0; j < pcerts.length; j++) {917if (certs[i].equals(pcerts[j])) {918match = true;919break;920}921}922if (!match) return false;923}924925// now do the same for pcerts926for (int i = 0; i < pcerts.length; i++) {927match = false;928for (int j = 0; j < certs.length; j++) {929if (pcerts[i].equals(certs[j])) {930match = true;931break;932}933}934if (!match) return false;935}936937return true;938}939940/**941* Links the specified class. This (misleadingly named) method may be942* used by a class loader to link a class. If the class <tt>c</tt> has943* already been linked, then this method simply returns. Otherwise, the944* class is linked as described in the "Execution" chapter of945* <cite>The Java™ Language Specification</cite>.946*947* @param c948* The class to link949*950* @throws NullPointerException951* If <tt>c</tt> is <tt>null</tt>.952*953* @see #defineClass(String, byte[], int, int)954*/955protected final void resolveClass(Class<?> c) {956resolveClass0(c);957}958959private native void resolveClass0(Class<?> c);960961/**962* Finds a class with the specified <a href="#name">binary name</a>,963* loading it if necessary.964*965* <p> This method loads the class through the system class loader (see966* {@link #getSystemClassLoader()}). The <tt>Class</tt> object returned967* might have more than one <tt>ClassLoader</tt> associated with it.968* Subclasses of <tt>ClassLoader</tt> need not usually invoke this method,969* because most class loaders need to override just {@link970* #findClass(String)}. </p>971*972* @param name973* The <a href="#name">binary name</a> of the class974*975* @return The <tt>Class</tt> object for the specified <tt>name</tt>976*977* @throws ClassNotFoundException978* If the class could not be found979*980* @see #ClassLoader(ClassLoader)981* @see #getParent()982*/983protected final Class<?> findSystemClass(String name)984throws ClassNotFoundException985{986ClassLoader system = getSystemClassLoader();987if (system == null) {988if (!checkName(name))989throw new ClassNotFoundException(name);990Class<?> cls = findBootstrapClass(name);991if (cls == null) {992throw new ClassNotFoundException(name);993}994return cls;995}996return system.loadClass(name);997}998999/**1000* Returns a class loaded by the bootstrap class loader;1001* or return null if not found.1002*/1003private Class<?> findBootstrapClassOrNull(String name)1004{1005if (!checkName(name)) return null;10061007return findBootstrapClass(name);1008}10091010// return null if not found1011private native Class<?> findBootstrapClass(String name);10121013/**1014* Returns the class with the given <a href="#name">binary name</a> if this1015* loader has been recorded by the Java virtual machine as an initiating1016* loader of a class with that <a href="#name">binary name</a>. Otherwise1017* <tt>null</tt> is returned.1018*1019* @param name1020* The <a href="#name">binary name</a> of the class1021*1022* @return The <tt>Class</tt> object, or <tt>null</tt> if the class has1023* not been loaded1024*1025* @since 1.11026*/1027protected final Class<?> findLoadedClass(String name) {1028if (!checkName(name))1029return null;1030return findLoadedClass0(name);1031}10321033private native final Class<?> findLoadedClass0(String name);10341035/**1036* Sets the signers of a class. This should be invoked after defining a1037* class.1038*1039* @param c1040* The <tt>Class</tt> object1041*1042* @param signers1043* The signers for the class1044*1045* @since 1.11046*/1047protected final void setSigners(Class<?> c, Object[] signers) {1048c.setSigners(signers);1049}105010511052// -- Resource --10531054/**1055* Finds the resource with the given name. A resource is some data1056* (images, audio, text, etc) that can be accessed by class code in a way1057* that is independent of the location of the code.1058*1059* <p> The name of a resource is a '<tt>/</tt>'-separated path name that1060* identifies the resource.1061*1062* <p> This method will first search the parent class loader for the1063* resource; if the parent is <tt>null</tt> the path of the class loader1064* built-in to the virtual machine is searched. That failing, this method1065* will invoke {@link #findResource(String)} to find the resource. </p>1066*1067* @apiNote When overriding this method it is recommended that an1068* implementation ensures that any delegation is consistent with the {@link1069* #getResources(java.lang.String) getResources(String)} method.1070*1071* @param name1072* The resource name1073*1074* @return A <tt>URL</tt> object for reading the resource, or1075* <tt>null</tt> if the resource could not be found or the invoker1076* doesn't have adequate privileges to get the resource.1077*1078* @since 1.11079*/1080public URL getResource(String name) {1081URL url;1082if (parent != null) {1083url = parent.getResource(name);1084} else {1085url = getBootstrapResource(name);1086}1087if (url == null) {1088url = findResource(name);1089}1090return url;1091}10921093/**1094* Finds all the resources with the given name. A resource is some data1095* (images, audio, text, etc) that can be accessed by class code in a way1096* that is independent of the location of the code.1097*1098* <p>The name of a resource is a <tt>/</tt>-separated path name that1099* identifies the resource.1100*1101* <p> The search order is described in the documentation for {@link1102* #getResource(String)}. </p>1103*1104* @apiNote When overriding this method it is recommended that an1105* implementation ensures that any delegation is consistent with the {@link1106* #getResource(java.lang.String) getResource(String)} method. This should1107* ensure that the first element returned by the Enumeration's1108* {@code nextElement} method is the same resource that the1109* {@code getResource(String)} method would return.1110*1111* @param name1112* The resource name1113*1114* @return An enumeration of {@link java.net.URL <tt>URL</tt>} objects for1115* the resource. If no resources could be found, the enumeration1116* will be empty. Resources that the class loader doesn't have1117* access to will not be in the enumeration.1118*1119* @throws IOException1120* If I/O errors occur1121*1122* @see #findResources(String)1123*1124* @since 1.21125*/1126public Enumeration<URL> getResources(String name) throws IOException {1127@SuppressWarnings("unchecked")1128Enumeration<URL>[] tmp = (Enumeration<URL>[]) new Enumeration<?>[2];1129if (parent != null) {1130tmp[0] = parent.getResources(name);1131} else {1132tmp[0] = getBootstrapResources(name);1133}1134tmp[1] = findResources(name);11351136return new CompoundEnumeration<>(tmp);1137}11381139/**1140* Finds the resource with the given name. Class loader implementations1141* should override this method to specify where to find resources.1142*1143* @param name1144* The resource name1145*1146* @return A <tt>URL</tt> object for reading the resource, or1147* <tt>null</tt> if the resource could not be found1148*1149* @since 1.21150*/1151protected URL findResource(String name) {1152return null;1153}11541155/**1156* Returns an enumeration of {@link java.net.URL <tt>URL</tt>} objects1157* representing all the resources with the given name. Class loader1158* implementations should override this method to specify where to load1159* resources from.1160*1161* @param name1162* The resource name1163*1164* @return An enumeration of {@link java.net.URL <tt>URL</tt>} objects for1165* the resources1166*1167* @throws IOException1168* If I/O errors occur1169*1170* @since 1.21171*/1172protected Enumeration<URL> findResources(String name) throws IOException {1173return java.util.Collections.emptyEnumeration();1174}11751176/**1177* Registers the caller as parallel capable.1178* The registration succeeds if and only if all of the following1179* conditions are met:1180* <ol>1181* <li> no instance of the caller has been created</li>1182* <li> all of the super classes (except class Object) of the caller are1183* registered as parallel capable</li>1184* </ol>1185* <p>Note that once a class loader is registered as parallel capable, there1186* is no way to change it back.</p>1187*1188* @return true if the caller is successfully registered as1189* parallel capable and false if otherwise.1190*1191* @since 1.71192*/1193@CallerSensitive1194protected static boolean registerAsParallelCapable() {1195Class<? extends ClassLoader> callerClass =1196Reflection.getCallerClass().asSubclass(ClassLoader.class);1197return ParallelLoaders.register(callerClass);1198}11991200/**1201* Find a resource of the specified name from the search path used to load1202* classes. This method locates the resource through the system class1203* loader (see {@link #getSystemClassLoader()}).1204*1205* @param name1206* The resource name1207*1208* @return A {@link java.net.URL <tt>URL</tt>} object for reading the1209* resource, or <tt>null</tt> if the resource could not be found1210*1211* @since 1.11212*/1213public static URL getSystemResource(String name) {1214ClassLoader system = getSystemClassLoader();1215if (system == null) {1216return getBootstrapResource(name);1217}1218return system.getResource(name);1219}12201221/**1222* Finds all resources of the specified name from the search path used to1223* load classes. The resources thus found are returned as an1224* {@link java.util.Enumeration <tt>Enumeration</tt>} of {@link1225* java.net.URL <tt>URL</tt>} objects.1226*1227* <p> The search order is described in the documentation for {@link1228* #getSystemResource(String)}. </p>1229*1230* @param name1231* The resource name1232*1233* @return An enumeration of resource {@link java.net.URL <tt>URL</tt>}1234* objects1235*1236* @throws IOException1237* If I/O errors occur12381239* @since 1.21240*/1241public static Enumeration<URL> getSystemResources(String name)1242throws IOException1243{1244ClassLoader system = getSystemClassLoader();1245if (system == null) {1246return getBootstrapResources(name);1247}1248return system.getResources(name);1249}12501251/**1252* Find resources from the VM's built-in classloader.1253*/1254private static URL getBootstrapResource(String name) {1255URLClassPath ucp = getBootstrapClassPath();1256Resource res = ucp.getResource(name);1257return res != null ? res.getURL() : null;1258}12591260/**1261* Find resources from the VM's built-in classloader.1262*/1263private static Enumeration<URL> getBootstrapResources(String name)1264throws IOException1265{1266final Enumeration<Resource> e =1267getBootstrapClassPath().getResources(name);1268return new Enumeration<URL> () {1269public URL nextElement() {1270return e.nextElement().getURL();1271}1272public boolean hasMoreElements() {1273return e.hasMoreElements();1274}1275};1276}12771278// Returns the URLClassPath that is used for finding system resources.1279static URLClassPath getBootstrapClassPath() {1280return sun.misc.Launcher.getBootstrapClassPath();1281}128212831284/**1285* Returns an input stream for reading the specified resource.1286*1287* <p> The search order is described in the documentation for {@link1288* #getResource(String)}. </p>1289*1290* @param name1291* The resource name1292*1293* @return An input stream for reading the resource, or <tt>null</tt>1294* if the resource could not be found1295*1296* @since 1.11297*/1298public InputStream getResourceAsStream(String name) {1299URL url = getResource(name);1300try {1301return url != null ? url.openStream() : null;1302} catch (IOException e) {1303return null;1304}1305}13061307/**1308* Open for reading, a resource of the specified name from the search path1309* used to load classes. This method locates the resource through the1310* system class loader (see {@link #getSystemClassLoader()}).1311*1312* @param name1313* The resource name1314*1315* @return An input stream for reading the resource, or <tt>null</tt>1316* if the resource could not be found1317*1318* @since 1.11319*/1320public static InputStream getSystemResourceAsStream(String name) {1321URL url = getSystemResource(name);1322try {1323return url != null ? url.openStream() : null;1324} catch (IOException e) {1325return null;1326}1327}132813291330// -- Hierarchy --13311332/**1333* Returns the parent class loader for delegation. Some implementations may1334* use <tt>null</tt> to represent the bootstrap class loader. This method1335* will return <tt>null</tt> in such implementations if this class loader's1336* parent is the bootstrap class loader.1337*1338* <p> If a security manager is present, and the invoker's class loader is1339* not <tt>null</tt> and is not an ancestor of this class loader, then this1340* method invokes the security manager's {@link1341* SecurityManager#checkPermission(java.security.Permission)1342* <tt>checkPermission</tt>} method with a {@link1343* RuntimePermission#RuntimePermission(String)1344* <tt>RuntimePermission("getClassLoader")</tt>} permission to verify1345* access to the parent class loader is permitted. If not, a1346* <tt>SecurityException</tt> will be thrown. </p>1347*1348* @return The parent <tt>ClassLoader</tt>1349*1350* @throws SecurityException1351* If a security manager exists and its <tt>checkPermission</tt>1352* method doesn't allow access to this class loader's parent class1353* loader.1354*1355* @since 1.21356*/1357@CallerSensitive1358public final ClassLoader getParent() {1359if (parent == null)1360return null;1361SecurityManager sm = System.getSecurityManager();1362if (sm != null) {1363// Check access to the parent class loader1364// If the caller's class loader is same as this class loader,1365// permission check is performed.1366checkClassLoaderPermission(parent, Reflection.getCallerClass());1367}1368return parent;1369}13701371/**1372* Returns the system class loader for delegation. This is the default1373* delegation parent for new <tt>ClassLoader</tt> instances, and is1374* typically the class loader used to start the application.1375*1376* <p> This method is first invoked early in the runtime's startup1377* sequence, at which point it creates the system class loader and sets it1378* as the context class loader of the invoking <tt>Thread</tt>.1379*1380* <p> The default system class loader is an implementation-dependent1381* instance of this class.1382*1383* <p> If the system property "<tt>java.system.class.loader</tt>" is defined1384* when this method is first invoked then the value of that property is1385* taken to be the name of a class that will be returned as the system1386* class loader. The class is loaded using the default system class loader1387* and must define a public constructor that takes a single parameter of1388* type <tt>ClassLoader</tt> which is used as the delegation parent. An1389* instance is then created using this constructor with the default system1390* class loader as the parameter. The resulting class loader is defined1391* to be the system class loader.1392*1393* <p> If a security manager is present, and the invoker's class loader is1394* not <tt>null</tt> and the invoker's class loader is not the same as or1395* an ancestor of the system class loader, then this method invokes the1396* security manager's {@link1397* SecurityManager#checkPermission(java.security.Permission)1398* <tt>checkPermission</tt>} method with a {@link1399* RuntimePermission#RuntimePermission(String)1400* <tt>RuntimePermission("getClassLoader")</tt>} permission to verify1401* access to the system class loader. If not, a1402* <tt>SecurityException</tt> will be thrown. </p>1403*1404* @return The system <tt>ClassLoader</tt> for delegation, or1405* <tt>null</tt> if none1406*1407* @throws SecurityException1408* If a security manager exists and its <tt>checkPermission</tt>1409* method doesn't allow access to the system class loader.1410*1411* @throws IllegalStateException1412* If invoked recursively during the construction of the class1413* loader specified by the "<tt>java.system.class.loader</tt>"1414* property.1415*1416* @throws Error1417* If the system property "<tt>java.system.class.loader</tt>"1418* is defined but the named class could not be loaded, the1419* provider class does not define the required constructor, or an1420* exception is thrown by that constructor when it is invoked. The1421* underlying cause of the error can be retrieved via the1422* {@link Throwable#getCause()} method.1423*1424* @revised 1.41425*/1426@CallerSensitive1427public static ClassLoader getSystemClassLoader() {1428initSystemClassLoader();1429if (scl == null) {1430return null;1431}1432SecurityManager sm = System.getSecurityManager();1433if (sm != null) {1434checkClassLoaderPermission(scl, Reflection.getCallerClass());1435}1436return scl;1437}14381439private static synchronized void initSystemClassLoader() {1440if (!sclSet) {1441if (scl != null)1442throw new IllegalStateException("recursive invocation");1443sun.misc.Launcher l = sun.misc.Launcher.getLauncher();1444if (l != null) {1445Throwable oops = null;1446scl = l.getClassLoader();1447try {1448scl = AccessController.doPrivileged(1449new SystemClassLoaderAction(scl));1450} catch (PrivilegedActionException pae) {1451oops = pae.getCause();1452if (oops instanceof InvocationTargetException) {1453oops = oops.getCause();1454}1455}1456if (oops != null) {1457if (oops instanceof Error) {1458throw (Error) oops;1459} else {1460// wrap the exception1461throw new Error(oops);1462}1463}1464}1465sclSet = true;1466}1467}14681469// Returns true if the specified class loader can be found in this class1470// loader's delegation chain.1471boolean isAncestor(ClassLoader cl) {1472ClassLoader acl = this;1473do {1474acl = acl.parent;1475if (cl == acl) {1476return true;1477}1478} while (acl != null);1479return false;1480}14811482// Tests if class loader access requires "getClassLoader" permission1483// check. A class loader 'from' can access class loader 'to' if1484// class loader 'from' is same as class loader 'to' or an ancestor1485// of 'to'. The class loader in a system domain can access1486// any class loader.1487private static boolean needsClassLoaderPermissionCheck(ClassLoader from,1488ClassLoader to)1489{1490if (from == to)1491return false;14921493if (from == null)1494return false;14951496return !to.isAncestor(from);1497}14981499// Returns the class's class loader, or null if none.1500static ClassLoader getClassLoader(Class<?> caller) {1501// This can be null if the VM is requesting it1502if (caller == null) {1503return null;1504}1505// Circumvent security check since this is package-private1506return caller.getClassLoader0();1507}15081509/*1510* Checks RuntimePermission("getClassLoader") permission1511* if caller's class loader is not null and caller's class loader1512* is not the same as or an ancestor of the given cl argument.1513*/1514static void checkClassLoaderPermission(ClassLoader cl, Class<?> caller) {1515SecurityManager sm = System.getSecurityManager();1516if (sm != null) {1517// caller can be null if the VM is requesting it1518ClassLoader ccl = getClassLoader(caller);1519if (needsClassLoaderPermissionCheck(ccl, cl)) {1520sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);1521}1522}1523}15241525// The class loader for the system1526// @GuardedBy("ClassLoader.class")1527private static ClassLoader scl;15281529// Set to true once the system class loader has been set1530// @GuardedBy("ClassLoader.class")1531private static boolean sclSet;153215331534// -- Package --15351536/**1537* Defines a package by name in this <tt>ClassLoader</tt>. This allows1538* class loaders to define the packages for their classes. Packages must1539* be created before the class is defined, and package names must be1540* unique within a class loader and cannot be redefined or changed once1541* created.1542*1543* @param name1544* The package name1545*1546* @param specTitle1547* The specification title1548*1549* @param specVersion1550* The specification version1551*1552* @param specVendor1553* The specification vendor1554*1555* @param implTitle1556* The implementation title1557*1558* @param implVersion1559* The implementation version1560*1561* @param implVendor1562* The implementation vendor1563*1564* @param sealBase1565* If not <tt>null</tt>, then this package is sealed with1566* respect to the given code source {@link java.net.URL1567* <tt>URL</tt>} object. Otherwise, the package is not sealed.1568*1569* @return The newly defined <tt>Package</tt> object1570*1571* @throws IllegalArgumentException1572* If package name duplicates an existing package either in this1573* class loader or one of its ancestors1574*1575* @since 1.21576*/1577protected Package definePackage(String name, String specTitle,1578String specVersion, String specVendor,1579String implTitle, String implVersion,1580String implVendor, URL sealBase)1581throws IllegalArgumentException1582{1583synchronized (packages) {1584Package pkg = getPackage(name);1585if (pkg != null) {1586throw new IllegalArgumentException(name);1587}1588pkg = new Package(name, specTitle, specVersion, specVendor,1589implTitle, implVersion, implVendor,1590sealBase, this);1591packages.put(name, pkg);1592return pkg;1593}1594}15951596/**1597* Returns a <tt>Package</tt> that has been defined by this class loader1598* or any of its ancestors.1599*1600* @param name1601* The package name1602*1603* @return The <tt>Package</tt> corresponding to the given name, or1604* <tt>null</tt> if not found1605*1606* @since 1.21607*/1608protected Package getPackage(String name) {1609Package pkg;1610synchronized (packages) {1611pkg = packages.get(name);1612}1613if (pkg == null) {1614if (parent != null) {1615pkg = parent.getPackage(name);1616} else {1617pkg = Package.getSystemPackage(name);1618}1619if (pkg != null) {1620synchronized (packages) {1621Package pkg2 = packages.get(name);1622if (pkg2 == null) {1623packages.put(name, pkg);1624} else {1625pkg = pkg2;1626}1627}1628}1629}1630return pkg;1631}16321633/**1634* Returns all of the <tt>Packages</tt> defined by this class loader and1635* its ancestors.1636*1637* @return The array of <tt>Package</tt> objects defined by this1638* <tt>ClassLoader</tt>1639*1640* @since 1.21641*/1642protected Package[] getPackages() {1643Map<String, Package> map;1644synchronized (packages) {1645map = new HashMap<>(packages);1646}1647Package[] pkgs;1648if (parent != null) {1649pkgs = parent.getPackages();1650} else {1651pkgs = Package.getSystemPackages();1652}1653if (pkgs != null) {1654for (int i = 0; i < pkgs.length; i++) {1655String pkgName = pkgs[i].getName();1656if (map.get(pkgName) == null) {1657map.put(pkgName, pkgs[i]);1658}1659}1660}1661return map.values().toArray(new Package[map.size()]);1662}166316641665// -- Native library access --16661667/**1668* Returns the absolute path name of a native library. The VM invokes this1669* method to locate the native libraries that belong to classes loaded with1670* this class loader. If this method returns <tt>null</tt>, the VM1671* searches the library along the path specified as the1672* "<tt>java.library.path</tt>" property.1673*1674* @param libname1675* The library name1676*1677* @return The absolute path of the native library1678*1679* @see System#loadLibrary(String)1680* @see System#mapLibraryName(String)1681*1682* @since 1.21683*/1684protected String findLibrary(String libname) {1685return null;1686}16871688/**1689* The inner class NativeLibrary denotes a loaded native library instance.1690* Every classloader contains a vector of loaded native libraries in the1691* private field <tt>nativeLibraries</tt>. The native libraries loaded1692* into the system are entered into the <tt>systemNativeLibraries</tt>1693* vector.1694*1695* <p> Every native library requires a particular version of JNI. This is1696* denoted by the private <tt>jniVersion</tt> field. This field is set by1697* the VM when it loads the library, and used by the VM to pass the correct1698* version of JNI to the native methods. </p>1699*1700* @see ClassLoader1701* @since 1.21702*/1703static class NativeLibrary {1704// opaque handle to native library, used in native code.1705long handle;1706// the version of JNI environment the native library requires.1707private int jniVersion;1708// the class from which the library is loaded, also indicates1709// the loader this native library belongs.1710private final Class<?> fromClass;1711// the canonicalized name of the native library.1712// or static library name1713String name;1714// Indicates if the native library is linked into the VM1715boolean isBuiltin;1716// Indicates if the native library is loaded1717boolean loaded;1718native void load(String name, boolean isBuiltin);17191720native long find(String name);1721native void unload(String name, boolean isBuiltin);17221723public NativeLibrary(Class<?> fromClass, String name, boolean isBuiltin) {1724this.name = name;1725this.fromClass = fromClass;1726this.isBuiltin = isBuiltin;1727}17281729protected void finalize() {1730synchronized (loadedLibraryNames) {1731if (fromClass.getClassLoader() != null && loaded) {1732/* remove the native library name */1733int size = loadedLibraryNames.size();1734for (int i = 0; i < size; i++) {1735if (name.equals(loadedLibraryNames.elementAt(i))) {1736loadedLibraryNames.removeElementAt(i);1737break;1738}1739}1740/* unload the library. */1741ClassLoader.nativeLibraryContext.push(this);1742try {1743unload(name, isBuiltin);1744} finally {1745ClassLoader.nativeLibraryContext.pop();1746}1747}1748}1749}1750// Invoked in the VM to determine the context class in1751// JNI_Load/JNI_Unload1752static Class<?> getFromClass() {1753return ClassLoader.nativeLibraryContext.peek().fromClass;1754}1755}17561757// All native library names we've loaded.1758private static Vector<String> loadedLibraryNames = new Vector<>();17591760// Native libraries belonging to system classes.1761private static Vector<NativeLibrary> systemNativeLibraries1762= new Vector<>();17631764// Native libraries associated with the class loader.1765private Vector<NativeLibrary> nativeLibraries = new Vector<>();17661767// native libraries being loaded/unloaded.1768private static Stack<NativeLibrary> nativeLibraryContext = new Stack<>();17691770// The paths searched for libraries1771private static String usr_paths[];1772private static String sys_paths[];17731774private static String[] initializePath(String propname) {1775String ldpath = System.getProperty(propname, "");1776String ps = File.pathSeparator;1777int ldlen = ldpath.length();1778int i, j, n;1779// Count the separators in the path1780i = ldpath.indexOf(ps);1781n = 0;1782while (i >= 0) {1783n++;1784i = ldpath.indexOf(ps, i + 1);1785}17861787// allocate the array of paths - n :'s = n + 1 path elements1788String[] paths = new String[n + 1];17891790// Fill the array with paths from the ldpath1791n = i = 0;1792j = ldpath.indexOf(ps);1793while (j >= 0) {1794if (j - i > 0) {1795paths[n++] = ldpath.substring(i, j);1796} else if (j - i == 0) {1797paths[n++] = ".";1798}1799i = j + 1;1800j = ldpath.indexOf(ps, i);1801}1802paths[n] = ldpath.substring(i, ldlen);1803return paths;1804}18051806// Invoked in the java.lang.Runtime class to implement load and loadLibrary.1807static void loadLibrary(Class<?> fromClass, String name,1808boolean isAbsolute) {1809ClassLoader loader =1810(fromClass == null) ? null : fromClass.getClassLoader();1811if (sys_paths == null) {1812usr_paths = initializePath("java.library.path");1813sys_paths = initializePath("sun.boot.library.path");1814}1815if (isAbsolute) {1816if (loadLibrary0(fromClass, new File(name))) {1817return;1818}1819throw new UnsatisfiedLinkError("Can't load library: " + name);1820}1821if (loader != null) {1822String libfilename = loader.findLibrary(name);1823if (libfilename != null) {1824File libfile = new File(libfilename);1825if (!libfile.isAbsolute()) {1826throw new UnsatisfiedLinkError(1827"ClassLoader.findLibrary failed to return an absolute path: " + libfilename);1828}1829if (loadLibrary0(fromClass, libfile)) {1830return;1831}1832throw new UnsatisfiedLinkError("Can't load " + libfilename);1833}1834}1835for (int i = 0 ; i < sys_paths.length ; i++) {1836File libfile = new File(sys_paths[i], System.mapLibraryName(name));1837if (loadLibrary0(fromClass, libfile)) {1838return;1839}1840libfile = ClassLoaderHelper.mapAlternativeName(libfile);1841if (libfile != null && loadLibrary0(fromClass, libfile)) {1842return;1843}1844}1845if (loader != null) {1846for (int i = 0 ; i < usr_paths.length ; i++) {1847File libfile = new File(usr_paths[i],1848System.mapLibraryName(name));1849if (loadLibrary0(fromClass, libfile)) {1850return;1851}1852libfile = ClassLoaderHelper.mapAlternativeName(libfile);1853if (libfile != null && loadLibrary0(fromClass, libfile)) {1854return;1855}1856}1857}1858// Oops, it failed1859throw new UnsatisfiedLinkError("no " + name + " in java.library.path");1860}18611862private static native String findBuiltinLib(String name);18631864private static boolean loadLibrary0(Class<?> fromClass, final File file) {1865// Check to see if we're attempting to access a static library1866String name = findBuiltinLib(file.getName());1867boolean isBuiltin = (name != null);1868if (!isBuiltin) {1869boolean exists = AccessController.doPrivileged(1870new PrivilegedAction<Object>() {1871public Object run() {1872return file.exists() ? Boolean.TRUE : null;1873}})1874!= null;1875if (!exists) {1876return false;1877}1878try {1879name = file.getCanonicalPath();1880} catch (IOException e) {1881return false;1882}1883}1884ClassLoader loader =1885(fromClass == null) ? null : fromClass.getClassLoader();1886Vector<NativeLibrary> libs =1887loader != null ? loader.nativeLibraries : systemNativeLibraries;1888synchronized (libs) {1889int size = libs.size();1890for (int i = 0; i < size; i++) {1891NativeLibrary lib = libs.elementAt(i);1892if (name.equals(lib.name)) {1893return true;1894}1895}18961897synchronized (loadedLibraryNames) {1898if (loadedLibraryNames.contains(name)) {1899throw new UnsatisfiedLinkError1900("Native Library " +1901name +1902" already loaded in another classloader");1903}1904/* If the library is being loaded (must be by the same thread,1905* because Runtime.load and Runtime.loadLibrary are1906* synchronous). The reason is can occur is that the JNI_OnLoad1907* function can cause another loadLibrary invocation.1908*1909* Thus we can use a static stack to hold the list of libraries1910* we are loading.1911*1912* If there is a pending load operation for the library, we1913* immediately return success; otherwise, we raise1914* UnsatisfiedLinkError.1915*/1916int n = nativeLibraryContext.size();1917for (int i = 0; i < n; i++) {1918NativeLibrary lib = nativeLibraryContext.elementAt(i);1919if (name.equals(lib.name)) {1920if (loader == lib.fromClass.getClassLoader()) {1921return true;1922} else {1923throw new UnsatisfiedLinkError1924("Native Library " +1925name +1926" is being loaded in another classloader");1927}1928}1929}1930NativeLibrary lib = new NativeLibrary(fromClass, name, isBuiltin);1931nativeLibraryContext.push(lib);1932try {1933lib.load(name, isBuiltin);1934} finally {1935nativeLibraryContext.pop();1936}1937if (lib.loaded) {1938loadedLibraryNames.addElement(name);1939libs.addElement(lib);1940return true;1941}1942return false;1943}1944}1945}19461947// Invoked in the VM class linking code.1948static long findNative(ClassLoader loader, String name) {1949Vector<NativeLibrary> libs =1950loader != null ? loader.nativeLibraries : systemNativeLibraries;1951synchronized (libs) {1952int size = libs.size();1953for (int i = 0; i < size; i++) {1954NativeLibrary lib = libs.elementAt(i);1955long entry = lib.find(name);1956if (entry != 0)1957return entry;1958}1959}1960return 0;1961}196219631964// -- Assertion management --19651966final Object assertionLock;19671968// The default toggle for assertion checking.1969// @GuardedBy("assertionLock")1970private boolean defaultAssertionStatus = false;19711972// Maps String packageName to Boolean package default assertion status Note1973// that the default package is placed under a null map key. If this field1974// is null then we are delegating assertion status queries to the VM, i.e.,1975// none of this ClassLoader's assertion status modification methods have1976// been invoked.1977// @GuardedBy("assertionLock")1978private Map<String, Boolean> packageAssertionStatus = null;19791980// Maps String fullyQualifiedClassName to Boolean assertionStatus If this1981// field is null then we are delegating assertion status queries to the VM,1982// i.e., none of this ClassLoader's assertion status modification methods1983// have been invoked.1984// @GuardedBy("assertionLock")1985Map<String, Boolean> classAssertionStatus = null;19861987/**1988* Sets the default assertion status for this class loader. This setting1989* determines whether classes loaded by this class loader and initialized1990* in the future will have assertions enabled or disabled by default.1991* This setting may be overridden on a per-package or per-class basis by1992* invoking {@link #setPackageAssertionStatus(String, boolean)} or {@link1993* #setClassAssertionStatus(String, boolean)}.1994*1995* @param enabled1996* <tt>true</tt> if classes loaded by this class loader will1997* henceforth have assertions enabled by default, <tt>false</tt>1998* if they will have assertions disabled by default.1999*2000* @since 1.42001*/2002public void setDefaultAssertionStatus(boolean enabled) {2003synchronized (assertionLock) {2004if (classAssertionStatus == null)2005initializeJavaAssertionMaps();20062007defaultAssertionStatus = enabled;2008}2009}20102011/**2012* Sets the package default assertion status for the named package. The2013* package default assertion status determines the assertion status for2014* classes initialized in the future that belong to the named package or2015* any of its "subpackages".2016*2017* <p> A subpackage of a package named p is any package whose name begins2018* with "<tt>p.</tt>". For example, <tt>javax.swing.text</tt> is a2019* subpackage of <tt>javax.swing</tt>, and both <tt>java.util</tt> and2020* <tt>java.lang.reflect</tt> are subpackages of <tt>java</tt>.2021*2022* <p> In the event that multiple package defaults apply to a given class,2023* the package default pertaining to the most specific package takes2024* precedence over the others. For example, if <tt>javax.lang</tt> and2025* <tt>javax.lang.reflect</tt> both have package defaults associated with2026* them, the latter package default applies to classes in2027* <tt>javax.lang.reflect</tt>.2028*2029* <p> Package defaults take precedence over the class loader's default2030* assertion status, and may be overridden on a per-class basis by invoking2031* {@link #setClassAssertionStatus(String, boolean)}. </p>2032*2033* @param packageName2034* The name of the package whose package default assertion status2035* is to be set. A <tt>null</tt> value indicates the unnamed2036* package that is "current"2037* (see section 7.4.2 of2038* <cite>The Java™ Language Specification</cite>.)2039*2040* @param enabled2041* <tt>true</tt> if classes loaded by this classloader and2042* belonging to the named package or any of its subpackages will2043* have assertions enabled by default, <tt>false</tt> if they will2044* have assertions disabled by default.2045*2046* @since 1.42047*/2048public void setPackageAssertionStatus(String packageName,2049boolean enabled) {2050synchronized (assertionLock) {2051if (packageAssertionStatus == null)2052initializeJavaAssertionMaps();20532054packageAssertionStatus.put(packageName, enabled);2055}2056}20572058/**2059* Sets the desired assertion status for the named top-level class in this2060* class loader and any nested classes contained therein. This setting2061* takes precedence over the class loader's default assertion status, and2062* over any applicable per-package default. This method has no effect if2063* the named class has already been initialized. (Once a class is2064* initialized, its assertion status cannot change.)2065*2066* <p> If the named class is not a top-level class, this invocation will2067* have no effect on the actual assertion status of any class. </p>2068*2069* @param className2070* The fully qualified class name of the top-level class whose2071* assertion status is to be set.2072*2073* @param enabled2074* <tt>true</tt> if the named class is to have assertions2075* enabled when (and if) it is initialized, <tt>false</tt> if the2076* class is to have assertions disabled.2077*2078* @since 1.42079*/2080public void setClassAssertionStatus(String className, boolean enabled) {2081synchronized (assertionLock) {2082if (classAssertionStatus == null)2083initializeJavaAssertionMaps();20842085classAssertionStatus.put(className, enabled);2086}2087}20882089/**2090* Sets the default assertion status for this class loader to2091* <tt>false</tt> and discards any package defaults or class assertion2092* status settings associated with the class loader. This method is2093* provided so that class loaders can be made to ignore any command line or2094* persistent assertion status settings and "start with a clean slate."2095*2096* @since 1.42097*/2098public void clearAssertionStatus() {2099/*2100* Whether or not "Java assertion maps" are initialized, set2101* them to empty maps, effectively ignoring any present settings.2102*/2103synchronized (assertionLock) {2104classAssertionStatus = new HashMap<>();2105packageAssertionStatus = new HashMap<>();2106defaultAssertionStatus = false;2107}2108}21092110/**2111* Returns the assertion status that would be assigned to the specified2112* class if it were to be initialized at the time this method is invoked.2113* If the named class has had its assertion status set, the most recent2114* setting will be returned; otherwise, if any package default assertion2115* status pertains to this class, the most recent setting for the most2116* specific pertinent package default assertion status is returned;2117* otherwise, this class loader's default assertion status is returned.2118* </p>2119*2120* @param className2121* The fully qualified class name of the class whose desired2122* assertion status is being queried.2123*2124* @return The desired assertion status of the specified class.2125*2126* @see #setClassAssertionStatus(String, boolean)2127* @see #setPackageAssertionStatus(String, boolean)2128* @see #setDefaultAssertionStatus(boolean)2129*2130* @since 1.42131*/2132boolean desiredAssertionStatus(String className) {2133synchronized (assertionLock) {2134// assert classAssertionStatus != null;2135// assert packageAssertionStatus != null;21362137// Check for a class entry2138Boolean result = classAssertionStatus.get(className);2139if (result != null)2140return result.booleanValue();21412142// Check for most specific package entry2143int dotIndex = className.lastIndexOf(".");2144if (dotIndex < 0) { // default package2145result = packageAssertionStatus.get(null);2146if (result != null)2147return result.booleanValue();2148}2149while(dotIndex > 0) {2150className = className.substring(0, dotIndex);2151result = packageAssertionStatus.get(className);2152if (result != null)2153return result.booleanValue();2154dotIndex = className.lastIndexOf(".", dotIndex-1);2155}21562157// Return the classloader default2158return defaultAssertionStatus;2159}2160}21612162// Set up the assertions with information provided by the VM.2163// Note: Should only be called inside a synchronized block2164private void initializeJavaAssertionMaps() {2165// assert Thread.holdsLock(assertionLock);21662167classAssertionStatus = new HashMap<>();2168packageAssertionStatus = new HashMap<>();2169AssertionStatusDirectives directives = retrieveDirectives();21702171for(int i = 0; i < directives.classes.length; i++)2172classAssertionStatus.put(directives.classes[i],2173directives.classEnabled[i]);21742175for(int i = 0; i < directives.packages.length; i++)2176packageAssertionStatus.put(directives.packages[i],2177directives.packageEnabled[i]);21782179defaultAssertionStatus = directives.deflt;2180}21812182// Retrieves the assertion directives from the VM.2183private static native AssertionStatusDirectives retrieveDirectives();2184}218521862187class SystemClassLoaderAction2188implements PrivilegedExceptionAction<ClassLoader> {2189private ClassLoader parent;21902191SystemClassLoaderAction(ClassLoader parent) {2192this.parent = parent;2193}21942195public ClassLoader run() throws Exception {2196String cls = System.getProperty("java.system.class.loader");2197if (cls == null) {2198return parent;2199}22002201Constructor<?> ctor = Class.forName(cls, true, parent)2202.getDeclaredConstructor(new Class<?>[] { ClassLoader.class });2203ClassLoader sys = (ClassLoader) ctor.newInstance(2204new Object[] { parent });2205Thread.currentThread().setContextClassLoader(sys);2206return sys;2207}2208}220922102211