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