emul/src/main/java/java/lang/ClassLoader.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Sun, 02 Dec 2012 06:25:28 +0100
changeset 232 36f16c49bdef
parent 122 0a582b5a2737
permissions -rw-r--r--
Throw exception when reaching native method without JavaScript implementation
     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         throw new SecurityException();
   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         throw new SecurityException();
   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         if (!checkName(name))
   502             return null;
   503         return findLoadedClass0(name);
   504     }
   505 
   506     private native final Class findLoadedClass0(String name);
   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         Enumeration[] tmp = new Enumeration[2];
   591         if (parent != null) {
   592             tmp[0] = parent.getResources(name);
   593         } else {
   594             tmp[0] = getBootstrapResources(name);
   595         }
   596         tmp[1] = findResources(name);
   597 
   598         return new CompoundEnumeration(tmp);
   599     }
   600 
   601     /**
   602      * Finds the resource with the given name. Class loader implementations
   603      * should override this method to specify where to find resources.  </p>
   604      *
   605      * @param  name
   606      *         The resource name
   607      *
   608      * @return  A <tt>URL</tt> object for reading the resource, or
   609      *          <tt>null</tt> if the resource could not be found
   610      *
   611      * @since  1.2
   612      */
   613     protected URL findResource(String name) {
   614         return null;
   615     }
   616 
   617     /**
   618      * Returns an enumeration of {@link java.net.URL <tt>URL</tt>} objects
   619      * representing all the resources with the given name. Class loader
   620      * implementations should override this method to specify where to load
   621      * resources from.  </p>
   622      *
   623      * @param  name
   624      *         The resource name
   625      *
   626      * @return  An enumeration of {@link java.net.URL <tt>URL</tt>} objects for
   627      *          the resources
   628      *
   629      * @throws  IOException
   630      *          If I/O errors occur
   631      *
   632      * @since  1.2
   633      */
   634     protected Enumeration<URL> findResources(String name) throws IOException {
   635         return new CompoundEnumeration(new Enumeration[0]);
   636     }
   637 
   638     // index 0: java.lang.ClassLoader.class
   639     // index 1: the immediate caller of index 0.
   640     // index 2: the immediate caller of index 1.
   641     private static native Class<? extends ClassLoader> getCaller(int index);
   642 
   643     /**
   644      * Registers the caller as parallel capable.</p>
   645      * The registration succeeds if and only if all of the following
   646      * conditions are met: <br>
   647      * 1. no instance of the caller has been created</p>
   648      * 2. all of the super classes (except class Object) of the caller are
   649      * registered as parallel capable</p>
   650      * Note that once a class loader is registered as parallel capable, there
   651      * is no way to change it back. </p>
   652      *
   653      * @return  true if the caller is successfully registered as
   654      *          parallel capable and false if otherwise.
   655      *
   656      * @since   1.7
   657      */
   658 //    protected static boolean registerAsParallelCapable() {
   659 //        return false;
   660 //    }
   661 
   662     /**
   663      * Find a resource of the specified name from the search path used to load
   664      * classes.  This method locates the resource through the system class
   665      * loader (see {@link #getSystemClassLoader()}).  </p>
   666      *
   667      * @param  name
   668      *         The resource name
   669      *
   670      * @return  A {@link java.net.URL <tt>URL</tt>} object for reading the
   671      *          resource, or <tt>null</tt> if the resource could not be found
   672      *
   673      * @since  1.1
   674      */
   675     public static URL getSystemResource(String name) {
   676         ClassLoader system = getSystemClassLoader();
   677         if (system == null) {
   678             return getBootstrapResource(name);
   679         }
   680         return system.getResource(name);
   681     }
   682 
   683     /**
   684      * Finds all resources of the specified name from the search path used to
   685      * load classes.  The resources thus found are returned as an
   686      * {@link java.util.Enumeration <tt>Enumeration</tt>} of {@link
   687      * java.net.URL <tt>URL</tt>} objects.
   688      *
   689      * <p> The search order is described in the documentation for {@link
   690      * #getSystemResource(String)}.  </p>
   691      *
   692      * @param  name
   693      *         The resource name
   694      *
   695      * @return  An enumeration of resource {@link java.net.URL <tt>URL</tt>}
   696      *          objects
   697      *
   698      * @throws  IOException
   699      *          If I/O errors occur
   700 
   701      * @since  1.2
   702      */
   703     public static Enumeration<URL> getSystemResources(String name)
   704         throws IOException
   705     {
   706         ClassLoader system = getSystemClassLoader();
   707         if (system == null) {
   708             return getBootstrapResources(name);
   709         }
   710         return system.getResources(name);
   711     }
   712 
   713 
   714 
   715     /**
   716      * Returns an input stream for reading the specified resource.
   717      *
   718      * <p> The search order is described in the documentation for {@link
   719      * #getResource(String)}.  </p>
   720      *
   721      * @param  name
   722      *         The resource name
   723      *
   724      * @return  An input stream for reading the resource, or <tt>null</tt>
   725      *          if the resource could not be found
   726      *
   727      * @since  1.1
   728      */
   729     public InputStream getResourceAsStream(String name) {
   730         URL url = getResource(name);
   731         try {
   732             return url != null ? url.openStream() : null;
   733         } catch (IOException e) {
   734             return null;
   735         }
   736     }
   737 
   738     /**
   739      * Open for reading, a resource of the specified name from the search path
   740      * used to load classes.  This method locates the resource through the
   741      * system class loader (see {@link #getSystemClassLoader()}).  </p>
   742      *
   743      * @param  name
   744      *         The resource name
   745      *
   746      * @return  An input stream for reading the resource, or <tt>null</tt>
   747      *          if the resource could not be found
   748      *
   749      * @since  1.1
   750      */
   751     public static InputStream getSystemResourceAsStream(String name) {
   752         URL url = getSystemResource(name);
   753         try {
   754             return url != null ? url.openStream() : null;
   755         } catch (IOException e) {
   756             return null;
   757         }
   758     }
   759 
   760 
   761     // -- Hierarchy --
   762 
   763     /**
   764      * Returns the parent class loader for delegation. Some implementations may
   765      * use <tt>null</tt> to represent the bootstrap class loader. This method
   766      * will return <tt>null</tt> in such implementations if this class loader's
   767      * parent is the bootstrap class loader.
   768      *
   769      * <p> If a security manager is present, and the invoker's class loader is
   770      * not <tt>null</tt> and is not an ancestor of this class loader, then this
   771      * method invokes the security manager's {@link
   772      * SecurityManager#checkPermission(java.security.Permission)
   773      * <tt>checkPermission</tt>} method with a {@link
   774      * RuntimePermission#RuntimePermission(String)
   775      * <tt>RuntimePermission("getClassLoader")</tt>} permission to verify
   776      * access to the parent class loader is permitted.  If not, a
   777      * <tt>SecurityException</tt> will be thrown.  </p>
   778      *
   779      * @return  The parent <tt>ClassLoader</tt>
   780      *
   781      * @throws  SecurityException
   782      *          If a security manager exists and its <tt>checkPermission</tt>
   783      *          method doesn't allow access to this class loader's parent class
   784      *          loader.
   785      *
   786      * @since  1.2
   787      */
   788     public final ClassLoader getParent() {
   789         throw new SecurityException();
   790     }
   791 
   792     /**
   793      * Returns the system class loader for delegation.  This is the default
   794      * delegation parent for new <tt>ClassLoader</tt> instances, and is
   795      * typically the class loader used to start the application.
   796      *
   797      * <p> This method is first invoked early in the runtime's startup
   798      * sequence, at which point it creates the system class loader and sets it
   799      * as the context class loader of the invoking <tt>Thread</tt>.
   800      *
   801      * <p> The default system class loader is an implementation-dependent
   802      * instance of this class.
   803      *
   804      * <p> If the system property "<tt>java.system.class.loader</tt>" is defined
   805      * when this method is first invoked then the value of that property is
   806      * taken to be the name of a class that will be returned as the system
   807      * class loader.  The class is loaded using the default system class loader
   808      * and must define a public constructor that takes a single parameter of
   809      * type <tt>ClassLoader</tt> which is used as the delegation parent.  An
   810      * instance is then created using this constructor with the default system
   811      * class loader as the parameter.  The resulting class loader is defined
   812      * to be the system class loader.
   813      *
   814      * <p> If a security manager is present, and the invoker's class loader is
   815      * not <tt>null</tt> and the invoker's class loader is not the same as or
   816      * an ancestor of the system class loader, then this method invokes the
   817      * security manager's {@link
   818      * SecurityManager#checkPermission(java.security.Permission)
   819      * <tt>checkPermission</tt>} method with a {@link
   820      * RuntimePermission#RuntimePermission(String)
   821      * <tt>RuntimePermission("getClassLoader")</tt>} permission to verify
   822      * access to the system class loader.  If not, a
   823      * <tt>SecurityException</tt> will be thrown.  </p>
   824      *
   825      * @return  The system <tt>ClassLoader</tt> for delegation, or
   826      *          <tt>null</tt> if none
   827      *
   828      * @throws  SecurityException
   829      *          If a security manager exists and its <tt>checkPermission</tt>
   830      *          method doesn't allow access to the system class loader.
   831      *
   832      * @throws  IllegalStateException
   833      *          If invoked recursively during the construction of the class
   834      *          loader specified by the "<tt>java.system.class.loader</tt>"
   835      *          property.
   836      *
   837      * @throws  Error
   838      *          If the system property "<tt>java.system.class.loader</tt>"
   839      *          is defined but the named class could not be loaded, the
   840      *          provider class does not define the required constructor, or an
   841      *          exception is thrown by that constructor when it is invoked. The
   842      *          underlying cause of the error can be retrieved via the
   843      *          {@link Throwable#getCause()} method.
   844      *
   845      * @revised  1.4
   846      */
   847     public static ClassLoader getSystemClassLoader() {
   848         throw new SecurityException();
   849     }
   850 
   851     // Returns true if the specified class loader can be found in this class
   852     // loader's delegation chain.
   853     boolean isAncestor(ClassLoader cl) {
   854         ClassLoader acl = this;
   855         do {
   856             acl = acl.parent;
   857             if (cl == acl) {
   858                 return true;
   859             }
   860         } while (acl != null);
   861         return false;
   862     }
   863 
   864     private boolean checkName(String name) {
   865         throw new UnsupportedOperationException(); 
   866     }
   867 
   868     private Class findBootstrapClassOrNull(String name) {
   869         throw new UnsupportedOperationException();
   870     }
   871 
   872     private static URL getBootstrapResource(String name) {
   873         throw new UnsupportedOperationException();
   874     }
   875 
   876     private static Enumeration<URL> getBootstrapResources(String name) {
   877         throw new UnsupportedOperationException();
   878     }
   879 
   880     private static class CompoundEnumeration implements Enumeration<URL> {
   881         private URL next;
   882         private int index;
   883         private final Enumeration[] arr;
   884 
   885         public CompoundEnumeration(Enumeration[] arr) {
   886             this.arr = arr;
   887             this.index = 0;
   888         }
   889 
   890         public boolean hasMoreElements() {
   891             if (next == null) {
   892                 if (arr[index].hasMoreElements()) {
   893                     next = (URL) arr[index].nextElement();
   894                 } else {
   895                     if (index < arr.length) {
   896                         index++;
   897                         return hasMoreElements();
   898                     }
   899                 }
   900             }
   901             return next != null;
   902         }
   903 
   904         public URL nextElement() {
   905             if (!hasMoreElements()) {
   906                 throw new NoSuchElementException();
   907             }
   908             URL r = next;
   909             next = null;
   910             return r;
   911         }
   912         
   913     }
   914 }