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