emul/src/main/java/java/lang/ClassLoader.java
author Jaroslav Tulach <jtulach@netbeans.org>
Tue, 30 Oct 2012 08:27:04 +0100
branchjdk7-b147
changeset 119 484416f2dc2c
child 122 0a582b5a2737
permissions -rw-r--r--
ClassLoader and closeable interface are needed as well
     1 /*
     2  * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    25 package java.lang;
    26 
    27 import java.io.InputStream;
    28 import java.io.IOException;
    29 import java.io.File;
    30 import java.lang.reflect.Constructor;
    31 import java.lang.reflect.InvocationTargetException;
    32 import java.net.MalformedURLException;
    33 import java.net.URL;
    34 import java.security.AccessController;
    35 import java.security.AccessControlContext;
    36 import java.security.CodeSource;
    37 import java.security.Policy;
    38 import java.security.PrivilegedAction;
    39 import java.security.PrivilegedActionException;
    40 import java.security.PrivilegedExceptionAction;
    41 import java.security.ProtectionDomain;
    42 import java.security.cert.Certificate;
    43 import java.util.Collections;
    44 import java.util.Enumeration;
    45 import java.util.HashMap;
    46 import java.util.HashSet;
    47 import java.util.Set;
    48 import java.util.Stack;
    49 import java.util.Map;
    50 import java.util.Vector;
    51 import java.util.Hashtable;
    52 import java.util.WeakHashMap;
    53 import java.util.concurrent.ConcurrentHashMap;
    54 import sun.misc.ClassFileTransformer;
    55 import sun.misc.CompoundEnumeration;
    56 import sun.misc.Resource;
    57 import sun.misc.URLClassPath;
    58 import sun.misc.VM;
    59 import sun.reflect.Reflection;
    60 import sun.security.util.SecurityConstants;
    61 
    62 /**
    63  * A class loader is an object that is responsible for loading classes. The
    64  * class <tt>ClassLoader</tt> is an abstract class.  Given the <a
    65  * href="#name">binary name</a> of a class, a class loader should attempt to
    66  * locate or generate data that constitutes a definition for the class.  A
    67  * typical strategy is to transform the name into a file name and then read a
    68  * "class file" of that name from a file system.
    69  *
    70  * <p> Every {@link Class <tt>Class</tt>} object contains a {@link
    71  * Class#getClassLoader() reference} to the <tt>ClassLoader</tt> that defined
    72  * it.
    73  *
    74  * <p> <tt>Class</tt> objects for array classes are not created by class
    75  * loaders, but are created automatically as required by the Java runtime.
    76  * The class loader for an array class, as returned by {@link
    77  * Class#getClassLoader()} is the same as the class loader for its element
    78  * type; if the element type is a primitive type, then the array class has no
    79  * class loader.
    80  *
    81  * <p> Applications implement subclasses of <tt>ClassLoader</tt> in order to
    82  * extend the manner in which the Java virtual machine dynamically loads
    83  * classes.
    84  *
    85  * <p> Class loaders may typically be used by security managers to indicate
    86  * security domains.
    87  *
    88  * <p> The <tt>ClassLoader</tt> class uses a delegation model to search for
    89  * classes and resources.  Each instance of <tt>ClassLoader</tt> has an
    90  * associated parent class loader.  When requested to find a class or
    91  * resource, a <tt>ClassLoader</tt> instance will delegate the search for the
    92  * class or resource to its parent class loader before attempting to find the
    93  * 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 may
    95  * serve as the parent of a <tt>ClassLoader</tt> instance.
    96  *
    97  * <p> Class loaders that support concurrent loading of classes are known as
    98  * <em>parallel capable</em> class loaders and are required to register
    99  * themselves at their class initialization time by invoking the
   100  * {@link
   101  * #registerAsParallelCapable <tt>ClassLoader.registerAsParallelCapable</tt>}
   102  * method. Note that the <tt>ClassLoader</tt> class is registered as parallel
   103  * capable by default. However, its subclasses still need to register themselves
   104  * if they are parallel capable. <br>
   105  * In environments in which the delegation model is not strictly
   106  * hierarchical, class loaders need to be parallel capable, otherwise class
   107  * loading can lead to deadlocks because the loader lock is held for the
   108  * duration of the class loading process (see {@link #loadClass
   109  * <tt>loadClass</tt>} methods).
   110  *
   111  * <p> Normally, the Java virtual machine loads classes from the local file
   112  * system in a platform-dependent manner.  For example, on UNIX systems, the
   113  * virtual machine loads classes from the directory defined by the
   114  * <tt>CLASSPATH</tt> environment variable.
   115  *
   116  * <p> However, some classes may not originate from a file; they may originate
   117  * from other sources, such as the network, or they could be constructed by an
   118  * application.  The method {@link #defineClass(String, byte[], int, int)
   119  * <tt>defineClass</tt>} converts an array of bytes into an instance of class
   120  * <tt>Class</tt>. Instances of this newly defined class can be created using
   121  * {@link Class#newInstance <tt>Class.newInstance</tt>}.
   122  *
   123  * <p> The methods and constructors of objects created by a class loader may
   124  * reference other classes.  To determine the class(es) referred to, the Java
   125  * virtual machine invokes the {@link #loadClass <tt>loadClass</tt>} method of
   126  * the class loader that originally created the class.
   127  *
   128  * <p> For example, an application could create a network class loader to
   129  * download class files from a server.  Sample code might look like:
   130  *
   131  * <blockquote><pre>
   132  *   ClassLoader loader&nbsp;= new NetworkClassLoader(host,&nbsp;port);
   133  *   Object main&nbsp;= loader.loadClass("Main", true).newInstance();
   134  *       &nbsp;.&nbsp;.&nbsp;.
   135  * </pre></blockquote>
   136  *
   137  * <p> The network class loader subclass must define the methods {@link
   138  * #findClass <tt>findClass</tt>} and <tt>loadClassData</tt> to load a class
   139  * 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>} to
   141  * 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 connection
   155  *             &nbsp;.&nbsp;.&nbsp;.
   156  *         }
   157  *     }
   158  * </pre></blockquote>
   159  *
   160  * <h4> <a name="name">Binary names</a> </h4>
   161  *
   162  * <p> Any class name provided as a {@link String} parameter to methods in
   163  * <tt>ClassLoader</tt> must be a binary name as defined by
   164  * <cite>The Java&trade; 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.0
   176  */
   177 public abstract class ClassLoader {
   178 
   179     private static native void registerNatives();
   180     static {
   181         registerNatives();
   182     }
   183 
   184     // The parent class loader for delegation
   185     // Note: VM hardcoded the offset of this field, thus all new fields
   186     // must be added *after* it.
   187     private final ClassLoader parent;
   188 
   189     /**
   190      * Encapsulates the set of parallel capable loader types.
   191      */
   192     private static class ParallelLoaders {
   193         private ParallelLoaders() {}
   194 
   195         // the set of parallel capable loader types
   196         private static final Set<Class<? extends ClassLoader>> loaderTypes =
   197             Collections.newSetFromMap(
   198                 new WeakHashMap<Class<? extends ClassLoader>, Boolean>());
   199         static {
   200             synchronized (loaderTypes) { loaderTypes.add(ClassLoader.class); }
   201         }
   202 
   203         /**
   204          * Registers the given class loader type as parallel capabale.
   205          * Returns {@code true} is successfully registered; {@code false} if
   206          * loader's super class is not registered.
   207          */
   208         static boolean register(Class<? extends ClassLoader> c) {
   209             synchronized (loaderTypes) {
   210                 if (loaderTypes.contains(c.getSuperclass())) {
   211                     // register the class loader as parallel capable
   212                     // if and only if all of its super classes are.
   213                     // Note: given current classloading sequence, if
   214                     // the immediate super class is parallel capable,
   215                     // all the super classes higher up must be too.
   216                     loaderTypes.add(c);
   217                     return true;
   218                 } else {
   219                     return false;
   220                 }
   221             }
   222         }
   223 
   224         /**
   225          * Returns {@code true} if the given class loader type is
   226          * registered as parallel capable.
   227          */
   228         static boolean isRegistered(Class<? extends ClassLoader> c) {
   229             synchronized (loaderTypes) {
   230                 return loaderTypes.contains(c);
   231             }
   232         }
   233     }
   234 
   235     // Maps class name to the corresponding lock object when the current
   236     // class loader is parallel capable.
   237     // Note: VM also uses this field to decide if the current class loader
   238     // is parallel capable and the appropriate lock object for class loading.
   239     private final ConcurrentHashMap<String, Object> parallelLockMap;
   240 
   241     // Hashtable that maps packages to certs
   242     private final Map <String, Certificate[]> package2certs;
   243 
   244     // Shared among all packages with unsigned classes
   245     private static final Certificate[] nocerts = new Certificate[0];
   246 
   247     // The classes loaded by this class loader. The only purpose of this table
   248     // is to keep the classes from being GC'ed until the loader is GC'ed.
   249     private final Vector<Class<?>> classes = new Vector<>();
   250 
   251     // The "default" domain. Set as the default ProtectionDomain on newly
   252     // created classes.
   253     private final ProtectionDomain defaultDomain =
   254         new ProtectionDomain(new CodeSource(null, (Certificate[]) null),
   255                              null, this, null);
   256 
   257     // The initiating protection domains for all classes loaded by this loader
   258     private final Set<ProtectionDomain> domains;
   259 
   260     // Invoked by the VM to record every loaded class with this loader.
   261     void addClass(Class c) {
   262         classes.addElement(c);
   263     }
   264 
   265     // The packages defined in this class loader.  Each package name is mapped
   266     // to its corresponding Package object.
   267     // @GuardedBy("itself")
   268     private final HashMap<String, Package> packages = new HashMap<>();
   269 
   270     private static Void checkCreateClassLoader() {
   271         SecurityManager security = System.getSecurityManager();
   272         if (security != null) {
   273             security.checkCreateClassLoader();
   274         }
   275         return null;
   276     }
   277 
   278     private ClassLoader(Void unused, ClassLoader parent) {
   279         this.parent = parent;
   280         if (ParallelLoaders.isRegistered(this.getClass())) {
   281             parallelLockMap = new ConcurrentHashMap<>();
   282             package2certs = new ConcurrentHashMap<>();
   283             domains =
   284                 Collections.synchronizedSet(new HashSet<ProtectionDomain>());
   285             assertionLock = new Object();
   286         } else {
   287             // no finer-grained lock; lock on the classloader instance
   288             parallelLockMap = null;
   289             package2certs = new Hashtable<>();
   290             domains = new HashSet<>();
   291             assertionLock = this;
   292         }
   293     }
   294 
   295     /**
   296      * Creates a new class loader using the specified parent class loader for
   297      * delegation.
   298      *
   299      * <p> If there is a security manager, its {@link
   300      * SecurityManager#checkCreateClassLoader()
   301      * <tt>checkCreateClassLoader</tt>} method is invoked.  This may result in
   302      * a security exception.  </p>
   303      *
   304      * @param  parent
   305      *         The parent class loader
   306      *
   307      * @throws  SecurityException
   308      *          If a security manager exists and its
   309      *          <tt>checkCreateClassLoader</tt> method doesn't allow creation
   310      *          of a new class loader.
   311      *
   312      * @since  1.2
   313      */
   314     protected ClassLoader(ClassLoader parent) {
   315         this(checkCreateClassLoader(), parent);
   316     }
   317 
   318     /**
   319      * Creates a new class loader using the <tt>ClassLoader</tt> returned by
   320      * the method {@link #getSystemClassLoader()
   321      * <tt>getSystemClassLoader()</tt>} as the parent class loader.
   322      *
   323      * <p> If there is a security manager, its {@link
   324      * SecurityManager#checkCreateClassLoader()
   325      * <tt>checkCreateClassLoader</tt>} method is invoked.  This may result in
   326      * a security exception.  </p>
   327      *
   328      * @throws  SecurityException
   329      *          If a security manager exists and its
   330      *          <tt>checkCreateClassLoader</tt> method doesn't allow creation
   331      *          of a new class loader.
   332      */
   333     protected ClassLoader() {
   334         this(checkCreateClassLoader(), getSystemClassLoader());
   335     }
   336 
   337     // -- Class --
   338 
   339     /**
   340      * Loads the class with the specified <a href="#name">binary name</a>.
   341      * This method searches for classes in the same manner as the {@link
   342      * #loadClass(String, boolean)} method.  It is invoked by the Java virtual
   343      * machine to resolve class references.  Invoking this method is equivalent
   344      * to invoking {@link #loadClass(String, boolean) <tt>loadClass(name,
   345      * false)</tt>}.  </p>
   346      *
   347      * @param  name
   348      *         The <a href="#name">binary name</a> of the class
   349      *
   350      * @return  The resulting <tt>Class</tt> object
   351      *
   352      * @throws  ClassNotFoundException
   353      *          If the class was not found
   354      */
   355     public Class<?> loadClass(String name) throws ClassNotFoundException {
   356         return loadClass(name, false);
   357     }
   358 
   359     /**
   360      * Loads the class with the specified <a href="#name">binary name</a>.  The
   361      * default implementation of this method searches for classes in the
   362      * following order:
   363      *
   364      * <p><ol>
   365      *
   366      *   <li><p> Invoke {@link #findLoadedClass(String)} to check if the class
   367      *   has already been loaded.  </p></li>
   368      *
   369      *   <li><p> Invoke the {@link #loadClass(String) <tt>loadClass</tt>} method
   370      *   on the parent class loader.  If the parent is <tt>null</tt> the class
   371      *   loader built-in to the virtual machine is used, instead.  </p></li>
   372      *
   373      *   <li><p> Invoke the {@link #findClass(String)} method to find the
   374      *   class.  </p></li>
   375      *
   376      * </ol>
   377      *
   378      * <p> If the class was found using the above steps, and the
   379      * <tt>resolve</tt> flag is true, this method will then invoke the {@link
   380      * #resolveClass(Class)} method on the resulting <tt>Class</tt> object.
   381      *
   382      * <p> Subclasses of <tt>ClassLoader</tt> are encouraged to override {@link
   383      * #findClass(String)}, rather than this method.  </p>
   384      *
   385      * <p> Unless overridden, this method synchronizes on the result of
   386      * {@link #getClassLoadingLock <tt>getClassLoadingLock</tt>} method
   387      * during the entire class loading process.
   388      *
   389      * @param  name
   390      *         The <a href="#name">binary name</a> of the class
   391      *
   392      * @param  resolve
   393      *         If <tt>true</tt> then resolve the class
   394      *
   395      * @return  The resulting <tt>Class</tt> object
   396      *
   397      * @throws  ClassNotFoundException
   398      *          If the class could not be found
   399      */
   400     protected Class<?> loadClass(String name, boolean resolve)
   401         throws ClassNotFoundException
   402     {
   403         synchronized (getClassLoadingLock(name)) {
   404             // First, check if the class has already been loaded
   405             Class c = findLoadedClass(name);
   406             if (c == null) {
   407                 long t0 = System.nanoTime();
   408                 try {
   409                     if (parent != null) {
   410                         c = parent.loadClass(name, false);
   411                     } else {
   412                         c = findBootstrapClassOrNull(name);
   413                     }
   414                 } catch (ClassNotFoundException e) {
   415                     // ClassNotFoundException thrown if class not found
   416                     // from the non-null parent class loader
   417                 }
   418 
   419                 if (c == null) {
   420                     // If still not found, then invoke findClass in order
   421                     // to find the class.
   422                     long t1 = System.nanoTime();
   423                     c = findClass(name);
   424 
   425                     // this is the defining class loader; record the stats
   426                     sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
   427                     sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
   428                     sun.misc.PerfCounter.getFindClasses().increment();
   429                 }
   430             }
   431             if (resolve) {
   432                 resolveClass(c);
   433             }
   434             return c;
   435         }
   436     }
   437 
   438     /**
   439      * Returns the lock object for class loading operations.
   440      * For backward compatibility, the default implementation of this method
   441      * behaves as follows. If this ClassLoader object is registered as
   442      * parallel capable, the method returns a dedicated object associated
   443      * with the specified class name. Otherwise, the method returns this
   444      * ClassLoader object. </p>
   445      *
   446      * @param  className
   447      *         The name of the to-be-loaded class
   448      *
   449      * @return the lock for class loading operations
   450      *
   451      * @throws NullPointerException
   452      *         If registered as parallel capable and <tt>className</tt> is null
   453      *
   454      * @see #loadClass(String, boolean)
   455      *
   456      * @since  1.7
   457      */
   458     protected Object getClassLoadingLock(String className) {
   459         Object lock = this;
   460         if (parallelLockMap != null) {
   461             Object newLock = new Object();
   462             lock = parallelLockMap.putIfAbsent(className, newLock);
   463             if (lock == null) {
   464                 lock = newLock;
   465             }
   466         }
   467         return lock;
   468     }
   469 
   470     // This method is invoked by the virtual machine to load a class.
   471     private Class loadClassInternal(String name)
   472         throws ClassNotFoundException
   473     {
   474         // For backward compatibility, explicitly lock on 'this' when
   475         // the current class loader is not parallel capable.
   476         if (parallelLockMap == null) {
   477             synchronized (this) {
   478                  return loadClass(name);
   479             }
   480         } else {
   481             return loadClass(name);
   482         }
   483     }
   484 
   485     // Invoked by the VM after loading class with this loader.
   486     private void checkPackageAccess(Class cls, ProtectionDomain pd) {
   487         final SecurityManager sm = System.getSecurityManager();
   488         if (sm != null) {
   489             final String name = cls.getName();
   490             final int i = name.lastIndexOf('.');
   491             if (i != -1) {
   492                 AccessController.doPrivileged(new PrivilegedAction<Void>() {
   493                     public Void run() {
   494                         sm.checkPackageAccess(name.substring(0, i));
   495                         return null;
   496                     }
   497                 }, new AccessControlContext(new ProtectionDomain[] {pd}));
   498             }
   499         }
   500         domains.add(pd);
   501     }
   502 
   503     /**
   504      * Finds the class with the specified <a href="#name">binary name</a>.
   505      * This method should be overridden by class loader implementations that
   506      * follow the delegation model for loading classes, and will be invoked by
   507      * the {@link #loadClass <tt>loadClass</tt>} method after checking the
   508      * parent class loader for the requested class.  The default implementation
   509      * throws a <tt>ClassNotFoundException</tt>.  </p>
   510      *
   511      * @param  name
   512      *         The <a href="#name">binary name</a> of the class
   513      *
   514      * @return  The resulting <tt>Class</tt> object
   515      *
   516      * @throws  ClassNotFoundException
   517      *          If the class could not be found
   518      *
   519      * @since  1.2
   520      */
   521     protected Class<?> findClass(String name) throws ClassNotFoundException {
   522         throw new ClassNotFoundException(name);
   523     }
   524 
   525     /**
   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 method
   528      * is deprecated in favor of the version that takes a <a
   529      * href="#name">binary name</a> as its first argument, and is more secure.
   530      *
   531      * @param  b
   532      *         The bytes that make up the class data.  The bytes in positions
   533      *         <tt>off</tt> through <tt>off+len-1</tt> should have the format
   534      *         of a valid class file as defined by
   535      *         <cite>The Java&trade; Virtual Machine Specification</cite>.
   536      *
   537      * @param  off
   538      *         The start offset in <tt>b</tt> of the class data
   539      *
   540      * @param  len
   541      *         The length of the class data
   542      *
   543      * @return  The <tt>Class</tt> object that was created from the specified
   544      *          class data
   545      *
   546      * @throws  ClassFormatError
   547      *          If the data did not contain a valid class
   548      *
   549      * @throws  IndexOutOfBoundsException
   550      *          If either <tt>off</tt> or <tt>len</tt> is negative, or if
   551      *          <tt>off+len</tt> is greater than <tt>b.length</tt>.
   552      *
   553      * @throws  SecurityException
   554      *          If an attempt is made to add this class to a package that
   555      *          contains classes that were signed by a different set of
   556      *          certificates than this class, or if an attempt is made
   557      *          to define a class in a package with a fully-qualified name
   558      *          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     @Deprecated
   567     protected final Class<?> defineClass(byte[] b, int off, int len)
   568         throws ClassFormatError
   569     {
   570         return defineClass(null, b, off, len, null);
   571     }
   572 
   573     /**
   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.ProtectionDomain
   578      * <tt>ProtectionDomain</tt>} to the newly defined class.  The
   579      * <tt>ProtectionDomain</tt> is effectively granted the same set of
   580      * permissions returned when {@link
   581      * 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 of
   584      * {@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, use
   588      * the {@link #defineClass(String, byte[], int, int,
   589      * java.security.ProtectionDomain) <tt>defineClass</tt>} method that takes a
   590      * <tt>ProtectionDomain</tt> as one of its arguments.  </p>
   591      *
   592      * @param  name
   593      *         The expected <a href="#name">binary name</a> of the class, or
   594      *         <tt>null</tt> if not known
   595      *
   596      * @param  b
   597      *         The bytes that make up the class data.  The bytes in positions
   598      *         <tt>off</tt> through <tt>off+len-1</tt> should have the format
   599      *         of a valid class file as defined by
   600      *         <cite>The Java&trade; Virtual Machine Specification</cite>.
   601      *
   602      * @param  off
   603      *         The start offset in <tt>b</tt> of the class data
   604      *
   605      * @param  len
   606      *         The length of the class data
   607      *
   608      * @return  The <tt>Class</tt> object that was created from the specified
   609      *          class data.
   610      *
   611      * @throws  ClassFormatError
   612      *          If the data did not contain a valid class
   613      *
   614      * @throws  IndexOutOfBoundsException
   615      *          If either <tt>off</tt> or <tt>len</tt> is negative, or if
   616      *          <tt>off+len</tt> is greater than <tt>b.length</tt>.
   617      *
   618      * @throws  SecurityException
   619      *          If an attempt is made to add this class to a package that
   620      *          contains classes that were signed by a different set of
   621      *          certificates than this class (which is unsigned), or if
   622      *          <tt>name</tt> begins with "<tt>java.</tt>".
   623      *
   624      * @see  #loadClass(String, boolean)
   625      * @see  #resolveClass(Class)
   626      * @see  java.security.CodeSource
   627      * @see  java.security.SecureClassLoader
   628      *
   629      * @since  1.1
   630      */
   631     protected final Class<?> defineClass(String name, byte[] b, int off, int len)
   632         throws ClassFormatError
   633     {
   634         return defineClass(name, b, off, len, null);
   635     }
   636 
   637     /* Determine protection domain, and check that:
   638         - not define java.* class,
   639         - signer of this class matches signers for the rest of the classes in
   640           package.
   641     */
   642     private ProtectionDomain preDefineClass(String name,
   643                                             ProtectionDomain pd)
   644     {
   645         if (!checkName(name))
   646             throw new NoClassDefFoundError("IllegalName: " + name);
   647 
   648         if ((name != null) && name.startsWith("java.")) {
   649             throw new SecurityException
   650                 ("Prohibited package name: " +
   651                  name.substring(0, name.lastIndexOf('.')));
   652         }
   653         if (pd == null) {
   654             pd = defaultDomain;
   655         }
   656 
   657         if (name != null) checkCerts(name, pd.getCodeSource());
   658 
   659         return pd;
   660     }
   661 
   662     private String defineClassSourceLocation(ProtectionDomain pd)
   663     {
   664         CodeSource cs = pd.getCodeSource();
   665         String source = null;
   666         if (cs != null && cs.getLocation() != null) {
   667             source = cs.getLocation().toString();
   668         }
   669         return source;
   670     }
   671 
   672     private Class defineTransformedClass(String name, byte[] b, int off, int len,
   673                                          ProtectionDomain pd,
   674                                          ClassFormatError cfe, String source)
   675       throws ClassFormatError
   676     {
   677         // Class format error - try to transform the bytecode and
   678         // define the class again
   679         //
   680         ClassFileTransformer[] transformers =
   681             ClassFileTransformer.getTransformers();
   682         Class c = null;
   683 
   684         if (transformers != null) {
   685             for (ClassFileTransformer transformer : transformers) {
   686                 try {
   687                     // Transform byte code using transformer
   688                     byte[] tb = transformer.transform(b, off, len);
   689                     c = defineClass1(name, tb, 0, tb.length,
   690                                      pd, source);
   691                     break;
   692                 } catch (ClassFormatError cfe2)     {
   693                     // If ClassFormatError occurs, try next transformer
   694                 }
   695             }
   696         }
   697 
   698         // Rethrow original ClassFormatError if unable to transform
   699         // bytecode to well-formed
   700         //
   701         if (c == null)
   702             throw cfe;
   703 
   704         return c;
   705     }
   706 
   707     private void postDefineClass(Class c, ProtectionDomain pd)
   708     {
   709         if (pd.getCodeSource() != null) {
   710             Certificate certs[] = pd.getCodeSource().getCertificates();
   711             if (certs != null)
   712                 setSigners(c, certs);
   713         }
   714     }
   715 
   716     /**
   717      * Converts an array of bytes into an instance of class <tt>Class</tt>,
   718      * with an optional <tt>ProtectionDomain</tt>.  If the domain is
   719      * <tt>null</tt>, then a default domain will be assigned to the class as
   720      * specified in the documentation for {@link #defineClass(String, byte[],
   721      * int, int)}.  Before the class can be used it must be resolved.
   722      *
   723      * <p> The first class defined in a package determines the exact set of
   724      * certificates that all subsequent classes defined in that package must
   725      * contain.  The set of certificates for a class is obtained from the
   726      * {@link java.security.CodeSource <tt>CodeSource</tt>} within the
   727      * <tt>ProtectionDomain</tt> of the class.  Any classes added to that
   728      * package must contain the same set of certificates or a
   729      * <tt>SecurityException</tt> will be thrown.  Note that if
   730      * <tt>name</tt> is <tt>null</tt>, this check is not performed.
   731      * You should always pass in the <a href="#name">binary name</a> of the
   732      * class you are defining as well as the bytes.  This ensures that the
   733      * class you are defining is indeed the class you think it is.
   734      *
   735      * <p> The specified <tt>name</tt> cannot begin with "<tt>java.</tt>", since
   736      * all classes in the "<tt>java.*</tt> packages can only be defined by the
   737      * bootstrap class loader.  If <tt>name</tt> is not <tt>null</tt>, it
   738      * must be equal to the <a href="#name">binary name</a> of the class
   739      * specified by the byte array "<tt>b</tt>", otherwise a {@link
   740      * <tt>NoClassDefFoundError</tt>} will be thrown.  </p>
   741      *
   742      * @param  name
   743      *         The expected <a href="#name">binary name</a> of the class, or
   744      *         <tt>null</tt> if not known
   745      *
   746      * @param  b
   747      *         The bytes that make up the class data. The bytes in positions
   748      *         <tt>off</tt> through <tt>off+len-1</tt> should have the format
   749      *         of a valid class file as defined by
   750      *         <cite>The Java&trade; Virtual Machine Specification</cite>.
   751      *
   752      * @param  off
   753      *         The start offset in <tt>b</tt> of the class data
   754      *
   755      * @param  len
   756      *         The length of the class data
   757      *
   758      * @param  protectionDomain
   759      *         The ProtectionDomain of the class
   760      *
   761      * @return  The <tt>Class</tt> object created from the data,
   762      *          and optional <tt>ProtectionDomain</tt>.
   763      *
   764      * @throws  ClassFormatError
   765      *          If the data did not contain a valid class
   766      *
   767      * @throws  NoClassDefFoundError
   768      *          If <tt>name</tt> is not equal to the <a href="#name">binary
   769      *          name</a> of the class specified by <tt>b</tt>
   770      *
   771      * @throws  IndexOutOfBoundsException
   772      *          If either <tt>off</tt> or <tt>len</tt> is negative, or if
   773      *          <tt>off+len</tt> is greater than <tt>b.length</tt>.
   774      *
   775      * @throws  SecurityException
   776      *          If an attempt is made to add this class to a package that
   777      *          contains classes that were signed by a different set of
   778      *          certificates than this class, or if <tt>name</tt> begins with
   779      *          "<tt>java.</tt>".
   780      */
   781     protected final Class<?> defineClass(String name, byte[] b, int off, int len,
   782                                          ProtectionDomain protectionDomain)
   783         throws ClassFormatError
   784     {
   785         protectionDomain = preDefineClass(name, protectionDomain);
   786 
   787         Class c = null;
   788         String source = defineClassSourceLocation(protectionDomain);
   789 
   790         try {
   791             c = defineClass1(name, b, off, len, protectionDomain, source);
   792         } catch (ClassFormatError cfe) {
   793             c = defineTransformedClass(name, b, off, len, protectionDomain, cfe,
   794                                        source);
   795         }
   796 
   797         postDefineClass(c, protectionDomain);
   798         return c;
   799     }
   800 
   801     /**
   802      * Converts a {@link java.nio.ByteBuffer <tt>ByteBuffer</tt>}
   803      * into an instance of class <tt>Class</tt>,
   804      * with an optional <tt>ProtectionDomain</tt>.  If the domain is
   805      * <tt>null</tt>, then a default domain will be assigned to the class as
   806      * specified in the documentation for {@link #defineClass(String, byte[],
   807      * int, int)}.  Before the class can be used it must be resolved.
   808      *
   809      * <p>The rules about the first class defined in a package determining the
   810      * set of certificates for the package, and the restrictions on class names
   811      * are identical to those specified in the documentation for {@link
   812      * #defineClass(String, byte[], int, int, ProtectionDomain)}.
   813      *
   814      * <p> An invocation of this method of the form
   815      * <i>cl</i><tt>.defineClass(</tt><i>name</i><tt>,</tt>
   816      * <i>bBuffer</i><tt>,</tt> <i>pd</i><tt>)</tt> yields exactly the same
   817      * result as the statements
   818      *
   819      * <blockquote><tt>
   820      * ...<br>
   821      * byte[] temp = new byte[</tt><i>bBuffer</i><tt>.{@link
   822      * java.nio.ByteBuffer#remaining remaining}()];<br>
   823      *     </tt><i>bBuffer</i><tt>.{@link java.nio.ByteBuffer#get(byte[])
   824      * get}(temp);<br>
   825      *     return {@link #defineClass(String, byte[], int, int, ProtectionDomain)
   826      * </tt><i>cl</i><tt>.defineClass}(</tt><i>name</i><tt>, temp, 0,
   827      * temp.length, </tt><i>pd</i><tt>);<br>
   828      * </tt></blockquote>
   829      *
   830      * @param  name
   831      *         The expected <a href="#name">binary name</a>. of the class, or
   832      *         <tt>null</tt> if not known
   833      *
   834      * @param  b
   835      *         The bytes that make up the class data. The bytes from positions
   836      *         <tt>b.position()</tt> through <tt>b.position() + b.limit() -1
   837      *         </tt> should have the format of a valid class file as defined by
   838      *         <cite>The Java&trade; Virtual Machine Specification</cite>.
   839      *
   840      * @param  protectionDomain
   841      *         The ProtectionDomain of the class, or <tt>null</tt>.
   842      *
   843      * @return  The <tt>Class</tt> object created from the data,
   844      *          and optional <tt>ProtectionDomain</tt>.
   845      *
   846      * @throws  ClassFormatError
   847      *          If the data did not contain a valid class.
   848      *
   849      * @throws  NoClassDefFoundError
   850      *          If <tt>name</tt> is not equal to the <a href="#name">binary
   851      *          name</a> of the class specified by <tt>b</tt>
   852      *
   853      * @throws  SecurityException
   854      *          If an attempt is made to add this class to a package that
   855      *          contains classes that were signed by a different set of
   856      *          certificates than this class, or if <tt>name</tt> begins with
   857      *          "<tt>java.</tt>".
   858      *
   859      * @see      #defineClass(String, byte[], int, int, ProtectionDomain)
   860      *
   861      * @since  1.5
   862      */
   863     protected final Class<?> defineClass(String name, java.nio.ByteBuffer b,
   864                                          ProtectionDomain protectionDomain)
   865         throws ClassFormatError
   866     {
   867         int len = b.remaining();
   868 
   869         // Use byte[] if not a direct ByteBufer:
   870         if (!b.isDirect()) {
   871             if (b.hasArray()) {
   872                 return defineClass(name, b.array(),
   873                                    b.position() + b.arrayOffset(), len,
   874                                    protectionDomain);
   875             } else {
   876                 // no array, or read-only array
   877                 byte[] tb = new byte[len];
   878                 b.get(tb);  // get bytes out of byte buffer.
   879                 return defineClass(name, tb, 0, len, protectionDomain);
   880             }
   881         }
   882 
   883         protectionDomain = preDefineClass(name, protectionDomain);
   884 
   885         Class c = null;
   886         String source = defineClassSourceLocation(protectionDomain);
   887 
   888         try {
   889             c = defineClass2(name, b, b.position(), len, protectionDomain,
   890                              source);
   891         } catch (ClassFormatError cfe) {
   892             byte[] tb = new byte[len];
   893             b.get(tb);  // get bytes out of byte buffer.
   894             c = defineTransformedClass(name, tb, 0, len, protectionDomain, cfe,
   895                                        source);
   896         }
   897 
   898         postDefineClass(c, protectionDomain);
   899         return c;
   900     }
   901 
   902     private native Class defineClass0(String name, byte[] b, int off, int len,
   903                                       ProtectionDomain pd);
   904 
   905     private native Class defineClass1(String name, byte[] b, int off, int len,
   906                                       ProtectionDomain pd, String source);
   907 
   908     private native Class defineClass2(String name, java.nio.ByteBuffer b,
   909                                       int off, int len, ProtectionDomain pd,
   910                                       String source);
   911 
   912     // true if the name is null or has the potential to be a valid binary name
   913     private boolean checkName(String name) {
   914         if ((name == null) || (name.length() == 0))
   915             return true;
   916         if ((name.indexOf('/') != -1)
   917             || (!VM.allowArraySyntax() && (name.charAt(0) == '[')))
   918             return false;
   919         return true;
   920     }
   921 
   922     private void checkCerts(String name, CodeSource cs) {
   923         int i = name.lastIndexOf('.');
   924         String pname = (i == -1) ? "" : name.substring(0, i);
   925 
   926         Certificate[] certs = null;
   927         if (cs != null) {
   928             certs = cs.getCertificates();
   929         }
   930         Certificate[] pcerts = null;
   931         if (parallelLockMap == null) {
   932             synchronized (this) {
   933                 pcerts = package2certs.get(pname);
   934                 if (pcerts == null) {
   935                     package2certs.put(pname, (certs == null? nocerts:certs));
   936                 }
   937             }
   938         } else {
   939             pcerts = ((ConcurrentHashMap<String, Certificate[]>)package2certs).
   940                 putIfAbsent(pname, (certs == null? nocerts:certs));
   941         }
   942         if (pcerts != null && !compareCerts(pcerts, certs)) {
   943             throw new SecurityException("class \""+ name +
   944                  "\"'s signer information does not match signer information of other classes in the same package");
   945         }
   946     }
   947 
   948     /**
   949      * check to make sure the certs for the new class (certs) are the same as
   950      * the certs for the first class inserted in the package (pcerts)
   951      */
   952     private boolean compareCerts(Certificate[] pcerts,
   953                                  Certificate[] certs)
   954     {
   955         // certs can be null, indicating no certs.
   956         if ((certs == null) || (certs.length == 0)) {
   957             return pcerts.length == 0;
   958         }
   959 
   960         // the length must be the same at this point
   961         if (certs.length != pcerts.length)
   962             return false;
   963 
   964         // go through and make sure all the certs in one array
   965         // are in the other and vice-versa.
   966         boolean match;
   967         for (int i = 0; i < certs.length; i++) {
   968             match = false;
   969             for (int j = 0; j < pcerts.length; j++) {
   970                 if (certs[i].equals(pcerts[j])) {
   971                     match = true;
   972                     break;
   973                 }
   974             }
   975             if (!match) return false;
   976         }
   977 
   978         // now do the same for pcerts
   979         for (int i = 0; i < pcerts.length; i++) {
   980             match = false;
   981             for (int j = 0; j < certs.length; j++) {
   982                 if (pcerts[i].equals(certs[j])) {
   983                     match = true;
   984                     break;
   985                 }
   986             }
   987             if (!match) return false;
   988         }
   989 
   990         return true;
   991     }
   992 
   993     /**
   994      * Links the specified class.  This (misleadingly named) method may be
   995      * used by a class loader to link a class.  If the class <tt>c</tt> has
   996      * already been linked, then this method simply returns. Otherwise, the
   997      * class is linked as described in the "Execution" chapter of
   998      * <cite>The Java&trade; Language Specification</cite>.
   999      * </p>
  1000      *
  1001      * @param  c
  1002      *         The class to link
  1003      *
  1004      * @throws  NullPointerException
  1005      *          If <tt>c</tt> is <tt>null</tt>.
  1006      *
  1007      * @see  #defineClass(String, byte[], int, int)
  1008      */
  1009     protected final void resolveClass(Class<?> c) {
  1010         resolveClass0(c);
  1011     }
  1012 
  1013     private native void resolveClass0(Class c);
  1014 
  1015     /**
  1016      * Finds a class with the specified <a href="#name">binary name</a>,
  1017      * loading it if necessary.
  1018      *
  1019      * <p> This method loads the class through the system class loader (see
  1020      * {@link #getSystemClassLoader()}).  The <tt>Class</tt> object returned
  1021      * might have more than one <tt>ClassLoader</tt> associated with it.
  1022      * Subclasses of <tt>ClassLoader</tt> need not usually invoke this method,
  1023      * because most class loaders need to override just {@link
  1024      * #findClass(String)}.  </p>
  1025      *
  1026      * @param  name
  1027      *         The <a href="#name">binary name</a> of the class
  1028      *
  1029      * @return  The <tt>Class</tt> object for the specified <tt>name</tt>
  1030      *
  1031      * @throws  ClassNotFoundException
  1032      *          If the class could not be found
  1033      *
  1034      * @see  #ClassLoader(ClassLoader)
  1035      * @see  #getParent()
  1036      */
  1037     protected final Class<?> findSystemClass(String name)
  1038         throws ClassNotFoundException
  1039     {
  1040         ClassLoader system = getSystemClassLoader();
  1041         if (system == null) {
  1042             if (!checkName(name))
  1043                 throw new ClassNotFoundException(name);
  1044             Class cls = findBootstrapClass(name);
  1045             if (cls == null) {
  1046                 throw new ClassNotFoundException(name);
  1047             }
  1048             return cls;
  1049         }
  1050         return system.loadClass(name);
  1051     }
  1052 
  1053     /**
  1054      * Returns a class loaded by the bootstrap class loader;
  1055      * or return null if not found.
  1056      */
  1057     private Class findBootstrapClassOrNull(String name)
  1058     {
  1059         if (!checkName(name)) return null;
  1060 
  1061         return findBootstrapClass(name);
  1062     }
  1063 
  1064     // return null if not found
  1065     private native Class findBootstrapClass(String name);
  1066 
  1067     /**
  1068      * Returns the class with the given <a href="#name">binary name</a> if this
  1069      * loader has been recorded by the Java virtual machine as an initiating
  1070      * loader of a class with that <a href="#name">binary name</a>.  Otherwise
  1071      * <tt>null</tt> is returned.  </p>
  1072      *
  1073      * @param  name
  1074      *         The <a href="#name">binary name</a> of the class
  1075      *
  1076      * @return  The <tt>Class</tt> object, or <tt>null</tt> if the class has
  1077      *          not been loaded
  1078      *
  1079      * @since  1.1
  1080      */
  1081     protected final Class<?> findLoadedClass(String name) {
  1082         if (!checkName(name))
  1083             return null;
  1084         return findLoadedClass0(name);
  1085     }
  1086 
  1087     private native final Class findLoadedClass0(String name);
  1088 
  1089     /**
  1090      * Sets the signers of a class.  This should be invoked after defining a
  1091      * class.  </p>
  1092      *
  1093      * @param  c
  1094      *         The <tt>Class</tt> object
  1095      *
  1096      * @param  signers
  1097      *         The signers for the class
  1098      *
  1099      * @since  1.1
  1100      */
  1101     protected final void setSigners(Class<?> c, Object[] signers) {
  1102         c.setSigners(signers);
  1103     }
  1104 
  1105 
  1106     // -- Resource --
  1107 
  1108     /**
  1109      * Finds the resource with the given name.  A resource is some data
  1110      * (images, audio, text, etc) that can be accessed by class code in a way
  1111      * that is independent of the location of the code.
  1112      *
  1113      * <p> The name of a resource is a '<tt>/</tt>'-separated path name that
  1114      * identifies the resource.
  1115      *
  1116      * <p> This method will first search the parent class loader for the
  1117      * resource; if the parent is <tt>null</tt> the path of the class loader
  1118      * built-in to the virtual machine is searched.  That failing, this method
  1119      * will invoke {@link #findResource(String)} to find the resource.  </p>
  1120      *
  1121      * @param  name
  1122      *         The resource name
  1123      *
  1124      * @return  A <tt>URL</tt> object for reading the resource, or
  1125      *          <tt>null</tt> if the resource could not be found or the invoker
  1126      *          doesn't have adequate  privileges to get the resource.
  1127      *
  1128      * @since  1.1
  1129      */
  1130     public URL getResource(String name) {
  1131         URL url;
  1132         if (parent != null) {
  1133             url = parent.getResource(name);
  1134         } else {
  1135             url = getBootstrapResource(name);
  1136         }
  1137         if (url == null) {
  1138             url = findResource(name);
  1139         }
  1140         return url;
  1141     }
  1142 
  1143     /**
  1144      * Finds all the resources with the given name. A resource is some data
  1145      * (images, audio, text, etc) that can be accessed by class code in a way
  1146      * that is independent of the location of the code.
  1147      *
  1148      * <p>The name of a resource is a <tt>/</tt>-separated path name that
  1149      * identifies the resource.
  1150      *
  1151      * <p> The search order is described in the documentation for {@link
  1152      * #getResource(String)}.  </p>
  1153      *
  1154      * @param  name
  1155      *         The resource name
  1156      *
  1157      * @return  An enumeration of {@link java.net.URL <tt>URL</tt>} objects for
  1158      *          the resource.  If no resources could  be found, the enumeration
  1159      *          will be empty.  Resources that the class loader doesn't have
  1160      *          access to will not be in the enumeration.
  1161      *
  1162      * @throws  IOException
  1163      *          If I/O errors occur
  1164      *
  1165      * @see  #findResources(String)
  1166      *
  1167      * @since  1.2
  1168      */
  1169     public Enumeration<URL> getResources(String name) throws IOException {
  1170         Enumeration[] tmp = new Enumeration[2];
  1171         if (parent != null) {
  1172             tmp[0] = parent.getResources(name);
  1173         } else {
  1174             tmp[0] = getBootstrapResources(name);
  1175         }
  1176         tmp[1] = findResources(name);
  1177 
  1178         return new CompoundEnumeration<>(tmp);
  1179     }
  1180 
  1181     /**
  1182      * Finds the resource with the given name. Class loader implementations
  1183      * should override this method to specify where to find resources.  </p>
  1184      *
  1185      * @param  name
  1186      *         The resource name
  1187      *
  1188      * @return  A <tt>URL</tt> object for reading the resource, or
  1189      *          <tt>null</tt> if the resource could not be found
  1190      *
  1191      * @since  1.2
  1192      */
  1193     protected URL findResource(String name) {
  1194         return null;
  1195     }
  1196 
  1197     /**
  1198      * Returns an enumeration of {@link java.net.URL <tt>URL</tt>} objects
  1199      * representing all the resources with the given name. Class loader
  1200      * implementations should override this method to specify where to load
  1201      * resources from.  </p>
  1202      *
  1203      * @param  name
  1204      *         The resource name
  1205      *
  1206      * @return  An enumeration of {@link java.net.URL <tt>URL</tt>} objects for
  1207      *          the resources
  1208      *
  1209      * @throws  IOException
  1210      *          If I/O errors occur
  1211      *
  1212      * @since  1.2
  1213      */
  1214     protected Enumeration<URL> findResources(String name) throws IOException {
  1215         return java.util.Collections.emptyEnumeration();
  1216     }
  1217 
  1218     // index 0: java.lang.ClassLoader.class
  1219     // index 1: the immediate caller of index 0.
  1220     // index 2: the immediate caller of index 1.
  1221     private static native Class<? extends ClassLoader> getCaller(int index);
  1222 
  1223     /**
  1224      * Registers the caller as parallel capable.</p>
  1225      * The registration succeeds if and only if all of the following
  1226      * conditions are met: <br>
  1227      * 1. no instance of the caller has been created</p>
  1228      * 2. all of the super classes (except class Object) of the caller are
  1229      * registered as parallel capable</p>
  1230      * Note that once a class loader is registered as parallel capable, there
  1231      * is no way to change it back. </p>
  1232      *
  1233      * @return  true if the caller is successfully registered as
  1234      *          parallel capable and false if otherwise.
  1235      *
  1236      * @since   1.7
  1237      */
  1238     protected static boolean registerAsParallelCapable() {
  1239         return ParallelLoaders.register(getCaller(1));
  1240     }
  1241 
  1242     /**
  1243      * Find a resource of the specified name from the search path used to load
  1244      * classes.  This method locates the resource through the system class
  1245      * loader (see {@link #getSystemClassLoader()}).  </p>
  1246      *
  1247      * @param  name
  1248      *         The resource name
  1249      *
  1250      * @return  A {@link java.net.URL <tt>URL</tt>} object for reading the
  1251      *          resource, or <tt>null</tt> if the resource could not be found
  1252      *
  1253      * @since  1.1
  1254      */
  1255     public static URL getSystemResource(String name) {
  1256         ClassLoader system = getSystemClassLoader();
  1257         if (system == null) {
  1258             return getBootstrapResource(name);
  1259         }
  1260         return system.getResource(name);
  1261     }
  1262 
  1263     /**
  1264      * Finds all resources of the specified name from the search path used to
  1265      * load classes.  The resources thus found are returned as an
  1266      * {@link java.util.Enumeration <tt>Enumeration</tt>} of {@link
  1267      * java.net.URL <tt>URL</tt>} objects.
  1268      *
  1269      * <p> The search order is described in the documentation for {@link
  1270      * #getSystemResource(String)}.  </p>
  1271      *
  1272      * @param  name
  1273      *         The resource name
  1274      *
  1275      * @return  An enumeration of resource {@link java.net.URL <tt>URL</tt>}
  1276      *          objects
  1277      *
  1278      * @throws  IOException
  1279      *          If I/O errors occur
  1280 
  1281      * @since  1.2
  1282      */
  1283     public static Enumeration<URL> getSystemResources(String name)
  1284         throws IOException
  1285     {
  1286         ClassLoader system = getSystemClassLoader();
  1287         if (system == null) {
  1288             return getBootstrapResources(name);
  1289         }
  1290         return system.getResources(name);
  1291     }
  1292 
  1293     /**
  1294      * Find resources from the VM's built-in classloader.
  1295      */
  1296     private static URL getBootstrapResource(String name) {
  1297         URLClassPath ucp = getBootstrapClassPath();
  1298         Resource res = ucp.getResource(name);
  1299         return res != null ? res.getURL() : null;
  1300     }
  1301 
  1302     /**
  1303      * Find resources from the VM's built-in classloader.
  1304      */
  1305     private static Enumeration<URL> getBootstrapResources(String name)
  1306         throws IOException
  1307     {
  1308         final Enumeration<Resource> e =
  1309             getBootstrapClassPath().getResources(name);
  1310         return new Enumeration<URL> () {
  1311             public URL nextElement() {
  1312                 return e.nextElement().getURL();
  1313             }
  1314             public boolean hasMoreElements() {
  1315                 return e.hasMoreElements();
  1316             }
  1317         };
  1318     }
  1319 
  1320     // Returns the URLClassPath that is used for finding system resources.
  1321     static URLClassPath getBootstrapClassPath() {
  1322         return sun.misc.Launcher.getBootstrapClassPath();
  1323     }
  1324 
  1325 
  1326     /**
  1327      * Returns an input stream for reading the specified resource.
  1328      *
  1329      * <p> The search order is described in the documentation for {@link
  1330      * #getResource(String)}.  </p>
  1331      *
  1332      * @param  name
  1333      *         The resource name
  1334      *
  1335      * @return  An input stream for reading the resource, or <tt>null</tt>
  1336      *          if the resource could not be found
  1337      *
  1338      * @since  1.1
  1339      */
  1340     public InputStream getResourceAsStream(String name) {
  1341         URL url = getResource(name);
  1342         try {
  1343             return url != null ? url.openStream() : null;
  1344         } catch (IOException e) {
  1345             return null;
  1346         }
  1347     }
  1348 
  1349     /**
  1350      * Open for reading, a resource of the specified name from the search path
  1351      * used to load classes.  This method locates the resource through the
  1352      * system class loader (see {@link #getSystemClassLoader()}).  </p>
  1353      *
  1354      * @param  name
  1355      *         The resource name
  1356      *
  1357      * @return  An input stream for reading the resource, or <tt>null</tt>
  1358      *          if the resource could not be found
  1359      *
  1360      * @since  1.1
  1361      */
  1362     public static InputStream getSystemResourceAsStream(String name) {
  1363         URL url = getSystemResource(name);
  1364         try {
  1365             return url != null ? url.openStream() : null;
  1366         } catch (IOException e) {
  1367             return null;
  1368         }
  1369     }
  1370 
  1371 
  1372     // -- Hierarchy --
  1373 
  1374     /**
  1375      * Returns the parent class loader for delegation. Some implementations may
  1376      * use <tt>null</tt> to represent the bootstrap class loader. This method
  1377      * will return <tt>null</tt> in such implementations if this class loader's
  1378      * parent is the bootstrap class loader.
  1379      *
  1380      * <p> If a security manager is present, and the invoker's class loader is
  1381      * not <tt>null</tt> and is not an ancestor of this class loader, then this
  1382      * method invokes the security manager's {@link
  1383      * SecurityManager#checkPermission(java.security.Permission)
  1384      * <tt>checkPermission</tt>} method with a {@link
  1385      * RuntimePermission#RuntimePermission(String)
  1386      * <tt>RuntimePermission("getClassLoader")</tt>} permission to verify
  1387      * access to the parent class loader is permitted.  If not, a
  1388      * <tt>SecurityException</tt> will be thrown.  </p>
  1389      *
  1390      * @return  The parent <tt>ClassLoader</tt>
  1391      *
  1392      * @throws  SecurityException
  1393      *          If a security manager exists and its <tt>checkPermission</tt>
  1394      *          method doesn't allow access to this class loader's parent class
  1395      *          loader.
  1396      *
  1397      * @since  1.2
  1398      */
  1399     public final ClassLoader getParent() {
  1400         if (parent == null)
  1401             return null;
  1402         SecurityManager sm = System.getSecurityManager();
  1403         if (sm != null) {
  1404             ClassLoader ccl = getCallerClassLoader();
  1405             if (ccl != null && !isAncestor(ccl)) {
  1406                 sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
  1407             }
  1408         }
  1409         return parent;
  1410     }
  1411 
  1412     /**
  1413      * Returns the system class loader for delegation.  This is the default
  1414      * delegation parent for new <tt>ClassLoader</tt> instances, and is
  1415      * typically the class loader used to start the application.
  1416      *
  1417      * <p> This method is first invoked early in the runtime's startup
  1418      * sequence, at which point it creates the system class loader and sets it
  1419      * as the context class loader of the invoking <tt>Thread</tt>.
  1420      *
  1421      * <p> The default system class loader is an implementation-dependent
  1422      * instance of this class.
  1423      *
  1424      * <p> If the system property "<tt>java.system.class.loader</tt>" is defined
  1425      * when this method is first invoked then the value of that property is
  1426      * taken to be the name of a class that will be returned as the system
  1427      * class loader.  The class is loaded using the default system class loader
  1428      * and must define a public constructor that takes a single parameter of
  1429      * type <tt>ClassLoader</tt> which is used as the delegation parent.  An
  1430      * instance is then created using this constructor with the default system
  1431      * class loader as the parameter.  The resulting class loader is defined
  1432      * to be the system class loader.
  1433      *
  1434      * <p> If a security manager is present, and the invoker's class loader is
  1435      * not <tt>null</tt> and the invoker's class loader is not the same as or
  1436      * an ancestor of the system class loader, then this method invokes the
  1437      * security manager's {@link
  1438      * SecurityManager#checkPermission(java.security.Permission)
  1439      * <tt>checkPermission</tt>} method with a {@link
  1440      * RuntimePermission#RuntimePermission(String)
  1441      * <tt>RuntimePermission("getClassLoader")</tt>} permission to verify
  1442      * access to the system class loader.  If not, a
  1443      * <tt>SecurityException</tt> will be thrown.  </p>
  1444      *
  1445      * @return  The system <tt>ClassLoader</tt> for delegation, or
  1446      *          <tt>null</tt> if none
  1447      *
  1448      * @throws  SecurityException
  1449      *          If a security manager exists and its <tt>checkPermission</tt>
  1450      *          method doesn't allow access to the system class loader.
  1451      *
  1452      * @throws  IllegalStateException
  1453      *          If invoked recursively during the construction of the class
  1454      *          loader specified by the "<tt>java.system.class.loader</tt>"
  1455      *          property.
  1456      *
  1457      * @throws  Error
  1458      *          If the system property "<tt>java.system.class.loader</tt>"
  1459      *          is defined but the named class could not be loaded, the
  1460      *          provider class does not define the required constructor, or an
  1461      *          exception is thrown by that constructor when it is invoked. The
  1462      *          underlying cause of the error can be retrieved via the
  1463      *          {@link Throwable#getCause()} method.
  1464      *
  1465      * @revised  1.4
  1466      */
  1467     public static ClassLoader getSystemClassLoader() {
  1468         initSystemClassLoader();
  1469         if (scl == null) {
  1470             return null;
  1471         }
  1472         SecurityManager sm = System.getSecurityManager();
  1473         if (sm != null) {
  1474             ClassLoader ccl = getCallerClassLoader();
  1475             if (ccl != null && ccl != scl && !scl.isAncestor(ccl)) {
  1476                 sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
  1477             }
  1478         }
  1479         return scl;
  1480     }
  1481 
  1482     private static synchronized void initSystemClassLoader() {
  1483         if (!sclSet) {
  1484             if (scl != null)
  1485                 throw new IllegalStateException("recursive invocation");
  1486             sun.misc.Launcher l = sun.misc.Launcher.getLauncher();
  1487             if (l != null) {
  1488                 Throwable oops = null;
  1489                 scl = l.getClassLoader();
  1490                 try {
  1491                     scl = AccessController.doPrivileged(
  1492                         new SystemClassLoaderAction(scl));
  1493                 } catch (PrivilegedActionException pae) {
  1494                     oops = pae.getCause();
  1495                     if (oops instanceof InvocationTargetException) {
  1496                         oops = oops.getCause();
  1497                     }
  1498                 }
  1499                 if (oops != null) {
  1500                     if (oops instanceof Error) {
  1501                         throw (Error) oops;
  1502                     } else {
  1503                         // wrap the exception
  1504                         throw new Error(oops);
  1505                     }
  1506                 }
  1507             }
  1508             sclSet = true;
  1509         }
  1510     }
  1511 
  1512     // Returns true if the specified class loader can be found in this class
  1513     // loader's delegation chain.
  1514     boolean isAncestor(ClassLoader cl) {
  1515         ClassLoader acl = this;
  1516         do {
  1517             acl = acl.parent;
  1518             if (cl == acl) {
  1519                 return true;
  1520             }
  1521         } while (acl != null);
  1522         return false;
  1523     }
  1524 
  1525     // Returns the invoker's class loader, or null if none.
  1526     // NOTE: This must always be invoked when there is exactly one intervening
  1527     // frame from the core libraries on the stack between this method's
  1528     // invocation and the desired invoker.
  1529     static ClassLoader getCallerClassLoader() {
  1530         // NOTE use of more generic Reflection.getCallerClass()
  1531         Class caller = Reflection.getCallerClass(3);
  1532         // This can be null if the VM is requesting it
  1533         if (caller == null) {
  1534             return null;
  1535         }
  1536         // Circumvent security check since this is package-private
  1537         return caller.getClassLoader0();
  1538     }
  1539 
  1540     // The class loader for the system
  1541     // @GuardedBy("ClassLoader.class")
  1542     private static ClassLoader scl;
  1543 
  1544     // Set to true once the system class loader has been set
  1545     // @GuardedBy("ClassLoader.class")
  1546     private static boolean sclSet;
  1547 
  1548 
  1549     // -- Package --
  1550 
  1551     /**
  1552      * Defines a package by name in this <tt>ClassLoader</tt>.  This allows
  1553      * class loaders to define the packages for their classes. Packages must
  1554      * be created before the class is defined, and package names must be
  1555      * unique within a class loader and cannot be redefined or changed once
  1556      * created.  </p>
  1557      *
  1558      * @param  name
  1559      *         The package name
  1560      *
  1561      * @param  specTitle
  1562      *         The specification title
  1563      *
  1564      * @param  specVersion
  1565      *         The specification version
  1566      *
  1567      * @param  specVendor
  1568      *         The specification vendor
  1569      *
  1570      * @param  implTitle
  1571      *         The implementation title
  1572      *
  1573      * @param  implVersion
  1574      *         The implementation version
  1575      *
  1576      * @param  implVendor
  1577      *         The implementation vendor
  1578      *
  1579      * @param  sealBase
  1580      *         If not <tt>null</tt>, then this package is sealed with
  1581      *         respect to the given code source {@link java.net.URL
  1582      *         <tt>URL</tt>}  object.  Otherwise, the package is not sealed.
  1583      *
  1584      * @return  The newly defined <tt>Package</tt> object
  1585      *
  1586      * @throws  IllegalArgumentException
  1587      *          If package name duplicates an existing package either in this
  1588      *          class loader or one of its ancestors
  1589      *
  1590      * @since  1.2
  1591      */
  1592     protected Package definePackage(String name, String specTitle,
  1593                                     String specVersion, String specVendor,
  1594                                     String implTitle, String implVersion,
  1595                                     String implVendor, URL sealBase)
  1596         throws IllegalArgumentException
  1597     {
  1598         synchronized (packages) {
  1599             Package pkg = getPackage(name);
  1600             if (pkg != null) {
  1601                 throw new IllegalArgumentException(name);
  1602             }
  1603             pkg = new Package(name, specTitle, specVersion, specVendor,
  1604                               implTitle, implVersion, implVendor,
  1605                               sealBase, this);
  1606             packages.put(name, pkg);
  1607             return pkg;
  1608         }
  1609     }
  1610 
  1611     /**
  1612      * Returns a <tt>Package</tt> that has been defined by this class loader
  1613      * or any of its ancestors.  </p>
  1614      *
  1615      * @param  name
  1616      *         The package name
  1617      *
  1618      * @return  The <tt>Package</tt> corresponding to the given name, or
  1619      *          <tt>null</tt> if not found
  1620      *
  1621      * @since  1.2
  1622      */
  1623     protected Package getPackage(String name) {
  1624         Package pkg;
  1625         synchronized (packages) {
  1626             pkg = packages.get(name);
  1627         }
  1628         if (pkg == null) {
  1629             if (parent != null) {
  1630                 pkg = parent.getPackage(name);
  1631             } else {
  1632                 pkg = Package.getSystemPackage(name);
  1633             }
  1634             if (pkg != null) {
  1635                 synchronized (packages) {
  1636                     Package pkg2 = packages.get(name);
  1637                     if (pkg2 == null) {
  1638                         packages.put(name, pkg);
  1639                     } else {
  1640                         pkg = pkg2;
  1641                     }
  1642                 }
  1643             }
  1644         }
  1645         return pkg;
  1646     }
  1647 
  1648     /**
  1649      * Returns all of the <tt>Packages</tt> defined by this class loader and
  1650      * its ancestors.  </p>
  1651      *
  1652      * @return  The array of <tt>Package</tt> objects defined by this
  1653      *          <tt>ClassLoader</tt>
  1654      *
  1655      * @since  1.2
  1656      */
  1657     protected Package[] getPackages() {
  1658         Map<String, Package> map;
  1659         synchronized (packages) {
  1660             map = new HashMap<>(packages);
  1661         }
  1662         Package[] pkgs;
  1663         if (parent != null) {
  1664             pkgs = parent.getPackages();
  1665         } else {
  1666             pkgs = Package.getSystemPackages();
  1667         }
  1668         if (pkgs != null) {
  1669             for (int i = 0; i < pkgs.length; i++) {
  1670                 String pkgName = pkgs[i].getName();
  1671                 if (map.get(pkgName) == null) {
  1672                     map.put(pkgName, pkgs[i]);
  1673                 }
  1674             }
  1675         }
  1676         return map.values().toArray(new Package[map.size()]);
  1677     }
  1678 
  1679 
  1680     // -- Native library access --
  1681 
  1682     /**
  1683      * Returns the absolute path name of a native library.  The VM invokes this
  1684      * method to locate the native libraries that belong to classes loaded with
  1685      * this class loader. If this method returns <tt>null</tt>, the VM
  1686      * searches the library along the path specified as the
  1687      * "<tt>java.library.path</tt>" property.  </p>
  1688      *
  1689      * @param  libname
  1690      *         The library name
  1691      *
  1692      * @return  The absolute path of the native library
  1693      *
  1694      * @see  System#loadLibrary(String)
  1695      * @see  System#mapLibraryName(String)
  1696      *
  1697      * @since  1.2
  1698      */
  1699     protected String findLibrary(String libname) {
  1700         return null;
  1701     }
  1702 
  1703     /**
  1704      * The inner class NativeLibrary denotes a loaded native library instance.
  1705      * Every classloader contains a vector of loaded native libraries in the
  1706      * private field <tt>nativeLibraries</tt>.  The native libraries loaded
  1707      * into the system are entered into the <tt>systemNativeLibraries</tt>
  1708      * vector.
  1709      *
  1710      * <p> Every native library requires a particular version of JNI. This is
  1711      * denoted by the private <tt>jniVersion</tt> field.  This field is set by
  1712      * the VM when it loads the library, and used by the VM to pass the correct
  1713      * version of JNI to the native methods.  </p>
  1714      *
  1715      * @see      ClassLoader
  1716      * @since    1.2
  1717      */
  1718     static class NativeLibrary {
  1719         // opaque handle to native library, used in native code.
  1720         long handle;
  1721         // the version of JNI environment the native library requires.
  1722         private int jniVersion;
  1723         // the class from which the library is loaded, also indicates
  1724         // the loader this native library belongs.
  1725         private Class fromClass;
  1726         // the canonicalized name of the native library.
  1727         String name;
  1728 
  1729         native void load(String name);
  1730         native long find(String name);
  1731         native void unload();
  1732 
  1733         public NativeLibrary(Class fromClass, String name) {
  1734             this.name = name;
  1735             this.fromClass = fromClass;
  1736         }
  1737 
  1738         protected void finalize() {
  1739             synchronized (loadedLibraryNames) {
  1740                 if (fromClass.getClassLoader() != null && handle != 0) {
  1741                     /* remove the native library name */
  1742                     int size = loadedLibraryNames.size();
  1743                     for (int i = 0; i < size; i++) {
  1744                         if (name.equals(loadedLibraryNames.elementAt(i))) {
  1745                             loadedLibraryNames.removeElementAt(i);
  1746                             break;
  1747                         }
  1748                     }
  1749                     /* unload the library. */
  1750                     ClassLoader.nativeLibraryContext.push(this);
  1751                     try {
  1752                         unload();
  1753                     } finally {
  1754                         ClassLoader.nativeLibraryContext.pop();
  1755                     }
  1756                 }
  1757             }
  1758         }
  1759         // Invoked in the VM to determine the context class in
  1760         // JNI_Load/JNI_Unload
  1761         static Class getFromClass() {
  1762             return ClassLoader.nativeLibraryContext.peek().fromClass;
  1763         }
  1764     }
  1765 
  1766     // All native library names we've loaded.
  1767     private static Vector<String> loadedLibraryNames = new Vector<>();
  1768 
  1769     // Native libraries belonging to system classes.
  1770     private static Vector<NativeLibrary> systemNativeLibraries
  1771         = new Vector<>();
  1772 
  1773     // Native libraries associated with the class loader.
  1774     private Vector<NativeLibrary> nativeLibraries = new Vector<>();
  1775 
  1776     // native libraries being loaded/unloaded.
  1777     private static Stack<NativeLibrary> nativeLibraryContext = new Stack<>();
  1778 
  1779     // The paths searched for libraries
  1780     private static String usr_paths[];
  1781     private static String sys_paths[];
  1782 
  1783     private static String[] initializePath(String propname) {
  1784         String ldpath = System.getProperty(propname, "");
  1785         String ps = File.pathSeparator;
  1786         int ldlen = ldpath.length();
  1787         int i, j, n;
  1788         // Count the separators in the path
  1789         i = ldpath.indexOf(ps);
  1790         n = 0;
  1791         while (i >= 0) {
  1792             n++;
  1793             i = ldpath.indexOf(ps, i + 1);
  1794         }
  1795 
  1796         // allocate the array of paths - n :'s = n + 1 path elements
  1797         String[] paths = new String[n + 1];
  1798 
  1799         // Fill the array with paths from the ldpath
  1800         n = i = 0;
  1801         j = ldpath.indexOf(ps);
  1802         while (j >= 0) {
  1803             if (j - i > 0) {
  1804                 paths[n++] = ldpath.substring(i, j);
  1805             } else if (j - i == 0) {
  1806                 paths[n++] = ".";
  1807             }
  1808             i = j + 1;
  1809             j = ldpath.indexOf(ps, i);
  1810         }
  1811         paths[n] = ldpath.substring(i, ldlen);
  1812         return paths;
  1813     }
  1814 
  1815     // Invoked in the java.lang.Runtime class to implement load and loadLibrary.
  1816     static void loadLibrary(Class fromClass, String name,
  1817                             boolean isAbsolute) {
  1818         ClassLoader loader =
  1819             (fromClass == null) ? null : fromClass.getClassLoader();
  1820         if (sys_paths == null) {
  1821             usr_paths = initializePath("java.library.path");
  1822             sys_paths = initializePath("sun.boot.library.path");
  1823         }
  1824         if (isAbsolute) {
  1825             if (loadLibrary0(fromClass, new File(name))) {
  1826                 return;
  1827             }
  1828             throw new UnsatisfiedLinkError("Can't load library: " + name);
  1829         }
  1830         if (loader != null) {
  1831             String libfilename = loader.findLibrary(name);
  1832             if (libfilename != null) {
  1833                 File libfile = new File(libfilename);
  1834                 if (!libfile.isAbsolute()) {
  1835                     throw new UnsatisfiedLinkError(
  1836     "ClassLoader.findLibrary failed to return an absolute path: " + libfilename);
  1837                 }
  1838                 if (loadLibrary0(fromClass, libfile)) {
  1839                     return;
  1840                 }
  1841                 throw new UnsatisfiedLinkError("Can't load " + libfilename);
  1842             }
  1843         }
  1844         for (int i = 0 ; i < sys_paths.length ; i++) {
  1845             File libfile = new File(sys_paths[i], System.mapLibraryName(name));
  1846             if (loadLibrary0(fromClass, libfile)) {
  1847                 return;
  1848             }
  1849         }
  1850         if (loader != null) {
  1851             for (int i = 0 ; i < usr_paths.length ; i++) {
  1852                 File libfile = new File(usr_paths[i],
  1853                                         System.mapLibraryName(name));
  1854                 if (loadLibrary0(fromClass, libfile)) {
  1855                     return;
  1856                 }
  1857             }
  1858         }
  1859         // Oops, it failed
  1860         throw new UnsatisfiedLinkError("no " + name + " in java.library.path");
  1861     }
  1862 
  1863     private static boolean loadLibrary0(Class fromClass, final File file) {
  1864         boolean exists = AccessController.doPrivileged(
  1865             new PrivilegedAction<Object>() {
  1866                 public Object run() {
  1867                     return file.exists() ? Boolean.TRUE : null;
  1868                 }})
  1869             != null;
  1870         if (!exists) {
  1871             return false;
  1872         }
  1873         String name;
  1874         try {
  1875             name = file.getCanonicalPath();
  1876         } catch (IOException e) {
  1877             return false;
  1878         }
  1879         ClassLoader loader =
  1880             (fromClass == null) ? null : fromClass.getClassLoader();
  1881         Vector<NativeLibrary> libs =
  1882             loader != null ? loader.nativeLibraries : systemNativeLibraries;
  1883         synchronized (libs) {
  1884             int size = libs.size();
  1885             for (int i = 0; i < size; i++) {
  1886                 NativeLibrary lib = libs.elementAt(i);
  1887                 if (name.equals(lib.name)) {
  1888                     return true;
  1889                 }
  1890             }
  1891 
  1892             synchronized (loadedLibraryNames) {
  1893                 if (loadedLibraryNames.contains(name)) {
  1894                     throw new UnsatisfiedLinkError
  1895                         ("Native Library " +
  1896                          name +
  1897                          " already loaded in another classloader");
  1898                 }
  1899                 /* If the library is being loaded (must be by the same thread,
  1900                  * because Runtime.load and Runtime.loadLibrary are
  1901                  * synchronous). The reason is can occur is that the JNI_OnLoad
  1902                  * function can cause another loadLibrary invocation.
  1903                  *
  1904                  * Thus we can use a static stack to hold the list of libraries
  1905                  * we are loading.
  1906                  *
  1907                  * If there is a pending load operation for the library, we
  1908                  * immediately return success; otherwise, we raise
  1909                  * UnsatisfiedLinkError.
  1910                  */
  1911                 int n = nativeLibraryContext.size();
  1912                 for (int i = 0; i < n; i++) {
  1913                     NativeLibrary lib = nativeLibraryContext.elementAt(i);
  1914                     if (name.equals(lib.name)) {
  1915                         if (loader == lib.fromClass.getClassLoader()) {
  1916                             return true;
  1917                         } else {
  1918                             throw new UnsatisfiedLinkError
  1919                                 ("Native Library " +
  1920                                  name +
  1921                                  " is being loaded in another classloader");
  1922                         }
  1923                     }
  1924                 }
  1925                 NativeLibrary lib = new NativeLibrary(fromClass, name);
  1926                 nativeLibraryContext.push(lib);
  1927                 try {
  1928                     lib.load(name);
  1929                 } finally {
  1930                     nativeLibraryContext.pop();
  1931                 }
  1932                 if (lib.handle != 0) {
  1933                     loadedLibraryNames.addElement(name);
  1934                     libs.addElement(lib);
  1935                     return true;
  1936                 }
  1937                 return false;
  1938             }
  1939         }
  1940     }
  1941 
  1942     // Invoked in the VM class linking code.
  1943     static long findNative(ClassLoader loader, String name) {
  1944         Vector<NativeLibrary> libs =
  1945             loader != null ? loader.nativeLibraries : systemNativeLibraries;
  1946         synchronized (libs) {
  1947             int size = libs.size();
  1948             for (int i = 0; i < size; i++) {
  1949                 NativeLibrary lib = libs.elementAt(i);
  1950                 long entry = lib.find(name);
  1951                 if (entry != 0)
  1952                     return entry;
  1953             }
  1954         }
  1955         return 0;
  1956     }
  1957 
  1958 
  1959     // -- Assertion management --
  1960 
  1961     final Object assertionLock;
  1962 
  1963     // The default toggle for assertion checking.
  1964     // @GuardedBy("assertionLock")
  1965     private boolean defaultAssertionStatus = false;
  1966 
  1967     // Maps String packageName to Boolean package default assertion status Note
  1968     // that the default package is placed under a null map key.  If this field
  1969     // is null then we are delegating assertion status queries to the VM, i.e.,
  1970     // none of this ClassLoader's assertion status modification methods have
  1971     // been invoked.
  1972     // @GuardedBy("assertionLock")
  1973     private Map<String, Boolean> packageAssertionStatus = null;
  1974 
  1975     // Maps String fullyQualifiedClassName to Boolean assertionStatus If this
  1976     // field is null then we are delegating assertion status queries to the VM,
  1977     // i.e., none of this ClassLoader's assertion status modification methods
  1978     // have been invoked.
  1979     // @GuardedBy("assertionLock")
  1980     Map<String, Boolean> classAssertionStatus = null;
  1981 
  1982     /**
  1983      * Sets the default assertion status for this class loader.  This setting
  1984      * determines whether classes loaded by this class loader and initialized
  1985      * in the future will have assertions enabled or disabled by default.
  1986      * This setting may be overridden on a per-package or per-class basis by
  1987      * invoking {@link #setPackageAssertionStatus(String, boolean)} or {@link
  1988      * #setClassAssertionStatus(String, boolean)}.  </p>
  1989      *
  1990      * @param  enabled
  1991      *         <tt>true</tt> if classes loaded by this class loader will
  1992      *         henceforth have assertions enabled by default, <tt>false</tt>
  1993      *         if they will have assertions disabled by default.
  1994      *
  1995      * @since  1.4
  1996      */
  1997     public void setDefaultAssertionStatus(boolean enabled) {
  1998         synchronized (assertionLock) {
  1999             if (classAssertionStatus == null)
  2000                 initializeJavaAssertionMaps();
  2001 
  2002             defaultAssertionStatus = enabled;
  2003         }
  2004     }
  2005 
  2006     /**
  2007      * Sets the package default assertion status for the named package.  The
  2008      * package default assertion status determines the assertion status for
  2009      * classes initialized in the future that belong to the named package or
  2010      * any of its "subpackages".
  2011      *
  2012      * <p> A subpackage of a package named p is any package whose name begins
  2013      * with "<tt>p.</tt>".  For example, <tt>javax.swing.text</tt> is a
  2014      * subpackage of <tt>javax.swing</tt>, and both <tt>java.util</tt> and
  2015      * <tt>java.lang.reflect</tt> are subpackages of <tt>java</tt>.
  2016      *
  2017      * <p> In the event that multiple package defaults apply to a given class,
  2018      * the package default pertaining to the most specific package takes
  2019      * precedence over the others.  For example, if <tt>javax.lang</tt> and
  2020      * <tt>javax.lang.reflect</tt> both have package defaults associated with
  2021      * them, the latter package default applies to classes in
  2022      * <tt>javax.lang.reflect</tt>.
  2023      *
  2024      * <p> Package defaults take precedence over the class loader's default
  2025      * assertion status, and may be overridden on a per-class basis by invoking
  2026      * {@link #setClassAssertionStatus(String, boolean)}.  </p>
  2027      *
  2028      * @param  packageName
  2029      *         The name of the package whose package default assertion status
  2030      *         is to be set. A <tt>null</tt> value indicates the unnamed
  2031      *         package that is "current"
  2032      *         (see section 7.4.2 of
  2033      *         <cite>The Java&trade; Language Specification</cite>.)
  2034      *
  2035      * @param  enabled
  2036      *         <tt>true</tt> if classes loaded by this classloader and
  2037      *         belonging to the named package or any of its subpackages will
  2038      *         have assertions enabled by default, <tt>false</tt> if they will
  2039      *         have assertions disabled by default.
  2040      *
  2041      * @since  1.4
  2042      */
  2043     public void setPackageAssertionStatus(String packageName,
  2044                                           boolean enabled) {
  2045         synchronized (assertionLock) {
  2046             if (packageAssertionStatus == null)
  2047                 initializeJavaAssertionMaps();
  2048 
  2049             packageAssertionStatus.put(packageName, enabled);
  2050         }
  2051     }
  2052 
  2053     /**
  2054      * Sets the desired assertion status for the named top-level class in this
  2055      * class loader and any nested classes contained therein.  This setting
  2056      * takes precedence over the class loader's default assertion status, and
  2057      * over any applicable per-package default.  This method has no effect if
  2058      * the named class has already been initialized.  (Once a class is
  2059      * initialized, its assertion status cannot change.)
  2060      *
  2061      * <p> If the named class is not a top-level class, this invocation will
  2062      * have no effect on the actual assertion status of any class. </p>
  2063      *
  2064      * @param  className
  2065      *         The fully qualified class name of the top-level class whose
  2066      *         assertion status is to be set.
  2067      *
  2068      * @param  enabled
  2069      *         <tt>true</tt> if the named class is to have assertions
  2070      *         enabled when (and if) it is initialized, <tt>false</tt> if the
  2071      *         class is to have assertions disabled.
  2072      *
  2073      * @since  1.4
  2074      */
  2075     public void setClassAssertionStatus(String className, boolean enabled) {
  2076         synchronized (assertionLock) {
  2077             if (classAssertionStatus == null)
  2078                 initializeJavaAssertionMaps();
  2079 
  2080             classAssertionStatus.put(className, enabled);
  2081         }
  2082     }
  2083 
  2084     /**
  2085      * Sets the default assertion status for this class loader to
  2086      * <tt>false</tt> and discards any package defaults or class assertion
  2087      * status settings associated with the class loader.  This method is
  2088      * provided so that class loaders can be made to ignore any command line or
  2089      * persistent assertion status settings and "start with a clean slate."
  2090      * </p>
  2091      *
  2092      * @since  1.4
  2093      */
  2094     public void clearAssertionStatus() {
  2095         /*
  2096          * Whether or not "Java assertion maps" are initialized, set
  2097          * them to empty maps, effectively ignoring any present settings.
  2098          */
  2099         synchronized (assertionLock) {
  2100             classAssertionStatus = new HashMap<>();
  2101             packageAssertionStatus = new HashMap<>();
  2102             defaultAssertionStatus = false;
  2103         }
  2104     }
  2105 
  2106     /**
  2107      * Returns the assertion status that would be assigned to the specified
  2108      * class if it were to be initialized at the time this method is invoked.
  2109      * If the named class has had its assertion status set, the most recent
  2110      * setting will be returned; otherwise, if any package default assertion
  2111      * status pertains to this class, the most recent setting for the most
  2112      * specific pertinent package default assertion status is returned;
  2113      * otherwise, this class loader's default assertion status is returned.
  2114      * </p>
  2115      *
  2116      * @param  className
  2117      *         The fully qualified class name of the class whose desired
  2118      *         assertion status is being queried.
  2119      *
  2120      * @return  The desired assertion status of the specified class.
  2121      *
  2122      * @see  #setClassAssertionStatus(String, boolean)
  2123      * @see  #setPackageAssertionStatus(String, boolean)
  2124      * @see  #setDefaultAssertionStatus(boolean)
  2125      *
  2126      * @since  1.4
  2127      */
  2128     boolean desiredAssertionStatus(String className) {
  2129         synchronized (assertionLock) {
  2130             // assert classAssertionStatus   != null;
  2131             // assert packageAssertionStatus != null;
  2132 
  2133             // Check for a class entry
  2134             Boolean result = classAssertionStatus.get(className);
  2135             if (result != null)
  2136                 return result.booleanValue();
  2137 
  2138             // Check for most specific package entry
  2139             int dotIndex = className.lastIndexOf(".");
  2140             if (dotIndex < 0) { // default package
  2141                 result = packageAssertionStatus.get(null);
  2142                 if (result != null)
  2143                     return result.booleanValue();
  2144             }
  2145             while(dotIndex > 0) {
  2146                 className = className.substring(0, dotIndex);
  2147                 result = packageAssertionStatus.get(className);
  2148                 if (result != null)
  2149                     return result.booleanValue();
  2150                 dotIndex = className.lastIndexOf(".", dotIndex-1);
  2151             }
  2152 
  2153             // Return the classloader default
  2154             return defaultAssertionStatus;
  2155         }
  2156     }
  2157 
  2158     // Set up the assertions with information provided by the VM.
  2159     // Note: Should only be called inside a synchronized block
  2160     private void initializeJavaAssertionMaps() {
  2161         // assert Thread.holdsLock(assertionLock);
  2162 
  2163         classAssertionStatus = new HashMap<>();
  2164         packageAssertionStatus = new HashMap<>();
  2165         AssertionStatusDirectives directives = retrieveDirectives();
  2166 
  2167         for(int i = 0; i < directives.classes.length; i++)
  2168             classAssertionStatus.put(directives.classes[i],
  2169                                      directives.classEnabled[i]);
  2170 
  2171         for(int i = 0; i < directives.packages.length; i++)
  2172             packageAssertionStatus.put(directives.packages[i],
  2173                                        directives.packageEnabled[i]);
  2174 
  2175         defaultAssertionStatus = directives.deflt;
  2176     }
  2177 
  2178     // Retrieves the assertion directives from the VM.
  2179     private static native AssertionStatusDirectives retrieveDirectives();
  2180 }
  2181 
  2182 
  2183 class SystemClassLoaderAction
  2184     implements PrivilegedExceptionAction<ClassLoader> {
  2185     private ClassLoader parent;
  2186 
  2187     SystemClassLoaderAction(ClassLoader parent) {
  2188         this.parent = parent;
  2189     }
  2190 
  2191     public ClassLoader run() throws Exception {
  2192         String cls = System.getProperty("java.system.class.loader");
  2193         if (cls == null) {
  2194             return parent;
  2195         }
  2196 
  2197         Constructor ctor = Class.forName(cls, true, parent)
  2198             .getDeclaredConstructor(new Class[] { ClassLoader.class });
  2199         ClassLoader sys = (ClassLoader) ctor.newInstance(
  2200             new Object[] { parent });
  2201         Thread.currentThread().setContextClassLoader(sys);
  2202         return sys;
  2203     }
  2204 }