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