rt/emul/mini/src/main/java/java/lang/ClassLoader.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Tue, 17 Jan 2017 07:04:06 +0100
changeset 1985 cd1cc103a03c
parent 1717 f5200d90b730
permissions -rw-r--r--
Implementation of ClassValue for bck2brwsr
     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.net.URL;
    30 import java.util.Enumeration;
    31 import java.util.NoSuchElementException;
    32 import org.apidesign.bck2brwsr.core.JavaScriptBody;
    33 
    34 /**
    35  * A class loader is an object that is responsible for loading classes. The
    36  * class <tt>ClassLoader</tt> is an abstract class.  Given the <a
    37  * href="#name">binary name</a> of a class, a class loader should attempt to
    38  * locate or generate data that constitutes a definition for the class.  A
    39  * typical strategy is to transform the name into a file name and then read a
    40  * "class file" of that name from a file system.
    41  *
    42  * <p> Every {@link Class <tt>Class</tt>} object contains a {@link
    43  * Class#getClassLoader() reference} to the <tt>ClassLoader</tt> that defined
    44  * it.
    45  *
    46  * <p> <tt>Class</tt> objects for array classes are not created by class
    47  * loaders, but are created automatically as required by the Java runtime.
    48  * The class loader for an array class, as returned by {@link
    49  * Class#getClassLoader()} is the same as the class loader for its element
    50  * type; if the element type is a primitive type, then the array class has no
    51  * class loader.
    52  *
    53  * <p> Applications implement subclasses of <tt>ClassLoader</tt> in order to
    54  * extend the manner in which the Java virtual machine dynamically loads
    55  * classes.
    56  *
    57  * <p> Class loaders may typically be used by security managers to indicate
    58  * security domains.
    59  *
    60  * <p> The <tt>ClassLoader</tt> class uses a delegation model to search for
    61  * classes and resources.  Each instance of <tt>ClassLoader</tt> has an
    62  * associated parent class loader.  When requested to find a class or
    63  * resource, a <tt>ClassLoader</tt> instance will delegate the search for the
    64  * class or resource to its parent class loader before attempting to find the
    65  * class or resource itself.  The virtual machine's built-in class loader,
    66  * called the "bootstrap class loader", does not itself have a parent but may
    67  * serve as the parent of a <tt>ClassLoader</tt> instance.
    68  *
    69  * <p> Class loaders that support concurrent loading of classes are known as
    70  * <em>parallel capable</em> class loaders and are required to register
    71  * themselves at their class initialization time by invoking the
    72  * {@link
    73  * #registerAsParallelCapable <tt>ClassLoader.registerAsParallelCapable</tt>}
    74  * method. Note that the <tt>ClassLoader</tt> class is registered as parallel
    75  * capable by default. However, its subclasses still need to register themselves
    76  * if they are parallel capable. <br>
    77  * In environments in which the delegation model is not strictly
    78  * hierarchical, class loaders need to be parallel capable, otherwise class
    79  * loading can lead to deadlocks because the loader lock is held for the
    80  * duration of the class loading process (see {@link #loadClass
    81  * <tt>loadClass</tt>} methods).
    82  *
    83  * <p> Normally, the Java virtual machine loads classes from the local file
    84  * system in a platform-dependent manner.  For example, on UNIX systems, the
    85  * virtual machine loads classes from the directory defined by the
    86  * <tt>CLASSPATH</tt> environment variable.
    87  *
    88  * <p> However, some classes may not originate from a file; they may originate
    89  * from other sources, such as the network, or they could be constructed by an
    90  * application.  The method {@link #defineClass(String, byte[], int, int)
    91  * <tt>defineClass</tt>} converts an array of bytes into an instance of class
    92  * <tt>Class</tt>. Instances of this newly defined class can be created using
    93  * {@link Class#newInstance <tt>Class.newInstance</tt>}.
    94  *
    95  * <p> The methods and constructors of objects created by a class loader may
    96  * reference other classes.  To determine the class(es) referred to, the Java
    97  * virtual machine invokes the {@link #loadClass <tt>loadClass</tt>} method of
    98  * the class loader that originally created the class.
    99  *
   100  * <p> For example, an application could create a network class loader to
   101  * download class files from a server.  Sample code might look like:
   102  *
   103  * <blockquote><pre>
   104  *   ClassLoader loader&nbsp;= new NetworkClassLoader(host,&nbsp;port);
   105  *   Object main&nbsp;= loader.loadClass("Main", true).newInstance();
   106  *       &nbsp;.&nbsp;.&nbsp;.
   107  * </pre></blockquote>
   108  *
   109  * <p> The network class loader subclass must define the methods {@link
   110  * #findClass <tt>findClass</tt>} and <tt>loadClassData</tt> to load a class
   111  * from the network.  Once it has downloaded the bytes that make up the class,
   112  * it should use the method {@link #defineClass <tt>defineClass</tt>} to
   113  * create a class instance.  A sample implementation is:
   114  *
   115  * <blockquote><pre>
   116  *     class NetworkClassLoader extends ClassLoader {
   117  *         String host;
   118  *         int port;
   119  *
   120  *         public Class findClass(String name) {
   121  *             byte[] b = loadClassData(name);
   122  *             return defineClass(name, b, 0, b.length);
   123  *         }
   124  *
   125  *         private byte[] loadClassData(String name) {
   126  *             // load the class data from the connection
   127  *             &nbsp;.&nbsp;.&nbsp;.
   128  *         }
   129  *     }
   130  * </pre></blockquote>
   131  *
   132  * <h4> <a name="name">Binary names</a> </h4>
   133  *
   134  * <p> Any class name provided as a {@link String} parameter to methods in
   135  * <tt>ClassLoader</tt> must be a binary name as defined by
   136  * <cite>The Java&trade; Language Specification</cite>.
   137  *
   138  * <p> Examples of valid class names include:
   139  * <blockquote><pre>
   140  *   "java.lang.String"
   141  *   "javax.swing.JSpinner$DefaultEditor"
   142  *   "java.security.KeyStore$Builder$FileBuilder$1"
   143  *   "java.net.URLClassLoader$3$1"
   144  * </pre></blockquote>
   145  *
   146  * @see      #resolveClass(Class)
   147  * @since 1.0
   148  */
   149 public abstract class ClassLoader {
   150 
   151     @JavaScriptBody(args = {}, body = "")
   152     private static native void registerNatives();
   153     static {
   154         registerNatives();
   155     }
   156 
   157     // The parent class loader for delegation
   158     // Note: VM hardcoded the offset of this field, thus all new fields
   159     // must be added *after* it.
   160     private final ClassLoader parent;
   161 
   162 
   163     /**
   164      * Creates a new class loader using the specified parent class loader for
   165      * delegation.
   166      *
   167      * <p> If there is a security manager, its {@link
   168      * SecurityManager#checkCreateClassLoader()
   169      * <tt>checkCreateClassLoader</tt>} method is invoked.  This may result in
   170      * a security exception.  </p>
   171      *
   172      * @param  parent
   173      *         The parent class loader
   174      *
   175      * @throws  SecurityException
   176      *          If a security manager exists and its
   177      *          <tt>checkCreateClassLoader</tt> method doesn't allow creation
   178      *          of a new class loader.
   179      *
   180      * @since  1.2
   181      */
   182     protected ClassLoader(ClassLoader parent) {
   183         this.parent = parent;
   184     }
   185 
   186     /**
   187      * Creates a new class loader using the <tt>ClassLoader</tt> returned by
   188      * the method {@link #getSystemClassLoader()
   189      * <tt>getSystemClassLoader()</tt>} as the parent class loader.
   190      *
   191      * <p> If there is a security manager, its {@link
   192      * SecurityManager#checkCreateClassLoader()
   193      * <tt>checkCreateClassLoader</tt>} method is invoked.  This may result in
   194      * a security exception.  </p>
   195      *
   196      * @throws  SecurityException
   197      *          If a security manager exists and its
   198      *          <tt>checkCreateClassLoader</tt> method doesn't allow creation
   199      *          of a new class loader.
   200      */
   201     protected ClassLoader() {
   202         this.parent = null;
   203     }
   204 
   205     // -- Class --
   206 
   207     /**
   208      * Loads the class with the specified <a href="#name">binary name</a>.
   209      * This method searches for classes in the same manner as the {@link
   210      * #loadClass(String, boolean)} method.  It is invoked by the Java virtual
   211      * machine to resolve class references.  Invoking this method is equivalent
   212      * to invoking {@link #loadClass(String, boolean) <tt>loadClass(name,
   213      * false)</tt>}.  </p>
   214      *
   215      * @param  name
   216      *         The <a href="#name">binary name</a> of the class
   217      *
   218      * @return  The resulting <tt>Class</tt> object
   219      *
   220      * @throws  ClassNotFoundException
   221      *          If the class was not found
   222      */
   223     public Class<?> loadClass(String name) throws ClassNotFoundException {
   224         return loadClass(name, false);
   225     }
   226 
   227     /**
   228      * Loads the class with the specified <a href="#name">binary name</a>.  The
   229      * default implementation of this method searches for classes in the
   230      * following order:
   231      *
   232      * <p><ol>
   233      *
   234      *   <li><p> Invoke {@link #findLoadedClass(String)} to check if the class
   235      *   has already been loaded.  </p></li>
   236      *
   237      *   <li><p> Invoke the {@link #loadClass(String) <tt>loadClass</tt>} method
   238      *   on the parent class loader.  If the parent is <tt>null</tt> the class
   239      *   loader built-in to the virtual machine is used, instead.  </p></li>
   240      *
   241      *   <li><p> Invoke the {@link #findClass(String)} method to find the
   242      *   class.  </p></li>
   243      *
   244      * </ol>
   245      *
   246      * <p> If the class was found using the above steps, and the
   247      * <tt>resolve</tt> flag is true, this method will then invoke the {@link
   248      * #resolveClass(Class)} method on the resulting <tt>Class</tt> object.
   249      *
   250      * <p> Subclasses of <tt>ClassLoader</tt> are encouraged to override {@link
   251      * #findClass(String)}, rather than this method.  </p>
   252      *
   253      * <p> Unless overridden, this method synchronizes on the result of
   254      * {@link #getClassLoadingLock <tt>getClassLoadingLock</tt>} method
   255      * during the entire class loading process.
   256      *
   257      * @param  name
   258      *         The <a href="#name">binary name</a> of the class
   259      *
   260      * @param  resolve
   261      *         If <tt>true</tt> then resolve the class
   262      *
   263      * @return  The resulting <tt>Class</tt> object
   264      *
   265      * @throws  ClassNotFoundException
   266      *          If the class could not be found
   267      */
   268     protected Class<?> loadClass(String name, boolean resolve)
   269         throws ClassNotFoundException
   270     {
   271         synchronized (getClassLoadingLock(name)) {
   272             // First, check if the class has already been loaded
   273             Class c = findLoadedClass(name);
   274             if (c == null) {
   275                 try {
   276                     if (parent != null) {
   277                         c = parent.loadClass(name, false);
   278                     } else {
   279                         c = findBootstrapClassOrNull(name);
   280                     }
   281                 } catch (ClassNotFoundException e) {
   282                     // ClassNotFoundException thrown if class not found
   283                     // from the non-null parent class loader
   284                 }
   285 
   286                 if (c == null) {
   287                     // If still not found, then invoke findClass in order
   288                     // to find the class.
   289                     c = findClass(name);
   290 
   291 //                    // this is the defining class loader; record the stats
   292 //                    sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
   293 //                    sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
   294 //                    sun.misc.PerfCounter.getFindClasses().increment();
   295                 }
   296             }
   297             if (resolve) {
   298                 resolveClass(c);
   299             }
   300             return c;
   301         }
   302     }
   303 
   304     /**
   305      * Returns the lock object for class loading operations.
   306      * For backward compatibility, the default implementation of this method
   307      * behaves as follows. If this ClassLoader object is registered as
   308      * parallel capable, the method returns a dedicated object associated
   309      * with the specified class name. Otherwise, the method returns this
   310      * ClassLoader object. </p>
   311      *
   312      * @param  className
   313      *         The name of the to-be-loaded class
   314      *
   315      * @return the lock for class loading operations
   316      *
   317      * @throws NullPointerException
   318      *         If registered as parallel capable and <tt>className</tt> is null
   319      *
   320      * @see #loadClass(String, boolean)
   321      *
   322      * @since  1.7
   323      */
   324     protected Object getClassLoadingLock(String className) {
   325         Object lock = this;
   326         return lock;
   327     }
   328 
   329     /**
   330      * Finds the class with the specified <a href="#name">binary name</a>.
   331      * This method should be overridden by class loader implementations that
   332      * follow the delegation model for loading classes, and will be invoked by
   333      * the {@link #loadClass <tt>loadClass</tt>} method after checking the
   334      * parent class loader for the requested class.  The default implementation
   335      * throws a <tt>ClassNotFoundException</tt>.  </p>
   336      *
   337      * @param  name
   338      *         The <a href="#name">binary name</a> of the class
   339      *
   340      * @return  The resulting <tt>Class</tt> object
   341      *
   342      * @throws  ClassNotFoundException
   343      *          If the class could not be found
   344      *
   345      * @since  1.2
   346      */
   347     protected Class<?> findClass(String name) throws ClassNotFoundException {
   348         throw new ClassNotFoundException(name);
   349     }
   350 
   351     /**
   352      * Converts an array of bytes into an instance of class <tt>Class</tt>.
   353      * Before the <tt>Class</tt> can be used it must be resolved.  This method
   354      * is deprecated in favor of the version that takes a <a
   355      * href="#name">binary name</a> as its first argument, and is more secure.
   356      *
   357      * @param  b
   358      *         The bytes that make up the class data.  The bytes in positions
   359      *         <tt>off</tt> through <tt>off+len-1</tt> should have the format
   360      *         of a valid class file as defined by
   361      *         <cite>The Java&trade; Virtual Machine Specification</cite>.
   362      *
   363      * @param  off
   364      *         The start offset in <tt>b</tt> of the class data
   365      *
   366      * @param  len
   367      *         The length of the class data
   368      *
   369      * @return  The <tt>Class</tt> object that was created from the specified
   370      *          class data
   371      *
   372      * @throws  ClassFormatError
   373      *          If the data did not contain a valid class
   374      *
   375      * @throws  IndexOutOfBoundsException
   376      *          If either <tt>off</tt> or <tt>len</tt> is negative, or if
   377      *          <tt>off+len</tt> is greater than <tt>b.length</tt>.
   378      *
   379      * @throws  SecurityException
   380      *          If an attempt is made to add this class to a package that
   381      *          contains classes that were signed by a different set of
   382      *          certificates than this class, or if an attempt is made
   383      *          to define a class in a package with a fully-qualified name
   384      *          that starts with "{@code java.}".
   385      *
   386      * @see  #loadClass(String, boolean)
   387      * @see  #resolveClass(Class)
   388      *
   389      * @deprecated  Replaced by {@link #defineClass(String, byte[], int, int)
   390      * defineClass(String, byte[], int, int)}
   391      */
   392     @Deprecated
   393     protected final Class<?> defineClass(byte[] b, int off, int len)
   394         throws ClassFormatError
   395     {
   396         throw new SecurityException();
   397     }
   398 
   399     /**
   400      * Converts an array of bytes into an instance of class <tt>Class</tt>.
   401      * Before the <tt>Class</tt> can be used it must be resolved.
   402      *
   403      * <p> This method assigns a default {@link java.security.ProtectionDomain
   404      * <tt>ProtectionDomain</tt>} to the newly defined class.  The
   405      * <tt>ProtectionDomain</tt> is effectively granted the same set of
   406      * permissions returned when {@link
   407      * java.security.Policy#getPermissions(java.security.CodeSource)
   408      * <tt>Policy.getPolicy().getPermissions(new CodeSource(null, null))</tt>}
   409      * is invoked.  The default domain is created on the first invocation of
   410      * {@link #defineClass(String, byte[], int, int) <tt>defineClass</tt>},
   411      * and re-used on subsequent invocations.
   412      *
   413      * <p> To assign a specific <tt>ProtectionDomain</tt> to the class, use
   414      * the {@link #defineClass(String, byte[], int, int,
   415      * java.security.ProtectionDomain) <tt>defineClass</tt>} method that takes a
   416      * <tt>ProtectionDomain</tt> as one of its arguments.  </p>
   417      *
   418      * @param  name
   419      *         The expected <a href="#name">binary name</a> of the class, or
   420      *         <tt>null</tt> if not known
   421      *
   422      * @param  b
   423      *         The bytes that make up the class data.  The bytes in positions
   424      *         <tt>off</tt> through <tt>off+len-1</tt> should have the format
   425      *         of a valid class file as defined by
   426      *         <cite>The Java&trade; Virtual Machine Specification</cite>.
   427      *
   428      * @param  off
   429      *         The start offset in <tt>b</tt> of the class data
   430      *
   431      * @param  len
   432      *         The length of the class data
   433      *
   434      * @return  The <tt>Class</tt> object that was created from the specified
   435      *          class data.
   436      *
   437      * @throws  ClassFormatError
   438      *          If the data did not contain a valid class
   439      *
   440      * @throws  IndexOutOfBoundsException
   441      *          If either <tt>off</tt> or <tt>len</tt> is negative, or if
   442      *          <tt>off+len</tt> is greater than <tt>b.length</tt>.
   443      *
   444      * @throws  SecurityException
   445      *          If an attempt is made to add this class to a package that
   446      *          contains classes that were signed by a different set of
   447      *          certificates than this class (which is unsigned), or if
   448      *          <tt>name</tt> begins with "<tt>java.</tt>".
   449      *
   450      * @see  #loadClass(String, boolean)
   451      * @see  #resolveClass(Class)
   452      * @see  java.security.CodeSource
   453      * @see  java.security.SecureClassLoader
   454      *
   455      * @since  1.1
   456      */
   457     protected final Class<?> defineClass(String name, byte[] b, int off, int len)
   458         throws ClassFormatError
   459     {
   460         throw new SecurityException();
   461     }
   462 
   463     /**
   464      * Links the specified class.  This (misleadingly named) method may be
   465      * used by a class loader to link a class.  If the class <tt>c</tt> has
   466      * already been linked, then this method simply returns. Otherwise, the
   467      * class is linked as described in the "Execution" chapter of
   468      * <cite>The Java&trade; Language Specification</cite>.
   469      * </p>
   470      *
   471      * @param  c
   472      *         The class to link
   473      *
   474      * @throws  NullPointerException
   475      *          If <tt>c</tt> is <tt>null</tt>.
   476      *
   477      * @see  #defineClass(String, byte[], int, int)
   478      */
   479     protected final void resolveClass(Class<?> c) {
   480         resolveClass0(c);
   481     }
   482 
   483     private native void resolveClass0(Class c);
   484 
   485 
   486     /**
   487      * Returns the class with the given <a href="#name">binary name</a> if this
   488      * loader has been recorded by the Java virtual machine as an initiating
   489      * loader of a class with that <a href="#name">binary name</a>.  Otherwise
   490      * <tt>null</tt> is returned.  </p>
   491      *
   492      * @param  name
   493      *         The <a href="#name">binary name</a> of the class
   494      *
   495      * @return  The <tt>Class</tt> object, or <tt>null</tt> if the class has
   496      *          not been loaded
   497      *
   498      * @since  1.1
   499      */
   500     protected final Class<?> findLoadedClass(String name) {
   501         try {
   502             return Class.forName(name);
   503         } catch (ClassNotFoundException ex) {
   504             return null;
   505         }
   506     }
   507 
   508     /**
   509      * Sets the signers of a class.  This should be invoked after defining a
   510      * class.  </p>
   511      *
   512      * @param  c
   513      *         The <tt>Class</tt> object
   514      *
   515      * @param  signers
   516      *         The signers for the class
   517      *
   518      * @since  1.1
   519      */
   520     protected final void setSigners(Class<?> c, Object[] signers) {
   521         //c.setSigners(signers);
   522         throw new UnsupportedOperationException();
   523     }
   524 
   525 
   526     // -- Resource --
   527 
   528     /**
   529      * Finds the resource with the given name.  A resource is some data
   530      * (images, audio, text, etc) that can be accessed by class code in a way
   531      * that is independent of the location of the code.
   532      *
   533      * <p> The name of a resource is a '<tt>/</tt>'-separated path name that
   534      * identifies the resource.
   535      *
   536      * <p> This method will first search the parent class loader for the
   537      * resource; if the parent is <tt>null</tt> the path of the class loader
   538      * built-in to the virtual machine is searched.  That failing, this method
   539      * will invoke {@link #findResource(String)} to find the resource.  </p>
   540      *
   541      * @param  name
   542      *         The resource name
   543      *
   544      * @return  A <tt>URL</tt> object for reading the resource, or
   545      *          <tt>null</tt> if the resource could not be found or the invoker
   546      *          doesn't have adequate  privileges to get the resource.
   547      *
   548      * @since  1.1
   549      */
   550     public URL getResource(String name) {
   551         URL url;
   552         if (parent != null) {
   553             url = parent.getResource(name);
   554         } else {
   555             url = getBootstrapResource(name);
   556         }
   557         if (url == null) {
   558             url = findResource(name);
   559         }
   560         return url;
   561     }
   562 
   563     /**
   564      * Finds all the resources with the given name. A resource is some data
   565      * (images, audio, text, etc) that can be accessed by class code in a way
   566      * that is independent of the location of the code.
   567      *
   568      * <p>The name of a resource is a <tt>/</tt>-separated path name that
   569      * identifies the resource.
   570      *
   571      * <p> The search order is described in the documentation for {@link
   572      * #getResource(String)}.  </p>
   573      *
   574      * @param  name
   575      *         The resource name
   576      *
   577      * @return  An enumeration of {@link java.net.URL <tt>URL</tt>} objects for
   578      *          the resource.  If no resources could  be found, the enumeration
   579      *          will be empty.  Resources that the class loader doesn't have
   580      *          access to will not be in the enumeration.
   581      *
   582      * @throws  IOException
   583      *          If I/O errors occur
   584      *
   585      * @see  #findResources(String)
   586      *
   587      * @since  1.2
   588      */
   589     public Enumeration<URL> getResources(String name) throws IOException {
   590         if (this == SYSTEM) {
   591             return findResources(name);
   592         }
   593         Enumeration[] tmp = new Enumeration[2];
   594         if (parent != null) {
   595             tmp[0] = parent.getResources(name);
   596         } else {
   597             tmp[0] = getBootstrapResources(name);
   598         }
   599         tmp[1] = findResources(name);
   600 
   601         return new CompoundEnumeration(tmp);
   602     }
   603 
   604     /**
   605      * Finds the resource with the given name. Class loader implementations
   606      * should override this method to specify where to find resources.  </p>
   607      *
   608      * @param  name
   609      *         The resource name
   610      *
   611      * @return  A <tt>URL</tt> object for reading the resource, or
   612      *          <tt>null</tt> if the resource could not be found
   613      *
   614      * @since  1.2
   615      */
   616     protected URL findResource(String name) {
   617         return null;
   618     }
   619 
   620     /**
   621      * Returns an enumeration of {@link java.net.URL <tt>URL</tt>} objects
   622      * representing all the resources with the given name. Class loader
   623      * implementations should override this method to specify where to load
   624      * resources from.  </p>
   625      *
   626      * @param  name
   627      *         The resource name
   628      *
   629      * @return  An enumeration of {@link java.net.URL <tt>URL</tt>} objects for
   630      *          the resources
   631      *
   632      * @throws  IOException
   633      *          If I/O errors occur
   634      *
   635      * @since  1.2
   636      */
   637     protected Enumeration<URL> findResources(String name) throws IOException {
   638         return new CompoundEnumeration(new Enumeration[0]);
   639     }
   640 
   641     // index 0: java.lang.ClassLoader.class
   642     // index 1: the immediate caller of index 0.
   643     // index 2: the immediate caller of index 1.
   644     private static native Class<? extends ClassLoader> getCaller(int index);
   645 
   646     /**
   647      * Registers the caller as parallel capable.</p>
   648      * The registration succeeds if and only if all of the following
   649      * conditions are met: <br>
   650      * 1. no instance of the caller has been created</p>
   651      * 2. all of the super classes (except class Object) of the caller are
   652      * registered as parallel capable</p>
   653      * Note that once a class loader is registered as parallel capable, there
   654      * is no way to change it back. </p>
   655      *
   656      * @return  true if the caller is successfully registered as
   657      *          parallel capable and false if otherwise.
   658      *
   659      * @since   1.7
   660      */
   661 //    protected static boolean registerAsParallelCapable() {
   662 //        return false;
   663 //    }
   664 
   665     /**
   666      * Find a resource of the specified name from the search path used to load
   667      * classes.  This method locates the resource through the system class
   668      * loader (see {@link #getSystemClassLoader()}).  </p>
   669      *
   670      * @param  name
   671      *         The resource name
   672      *
   673      * @return  A {@link java.net.URL <tt>URL</tt>} object for reading the
   674      *          resource, or <tt>null</tt> if the resource could not be found
   675      *
   676      * @since  1.1
   677      */
   678     public static URL getSystemResource(String name) {
   679         ClassLoader system = getSystemClassLoader();
   680         if (system == null) {
   681             return getBootstrapResource(name);
   682         }
   683         return system.getResource(name);
   684     }
   685 
   686     /**
   687      * Finds all resources of the specified name from the search path used to
   688      * load classes.  The resources thus found are returned as an
   689      * {@link java.util.Enumeration <tt>Enumeration</tt>} of {@link
   690      * java.net.URL <tt>URL</tt>} objects.
   691      *
   692      * <p> The search order is described in the documentation for {@link
   693      * #getSystemResource(String)}.  </p>
   694      *
   695      * @param  name
   696      *         The resource name
   697      *
   698      * @return  An enumeration of resource {@link java.net.URL <tt>URL</tt>}
   699      *          objects
   700      *
   701      * @throws  IOException
   702      *          If I/O errors occur
   703 
   704      * @since  1.2
   705      */
   706     public static Enumeration<URL> getSystemResources(String name)
   707         throws IOException
   708     {
   709         ClassLoader system = null; // getSystemClassLoader();
   710         if (system == null) {
   711             return getBootstrapResources(name);
   712         }
   713         return system.getResources(name);
   714     }
   715 
   716 
   717 
   718     /**
   719      * Returns an input stream for reading the specified resource.
   720      *
   721      * <p> The search order is described in the documentation for {@link
   722      * #getResource(String)}.  </p>
   723      *
   724      * @param  name
   725      *         The resource name
   726      *
   727      * @return  An input stream for reading the resource, or <tt>null</tt>
   728      *          if the resource could not be found
   729      *
   730      * @since  1.1
   731      */
   732     public InputStream getResourceAsStream(String name) {
   733         URL url = getResource(name);
   734         try {
   735             return url != null ? url.openStream() : null;
   736         } catch (IOException e) {
   737             return null;
   738         }
   739     }
   740 
   741     /**
   742      * Open for reading, a resource of the specified name from the search path
   743      * used to load classes.  This method locates the resource through the
   744      * system class loader (see {@link #getSystemClassLoader()}).  </p>
   745      *
   746      * @param  name
   747      *         The resource name
   748      *
   749      * @return  An input stream for reading the resource, or <tt>null</tt>
   750      *          if the resource could not be found
   751      *
   752      * @since  1.1
   753      */
   754     public static InputStream getSystemResourceAsStream(String name) {
   755         URL url = getSystemResource(name);
   756         try {
   757             return url != null ? url.openStream() : null;
   758         } catch (IOException e) {
   759             return null;
   760         }
   761     }
   762 
   763 
   764     // -- Hierarchy --
   765 
   766     /**
   767      * Returns the parent class loader for delegation. Some implementations may
   768      * use <tt>null</tt> to represent the bootstrap class loader. This method
   769      * will return <tt>null</tt> in such implementations if this class loader's
   770      * parent is the bootstrap class loader.
   771      *
   772      * <p> If a security manager is present, and the invoker's class loader is
   773      * not <tt>null</tt> and is not an ancestor of this class loader, then this
   774      * method invokes the security manager's {@link
   775      * SecurityManager#checkPermission(java.security.Permission)
   776      * <tt>checkPermission</tt>} method with a {@link
   777      * RuntimePermission#RuntimePermission(String)
   778      * <tt>RuntimePermission("getClassLoader")</tt>} permission to verify
   779      * access to the parent class loader is permitted.  If not, a
   780      * <tt>SecurityException</tt> will be thrown.  </p>
   781      *
   782      * @return  The parent <tt>ClassLoader</tt>
   783      *
   784      * @throws  SecurityException
   785      *          If a security manager exists and its <tt>checkPermission</tt>
   786      *          method doesn't allow access to this class loader's parent class
   787      *          loader.
   788      *
   789      * @since  1.2
   790      */
   791     public final ClassLoader getParent() {
   792         throw new SecurityException();
   793     }
   794 
   795     /**
   796      * Returns the system class loader for delegation.  This is the default
   797      * delegation parent for new <tt>ClassLoader</tt> instances, and is
   798      * typically the class loader used to start the application.
   799      *
   800      * <p> This method is first invoked early in the runtime's startup
   801      * sequence, at which point it creates the system class loader and sets it
   802      * as the context class loader of the invoking <tt>Thread</tt>.
   803      *
   804      * <p> The default system class loader is an implementation-dependent
   805      * instance of this class.
   806      *
   807      * <p> If the system property "<tt>java.system.class.loader</tt>" is defined
   808      * when this method is first invoked then the value of that property is
   809      * taken to be the name of a class that will be returned as the system
   810      * class loader.  The class is loaded using the default system class loader
   811      * and must define a public constructor that takes a single parameter of
   812      * type <tt>ClassLoader</tt> which is used as the delegation parent.  An
   813      * instance is then created using this constructor with the default system
   814      * class loader as the parameter.  The resulting class loader is defined
   815      * to be the system class loader.
   816      *
   817      * <p> If a security manager is present, and the invoker's class loader is
   818      * not <tt>null</tt> and the invoker's class loader is not the same as or
   819      * an ancestor of the system class loader, then this method invokes the
   820      * security manager's {@link
   821      * SecurityManager#checkPermission(java.security.Permission)
   822      * <tt>checkPermission</tt>} method with a {@link
   823      * RuntimePermission#RuntimePermission(String)
   824      * <tt>RuntimePermission("getClassLoader")</tt>} permission to verify
   825      * access to the system class loader.  If not, a
   826      * <tt>SecurityException</tt> will be thrown.  </p>
   827      *
   828      * @return  The system <tt>ClassLoader</tt> for delegation, or
   829      *          <tt>null</tt> if none
   830      *
   831      * @throws  SecurityException
   832      *          If a security manager exists and its <tt>checkPermission</tt>
   833      *          method doesn't allow access to the system class loader.
   834      *
   835      * @throws  IllegalStateException
   836      *          If invoked recursively during the construction of the class
   837      *          loader specified by the "<tt>java.system.class.loader</tt>"
   838      *          property.
   839      *
   840      * @throws  Error
   841      *          If the system property "<tt>java.system.class.loader</tt>"
   842      *          is defined but the named class could not be loaded, the
   843      *          provider class does not define the required constructor, or an
   844      *          exception is thrown by that constructor when it is invoked. The
   845      *          underlying cause of the error can be retrieved via the
   846      *          {@link Throwable#getCause()} method.
   847      *
   848      * @revised  1.4
   849      */
   850     public static ClassLoader getSystemClassLoader() {
   851         if (SYSTEM == null) {
   852             SYSTEM = new ClassLoader() {
   853                 @Override
   854                 protected Enumeration<URL> findResources(String name) throws IOException {
   855                     return getBootstrapResources(name);
   856                 }
   857 
   858                 @Override
   859                 protected URL findResource(String name) {
   860                     return getBootstrapResource(name);
   861                 }
   862 
   863                 @Override
   864                 protected Class<?> findClass(String name) throws ClassNotFoundException {
   865                     return Class.forName(name);
   866                 }
   867             };
   868         }
   869         return SYSTEM;
   870     }
   871     private static ClassLoader SYSTEM;
   872 
   873     // Returns true if the specified class loader can be found in this class
   874     // loader's delegation chain.
   875     boolean isAncestor(ClassLoader cl) {
   876         ClassLoader acl = this;
   877         do {
   878             acl = acl.parent;
   879             if (cl == acl) {
   880                 return true;
   881             }
   882         } while (acl != null);
   883         return false;
   884     }
   885 
   886     private Class findBootstrapClassOrNull(String name) {
   887         throw new UnsupportedOperationException();
   888     }
   889 
   890     private static URL getBootstrapResource(String name) {
   891         return Object.class.getResource("/" + name);
   892     }
   893 
   894     @JavaScriptBody(args = { "name", "skip" }, body
   895         = "var lb = vm.loadBytes ? vm.loadBytes : exports.loadBytes;"
   896         + "return lb ? lb(name, skip) : null;"
   897     )
   898     static native byte[] getResourceAsStream0(String name, int skip);
   899 
   900     private static Enumeration<URL> getBootstrapResources(String name) {
   901         return new ResEnum(name);
   902     }
   903     
   904     private static class ResEnum implements Enumeration<URL> {
   905         private final String name;
   906         private URL next;
   907         private int skip;
   908 
   909         public ResEnum(String name) {
   910             this.name = name;
   911         }
   912 
   913 
   914         public boolean hasMoreElements() {
   915             if (next == null && skip >= 0) {
   916                 byte[] arr = getResourceAsStream0(name, skip++);
   917                 if (arr != null) {
   918                     next = Class.newResourceURL(name, arr);
   919                 } else {
   920                     skip = -1;
   921                 }
   922             }
   923             return next != null;
   924         }
   925 
   926         public URL nextElement() {
   927             URL r = next;
   928             if (r == null) {
   929                 throw new NoSuchElementException();
   930             }
   931             next = null;
   932             return r;
   933         }
   934     }
   935     
   936     private static class OneOrZeroEnum implements Enumeration<URL> {
   937         private URL u;
   938 
   939         public OneOrZeroEnum(URL u) {
   940             this.u = u;
   941         }
   942 
   943         public boolean hasMoreElements() {
   944             return u != null;
   945         }
   946 
   947         public URL nextElement() {
   948             URL r = u;
   949             if (r == null) {
   950                 throw new NoSuchElementException();
   951             }
   952             u = null;
   953             return r;
   954         }
   955     }
   956 
   957     private static class CompoundEnumeration implements Enumeration<URL> {
   958         private URL next;
   959         private int index;
   960         private final Enumeration[] arr;
   961 
   962         public CompoundEnumeration(Enumeration[] arr) {
   963             this.arr = arr;
   964             this.index = 0;
   965         }
   966 
   967         public boolean hasMoreElements() {
   968             if (next == null && index < arr.length) {
   969                 if (arr[index].hasMoreElements()) {
   970                     next = (URL) arr[index].nextElement();
   971                 } else {
   972                     if (index < arr.length) {
   973                         index++;
   974                         return hasMoreElements();
   975                     }
   976                 }
   977             }
   978             return next != null;
   979         }
   980 
   981         public URL nextElement() {
   982             if (!hasMoreElements()) {
   983                 throw new NoSuchElementException();
   984             }
   985             URL r = next;
   986             next = null;
   987             return r;
   988         }
   989         
   990     }
   991 }