emul/mini/src/main/java/java/lang/ClassLoader.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Sat, 26 Jan 2013 08:47:05 +0100
changeset 592 5e13b1ac2886
parent 554 05224402145d
permissions -rw-r--r--
In order to support fields of the same name in subclasses we are now prefixing them with name of the class that defines them. To provide convenient way to access them from generated bytecode and also directly from JavaScript, there is a getter/setter function for each field. It starts with _ followed by the field name. If called with a parameter, it sets the field, with a parameter it just returns it.
     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 = null; // 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         URL u = Object.class.getResource("/" + name);
   878         return new OneOrZeroEnum(u);
   879     }
   880     
   881     private static class OneOrZeroEnum implements Enumeration<URL> {
   882         private URL u;
   883 
   884         public OneOrZeroEnum(URL u) {
   885             this.u = u;
   886         }
   887 
   888         public boolean hasMoreElements() {
   889             return u != null;
   890         }
   891 
   892         public URL nextElement() {
   893             URL r = u;
   894             if (r == null) {
   895                 throw new NoSuchElementException();
   896             }
   897             u = null;
   898             return r;
   899         }
   900     }
   901 
   902     private static class CompoundEnumeration implements Enumeration<URL> {
   903         private URL next;
   904         private int index;
   905         private final Enumeration[] arr;
   906 
   907         public CompoundEnumeration(Enumeration[] arr) {
   908             this.arr = arr;
   909             this.index = 0;
   910         }
   911 
   912         public boolean hasMoreElements() {
   913             if (next == null) {
   914                 if (arr[index].hasMoreElements()) {
   915                     next = (URL) arr[index].nextElement();
   916                 } else {
   917                     if (index < arr.length) {
   918                         index++;
   919                         return hasMoreElements();
   920                     }
   921                 }
   922             }
   923             return next != null;
   924         }
   925 
   926         public URL nextElement() {
   927             if (!hasMoreElements()) {
   928                 throw new NoSuchElementException();
   929             }
   930             URL r = next;
   931             next = null;
   932             return r;
   933         }
   934         
   935     }
   936 }