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