1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/emul/mini/src/main/java/java/lang/ClassLoader.java Wed Jan 23 20:39:23 2013 +0100
1.3 @@ -0,0 +1,914 @@
1.4 +/*
1.5 + * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved.
1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
1.7 + *
1.8 + * This code is free software; you can redistribute it and/or modify it
1.9 + * under the terms of the GNU General Public License version 2 only, as
1.10 + * published by the Free Software Foundation. Oracle designates this
1.11 + * particular file as subject to the "Classpath" exception as provided
1.12 + * by Oracle in the LICENSE file that accompanied this code.
1.13 + *
1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1.17 + * version 2 for more details (a copy is included in the LICENSE file that
1.18 + * accompanied this code).
1.19 + *
1.20 + * You should have received a copy of the GNU General Public License version
1.21 + * 2 along with this work; if not, write to the Free Software Foundation,
1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1.23 + *
1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1.25 + * or visit www.oracle.com if you need additional information or have any
1.26 + * questions.
1.27 + */
1.28 +package java.lang;
1.29 +
1.30 +import java.io.InputStream;
1.31 +import java.io.IOException;
1.32 +import java.net.URL;
1.33 +import java.util.Enumeration;
1.34 +import java.util.NoSuchElementException;
1.35 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
1.36 +
1.37 +/**
1.38 + * A class loader is an object that is responsible for loading classes. The
1.39 + * class <tt>ClassLoader</tt> is an abstract class. Given the <a
1.40 + * href="#name">binary name</a> of a class, a class loader should attempt to
1.41 + * locate or generate data that constitutes a definition for the class. A
1.42 + * typical strategy is to transform the name into a file name and then read a
1.43 + * "class file" of that name from a file system.
1.44 + *
1.45 + * <p> Every {@link Class <tt>Class</tt>} object contains a {@link
1.46 + * Class#getClassLoader() reference} to the <tt>ClassLoader</tt> that defined
1.47 + * it.
1.48 + *
1.49 + * <p> <tt>Class</tt> objects for array classes are not created by class
1.50 + * loaders, but are created automatically as required by the Java runtime.
1.51 + * The class loader for an array class, as returned by {@link
1.52 + * Class#getClassLoader()} is the same as the class loader for its element
1.53 + * type; if the element type is a primitive type, then the array class has no
1.54 + * class loader.
1.55 + *
1.56 + * <p> Applications implement subclasses of <tt>ClassLoader</tt> in order to
1.57 + * extend the manner in which the Java virtual machine dynamically loads
1.58 + * classes.
1.59 + *
1.60 + * <p> Class loaders may typically be used by security managers to indicate
1.61 + * security domains.
1.62 + *
1.63 + * <p> The <tt>ClassLoader</tt> class uses a delegation model to search for
1.64 + * classes and resources. Each instance of <tt>ClassLoader</tt> has an
1.65 + * associated parent class loader. When requested to find a class or
1.66 + * resource, a <tt>ClassLoader</tt> instance will delegate the search for the
1.67 + * class or resource to its parent class loader before attempting to find the
1.68 + * class or resource itself. The virtual machine's built-in class loader,
1.69 + * called the "bootstrap class loader", does not itself have a parent but may
1.70 + * serve as the parent of a <tt>ClassLoader</tt> instance.
1.71 + *
1.72 + * <p> Class loaders that support concurrent loading of classes are known as
1.73 + * <em>parallel capable</em> class loaders and are required to register
1.74 + * themselves at their class initialization time by invoking the
1.75 + * {@link
1.76 + * #registerAsParallelCapable <tt>ClassLoader.registerAsParallelCapable</tt>}
1.77 + * method. Note that the <tt>ClassLoader</tt> class is registered as parallel
1.78 + * capable by default. However, its subclasses still need to register themselves
1.79 + * if they are parallel capable. <br>
1.80 + * In environments in which the delegation model is not strictly
1.81 + * hierarchical, class loaders need to be parallel capable, otherwise class
1.82 + * loading can lead to deadlocks because the loader lock is held for the
1.83 + * duration of the class loading process (see {@link #loadClass
1.84 + * <tt>loadClass</tt>} methods).
1.85 + *
1.86 + * <p> Normally, the Java virtual machine loads classes from the local file
1.87 + * system in a platform-dependent manner. For example, on UNIX systems, the
1.88 + * virtual machine loads classes from the directory defined by the
1.89 + * <tt>CLASSPATH</tt> environment variable.
1.90 + *
1.91 + * <p> However, some classes may not originate from a file; they may originate
1.92 + * from other sources, such as the network, or they could be constructed by an
1.93 + * application. The method {@link #defineClass(String, byte[], int, int)
1.94 + * <tt>defineClass</tt>} converts an array of bytes into an instance of class
1.95 + * <tt>Class</tt>. Instances of this newly defined class can be created using
1.96 + * {@link Class#newInstance <tt>Class.newInstance</tt>}.
1.97 + *
1.98 + * <p> The methods and constructors of objects created by a class loader may
1.99 + * reference other classes. To determine the class(es) referred to, the Java
1.100 + * virtual machine invokes the {@link #loadClass <tt>loadClass</tt>} method of
1.101 + * the class loader that originally created the class.
1.102 + *
1.103 + * <p> For example, an application could create a network class loader to
1.104 + * download class files from a server. Sample code might look like:
1.105 + *
1.106 + * <blockquote><pre>
1.107 + * ClassLoader loader = new NetworkClassLoader(host, port);
1.108 + * Object main = loader.loadClass("Main", true).newInstance();
1.109 + * . . .
1.110 + * </pre></blockquote>
1.111 + *
1.112 + * <p> The network class loader subclass must define the methods {@link
1.113 + * #findClass <tt>findClass</tt>} and <tt>loadClassData</tt> to load a class
1.114 + * from the network. Once it has downloaded the bytes that make up the class,
1.115 + * it should use the method {@link #defineClass <tt>defineClass</tt>} to
1.116 + * create a class instance. A sample implementation is:
1.117 + *
1.118 + * <blockquote><pre>
1.119 + * class NetworkClassLoader extends ClassLoader {
1.120 + * String host;
1.121 + * int port;
1.122 + *
1.123 + * public Class findClass(String name) {
1.124 + * byte[] b = loadClassData(name);
1.125 + * return defineClass(name, b, 0, b.length);
1.126 + * }
1.127 + *
1.128 + * private byte[] loadClassData(String name) {
1.129 + * // load the class data from the connection
1.130 + * . . .
1.131 + * }
1.132 + * }
1.133 + * </pre></blockquote>
1.134 + *
1.135 + * <h4> <a name="name">Binary names</a> </h4>
1.136 + *
1.137 + * <p> Any class name provided as a {@link String} parameter to methods in
1.138 + * <tt>ClassLoader</tt> must be a binary name as defined by
1.139 + * <cite>The Java™ Language Specification</cite>.
1.140 + *
1.141 + * <p> Examples of valid class names include:
1.142 + * <blockquote><pre>
1.143 + * "java.lang.String"
1.144 + * "javax.swing.JSpinner$DefaultEditor"
1.145 + * "java.security.KeyStore$Builder$FileBuilder$1"
1.146 + * "java.net.URLClassLoader$3$1"
1.147 + * </pre></blockquote>
1.148 + *
1.149 + * @see #resolveClass(Class)
1.150 + * @since 1.0
1.151 + */
1.152 +public abstract class ClassLoader {
1.153 +
1.154 + @JavaScriptBody(args = {}, body = "")
1.155 + private static native void registerNatives();
1.156 + static {
1.157 + registerNatives();
1.158 + }
1.159 +
1.160 + // The parent class loader for delegation
1.161 + // Note: VM hardcoded the offset of this field, thus all new fields
1.162 + // must be added *after* it.
1.163 + private final ClassLoader parent;
1.164 +
1.165 +
1.166 + /**
1.167 + * Creates a new class loader using the specified parent class loader for
1.168 + * delegation.
1.169 + *
1.170 + * <p> If there is a security manager, its {@link
1.171 + * SecurityManager#checkCreateClassLoader()
1.172 + * <tt>checkCreateClassLoader</tt>} method is invoked. This may result in
1.173 + * a security exception. </p>
1.174 + *
1.175 + * @param parent
1.176 + * The parent class loader
1.177 + *
1.178 + * @throws SecurityException
1.179 + * If a security manager exists and its
1.180 + * <tt>checkCreateClassLoader</tt> method doesn't allow creation
1.181 + * of a new class loader.
1.182 + *
1.183 + * @since 1.2
1.184 + */
1.185 + protected ClassLoader(ClassLoader parent) {
1.186 + throw new SecurityException();
1.187 + }
1.188 +
1.189 + /**
1.190 + * Creates a new class loader using the <tt>ClassLoader</tt> returned by
1.191 + * the method {@link #getSystemClassLoader()
1.192 + * <tt>getSystemClassLoader()</tt>} as the parent class loader.
1.193 + *
1.194 + * <p> If there is a security manager, its {@link
1.195 + * SecurityManager#checkCreateClassLoader()
1.196 + * <tt>checkCreateClassLoader</tt>} method is invoked. This may result in
1.197 + * a security exception. </p>
1.198 + *
1.199 + * @throws SecurityException
1.200 + * If a security manager exists and its
1.201 + * <tt>checkCreateClassLoader</tt> method doesn't allow creation
1.202 + * of a new class loader.
1.203 + */
1.204 + protected ClassLoader() {
1.205 + throw new SecurityException();
1.206 + }
1.207 +
1.208 + // -- Class --
1.209 +
1.210 + /**
1.211 + * Loads the class with the specified <a href="#name">binary name</a>.
1.212 + * This method searches for classes in the same manner as the {@link
1.213 + * #loadClass(String, boolean)} method. It is invoked by the Java virtual
1.214 + * machine to resolve class references. Invoking this method is equivalent
1.215 + * to invoking {@link #loadClass(String, boolean) <tt>loadClass(name,
1.216 + * false)</tt>}. </p>
1.217 + *
1.218 + * @param name
1.219 + * The <a href="#name">binary name</a> of the class
1.220 + *
1.221 + * @return The resulting <tt>Class</tt> object
1.222 + *
1.223 + * @throws ClassNotFoundException
1.224 + * If the class was not found
1.225 + */
1.226 + public Class<?> loadClass(String name) throws ClassNotFoundException {
1.227 + return loadClass(name, false);
1.228 + }
1.229 +
1.230 + /**
1.231 + * Loads the class with the specified <a href="#name">binary name</a>. The
1.232 + * default implementation of this method searches for classes in the
1.233 + * following order:
1.234 + *
1.235 + * <p><ol>
1.236 + *
1.237 + * <li><p> Invoke {@link #findLoadedClass(String)} to check if the class
1.238 + * has already been loaded. </p></li>
1.239 + *
1.240 + * <li><p> Invoke the {@link #loadClass(String) <tt>loadClass</tt>} method
1.241 + * on the parent class loader. If the parent is <tt>null</tt> the class
1.242 + * loader built-in to the virtual machine is used, instead. </p></li>
1.243 + *
1.244 + * <li><p> Invoke the {@link #findClass(String)} method to find the
1.245 + * class. </p></li>
1.246 + *
1.247 + * </ol>
1.248 + *
1.249 + * <p> If the class was found using the above steps, and the
1.250 + * <tt>resolve</tt> flag is true, this method will then invoke the {@link
1.251 + * #resolveClass(Class)} method on the resulting <tt>Class</tt> object.
1.252 + *
1.253 + * <p> Subclasses of <tt>ClassLoader</tt> are encouraged to override {@link
1.254 + * #findClass(String)}, rather than this method. </p>
1.255 + *
1.256 + * <p> Unless overridden, this method synchronizes on the result of
1.257 + * {@link #getClassLoadingLock <tt>getClassLoadingLock</tt>} method
1.258 + * during the entire class loading process.
1.259 + *
1.260 + * @param name
1.261 + * The <a href="#name">binary name</a> of the class
1.262 + *
1.263 + * @param resolve
1.264 + * If <tt>true</tt> then resolve the class
1.265 + *
1.266 + * @return The resulting <tt>Class</tt> object
1.267 + *
1.268 + * @throws ClassNotFoundException
1.269 + * If the class could not be found
1.270 + */
1.271 + protected Class<?> loadClass(String name, boolean resolve)
1.272 + throws ClassNotFoundException
1.273 + {
1.274 + synchronized (getClassLoadingLock(name)) {
1.275 + // First, check if the class has already been loaded
1.276 + Class c = findLoadedClass(name);
1.277 + if (c == null) {
1.278 + try {
1.279 + if (parent != null) {
1.280 + c = parent.loadClass(name, false);
1.281 + } else {
1.282 + c = findBootstrapClassOrNull(name);
1.283 + }
1.284 + } catch (ClassNotFoundException e) {
1.285 + // ClassNotFoundException thrown if class not found
1.286 + // from the non-null parent class loader
1.287 + }
1.288 +
1.289 + if (c == null) {
1.290 + // If still not found, then invoke findClass in order
1.291 + // to find the class.
1.292 + c = findClass(name);
1.293 +
1.294 +// // this is the defining class loader; record the stats
1.295 +// sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
1.296 +// sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
1.297 +// sun.misc.PerfCounter.getFindClasses().increment();
1.298 + }
1.299 + }
1.300 + if (resolve) {
1.301 + resolveClass(c);
1.302 + }
1.303 + return c;
1.304 + }
1.305 + }
1.306 +
1.307 + /**
1.308 + * Returns the lock object for class loading operations.
1.309 + * For backward compatibility, the default implementation of this method
1.310 + * behaves as follows. If this ClassLoader object is registered as
1.311 + * parallel capable, the method returns a dedicated object associated
1.312 + * with the specified class name. Otherwise, the method returns this
1.313 + * ClassLoader object. </p>
1.314 + *
1.315 + * @param className
1.316 + * The name of the to-be-loaded class
1.317 + *
1.318 + * @return the lock for class loading operations
1.319 + *
1.320 + * @throws NullPointerException
1.321 + * If registered as parallel capable and <tt>className</tt> is null
1.322 + *
1.323 + * @see #loadClass(String, boolean)
1.324 + *
1.325 + * @since 1.7
1.326 + */
1.327 + protected Object getClassLoadingLock(String className) {
1.328 + Object lock = this;
1.329 + return lock;
1.330 + }
1.331 +
1.332 + /**
1.333 + * Finds the class with the specified <a href="#name">binary name</a>.
1.334 + * This method should be overridden by class loader implementations that
1.335 + * follow the delegation model for loading classes, and will be invoked by
1.336 + * the {@link #loadClass <tt>loadClass</tt>} method after checking the
1.337 + * parent class loader for the requested class. The default implementation
1.338 + * throws a <tt>ClassNotFoundException</tt>. </p>
1.339 + *
1.340 + * @param name
1.341 + * The <a href="#name">binary name</a> of the class
1.342 + *
1.343 + * @return The resulting <tt>Class</tt> object
1.344 + *
1.345 + * @throws ClassNotFoundException
1.346 + * If the class could not be found
1.347 + *
1.348 + * @since 1.2
1.349 + */
1.350 + protected Class<?> findClass(String name) throws ClassNotFoundException {
1.351 + throw new ClassNotFoundException(name);
1.352 + }
1.353 +
1.354 + /**
1.355 + * Converts an array of bytes into an instance of class <tt>Class</tt>.
1.356 + * Before the <tt>Class</tt> can be used it must be resolved. This method
1.357 + * is deprecated in favor of the version that takes a <a
1.358 + * href="#name">binary name</a> as its first argument, and is more secure.
1.359 + *
1.360 + * @param b
1.361 + * The bytes that make up the class data. The bytes in positions
1.362 + * <tt>off</tt> through <tt>off+len-1</tt> should have the format
1.363 + * of a valid class file as defined by
1.364 + * <cite>The Java™ Virtual Machine Specification</cite>.
1.365 + *
1.366 + * @param off
1.367 + * The start offset in <tt>b</tt> of the class data
1.368 + *
1.369 + * @param len
1.370 + * The length of the class data
1.371 + *
1.372 + * @return The <tt>Class</tt> object that was created from the specified
1.373 + * class data
1.374 + *
1.375 + * @throws ClassFormatError
1.376 + * If the data did not contain a valid class
1.377 + *
1.378 + * @throws IndexOutOfBoundsException
1.379 + * If either <tt>off</tt> or <tt>len</tt> is negative, or if
1.380 + * <tt>off+len</tt> is greater than <tt>b.length</tt>.
1.381 + *
1.382 + * @throws SecurityException
1.383 + * If an attempt is made to add this class to a package that
1.384 + * contains classes that were signed by a different set of
1.385 + * certificates than this class, or if an attempt is made
1.386 + * to define a class in a package with a fully-qualified name
1.387 + * that starts with "{@code java.}".
1.388 + *
1.389 + * @see #loadClass(String, boolean)
1.390 + * @see #resolveClass(Class)
1.391 + *
1.392 + * @deprecated Replaced by {@link #defineClass(String, byte[], int, int)
1.393 + * defineClass(String, byte[], int, int)}
1.394 + */
1.395 + @Deprecated
1.396 + protected final Class<?> defineClass(byte[] b, int off, int len)
1.397 + throws ClassFormatError
1.398 + {
1.399 + throw new SecurityException();
1.400 + }
1.401 +
1.402 + /**
1.403 + * Converts an array of bytes into an instance of class <tt>Class</tt>.
1.404 + * Before the <tt>Class</tt> can be used it must be resolved.
1.405 + *
1.406 + * <p> This method assigns a default {@link java.security.ProtectionDomain
1.407 + * <tt>ProtectionDomain</tt>} to the newly defined class. The
1.408 + * <tt>ProtectionDomain</tt> is effectively granted the same set of
1.409 + * permissions returned when {@link
1.410 + * java.security.Policy#getPermissions(java.security.CodeSource)
1.411 + * <tt>Policy.getPolicy().getPermissions(new CodeSource(null, null))</tt>}
1.412 + * is invoked. The default domain is created on the first invocation of
1.413 + * {@link #defineClass(String, byte[], int, int) <tt>defineClass</tt>},
1.414 + * and re-used on subsequent invocations.
1.415 + *
1.416 + * <p> To assign a specific <tt>ProtectionDomain</tt> to the class, use
1.417 + * the {@link #defineClass(String, byte[], int, int,
1.418 + * java.security.ProtectionDomain) <tt>defineClass</tt>} method that takes a
1.419 + * <tt>ProtectionDomain</tt> as one of its arguments. </p>
1.420 + *
1.421 + * @param name
1.422 + * The expected <a href="#name">binary name</a> of the class, or
1.423 + * <tt>null</tt> if not known
1.424 + *
1.425 + * @param b
1.426 + * The bytes that make up the class data. The bytes in positions
1.427 + * <tt>off</tt> through <tt>off+len-1</tt> should have the format
1.428 + * of a valid class file as defined by
1.429 + * <cite>The Java™ Virtual Machine Specification</cite>.
1.430 + *
1.431 + * @param off
1.432 + * The start offset in <tt>b</tt> of the class data
1.433 + *
1.434 + * @param len
1.435 + * The length of the class data
1.436 + *
1.437 + * @return The <tt>Class</tt> object that was created from the specified
1.438 + * class data.
1.439 + *
1.440 + * @throws ClassFormatError
1.441 + * If the data did not contain a valid class
1.442 + *
1.443 + * @throws IndexOutOfBoundsException
1.444 + * If either <tt>off</tt> or <tt>len</tt> is negative, or if
1.445 + * <tt>off+len</tt> is greater than <tt>b.length</tt>.
1.446 + *
1.447 + * @throws SecurityException
1.448 + * If an attempt is made to add this class to a package that
1.449 + * contains classes that were signed by a different set of
1.450 + * certificates than this class (which is unsigned), or if
1.451 + * <tt>name</tt> begins with "<tt>java.</tt>".
1.452 + *
1.453 + * @see #loadClass(String, boolean)
1.454 + * @see #resolveClass(Class)
1.455 + * @see java.security.CodeSource
1.456 + * @see java.security.SecureClassLoader
1.457 + *
1.458 + * @since 1.1
1.459 + */
1.460 + protected final Class<?> defineClass(String name, byte[] b, int off, int len)
1.461 + throws ClassFormatError
1.462 + {
1.463 + throw new SecurityException();
1.464 + }
1.465 +
1.466 + /**
1.467 + * Links the specified class. This (misleadingly named) method may be
1.468 + * used by a class loader to link a class. If the class <tt>c</tt> has
1.469 + * already been linked, then this method simply returns. Otherwise, the
1.470 + * class is linked as described in the "Execution" chapter of
1.471 + * <cite>The Java™ Language Specification</cite>.
1.472 + * </p>
1.473 + *
1.474 + * @param c
1.475 + * The class to link
1.476 + *
1.477 + * @throws NullPointerException
1.478 + * If <tt>c</tt> is <tt>null</tt>.
1.479 + *
1.480 + * @see #defineClass(String, byte[], int, int)
1.481 + */
1.482 + protected final void resolveClass(Class<?> c) {
1.483 + resolveClass0(c);
1.484 + }
1.485 +
1.486 + private native void resolveClass0(Class c);
1.487 +
1.488 +
1.489 + /**
1.490 + * Returns the class with the given <a href="#name">binary name</a> if this
1.491 + * loader has been recorded by the Java virtual machine as an initiating
1.492 + * loader of a class with that <a href="#name">binary name</a>. Otherwise
1.493 + * <tt>null</tt> is returned. </p>
1.494 + *
1.495 + * @param name
1.496 + * The <a href="#name">binary name</a> of the class
1.497 + *
1.498 + * @return The <tt>Class</tt> object, or <tt>null</tt> if the class has
1.499 + * not been loaded
1.500 + *
1.501 + * @since 1.1
1.502 + */
1.503 + protected final Class<?> findLoadedClass(String name) {
1.504 + if (!checkName(name))
1.505 + return null;
1.506 + return findLoadedClass0(name);
1.507 + }
1.508 +
1.509 + private native final Class findLoadedClass0(String name);
1.510 +
1.511 + /**
1.512 + * Sets the signers of a class. This should be invoked after defining a
1.513 + * class. </p>
1.514 + *
1.515 + * @param c
1.516 + * The <tt>Class</tt> object
1.517 + *
1.518 + * @param signers
1.519 + * The signers for the class
1.520 + *
1.521 + * @since 1.1
1.522 + */
1.523 + protected final void setSigners(Class<?> c, Object[] signers) {
1.524 + //c.setSigners(signers);
1.525 + throw new UnsupportedOperationException();
1.526 + }
1.527 +
1.528 +
1.529 + // -- Resource --
1.530 +
1.531 + /**
1.532 + * Finds the resource with the given name. A resource is some data
1.533 + * (images, audio, text, etc) that can be accessed by class code in a way
1.534 + * that is independent of the location of the code.
1.535 + *
1.536 + * <p> The name of a resource is a '<tt>/</tt>'-separated path name that
1.537 + * identifies the resource.
1.538 + *
1.539 + * <p> This method will first search the parent class loader for the
1.540 + * resource; if the parent is <tt>null</tt> the path of the class loader
1.541 + * built-in to the virtual machine is searched. That failing, this method
1.542 + * will invoke {@link #findResource(String)} to find the resource. </p>
1.543 + *
1.544 + * @param name
1.545 + * The resource name
1.546 + *
1.547 + * @return A <tt>URL</tt> object for reading the resource, or
1.548 + * <tt>null</tt> if the resource could not be found or the invoker
1.549 + * doesn't have adequate privileges to get the resource.
1.550 + *
1.551 + * @since 1.1
1.552 + */
1.553 + public URL getResource(String name) {
1.554 + URL url;
1.555 + if (parent != null) {
1.556 + url = parent.getResource(name);
1.557 + } else {
1.558 + url = getBootstrapResource(name);
1.559 + }
1.560 + if (url == null) {
1.561 + url = findResource(name);
1.562 + }
1.563 + return url;
1.564 + }
1.565 +
1.566 + /**
1.567 + * Finds all the resources with the given name. A resource is some data
1.568 + * (images, audio, text, etc) that can be accessed by class code in a way
1.569 + * that is independent of the location of the code.
1.570 + *
1.571 + * <p>The name of a resource is a <tt>/</tt>-separated path name that
1.572 + * identifies the resource.
1.573 + *
1.574 + * <p> The search order is described in the documentation for {@link
1.575 + * #getResource(String)}. </p>
1.576 + *
1.577 + * @param name
1.578 + * The resource name
1.579 + *
1.580 + * @return An enumeration of {@link java.net.URL <tt>URL</tt>} objects for
1.581 + * the resource. If no resources could be found, the enumeration
1.582 + * will be empty. Resources that the class loader doesn't have
1.583 + * access to will not be in the enumeration.
1.584 + *
1.585 + * @throws IOException
1.586 + * If I/O errors occur
1.587 + *
1.588 + * @see #findResources(String)
1.589 + *
1.590 + * @since 1.2
1.591 + */
1.592 + public Enumeration<URL> getResources(String name) throws IOException {
1.593 + Enumeration[] tmp = new Enumeration[2];
1.594 + if (parent != null) {
1.595 + tmp[0] = parent.getResources(name);
1.596 + } else {
1.597 + tmp[0] = getBootstrapResources(name);
1.598 + }
1.599 + tmp[1] = findResources(name);
1.600 +
1.601 + return new CompoundEnumeration(tmp);
1.602 + }
1.603 +
1.604 + /**
1.605 + * Finds the resource with the given name. Class loader implementations
1.606 + * should override this method to specify where to find resources. </p>
1.607 + *
1.608 + * @param name
1.609 + * The resource name
1.610 + *
1.611 + * @return A <tt>URL</tt> object for reading the resource, or
1.612 + * <tt>null</tt> if the resource could not be found
1.613 + *
1.614 + * @since 1.2
1.615 + */
1.616 + protected URL findResource(String name) {
1.617 + return null;
1.618 + }
1.619 +
1.620 + /**
1.621 + * Returns an enumeration of {@link java.net.URL <tt>URL</tt>} objects
1.622 + * representing all the resources with the given name. Class loader
1.623 + * implementations should override this method to specify where to load
1.624 + * resources from. </p>
1.625 + *
1.626 + * @param name
1.627 + * The resource name
1.628 + *
1.629 + * @return An enumeration of {@link java.net.URL <tt>URL</tt>} objects for
1.630 + * the resources
1.631 + *
1.632 + * @throws IOException
1.633 + * If I/O errors occur
1.634 + *
1.635 + * @since 1.2
1.636 + */
1.637 + protected Enumeration<URL> findResources(String name) throws IOException {
1.638 + return new CompoundEnumeration(new Enumeration[0]);
1.639 + }
1.640 +
1.641 + // index 0: java.lang.ClassLoader.class
1.642 + // index 1: the immediate caller of index 0.
1.643 + // index 2: the immediate caller of index 1.
1.644 + private static native Class<? extends ClassLoader> getCaller(int index);
1.645 +
1.646 + /**
1.647 + * Registers the caller as parallel capable.</p>
1.648 + * The registration succeeds if and only if all of the following
1.649 + * conditions are met: <br>
1.650 + * 1. no instance of the caller has been created</p>
1.651 + * 2. all of the super classes (except class Object) of the caller are
1.652 + * registered as parallel capable</p>
1.653 + * Note that once a class loader is registered as parallel capable, there
1.654 + * is no way to change it back. </p>
1.655 + *
1.656 + * @return true if the caller is successfully registered as
1.657 + * parallel capable and false if otherwise.
1.658 + *
1.659 + * @since 1.7
1.660 + */
1.661 +// protected static boolean registerAsParallelCapable() {
1.662 +// return false;
1.663 +// }
1.664 +
1.665 + /**
1.666 + * Find a resource of the specified name from the search path used to load
1.667 + * classes. This method locates the resource through the system class
1.668 + * loader (see {@link #getSystemClassLoader()}). </p>
1.669 + *
1.670 + * @param name
1.671 + * The resource name
1.672 + *
1.673 + * @return A {@link java.net.URL <tt>URL</tt>} object for reading the
1.674 + * resource, or <tt>null</tt> if the resource could not be found
1.675 + *
1.676 + * @since 1.1
1.677 + */
1.678 + public static URL getSystemResource(String name) {
1.679 + ClassLoader system = getSystemClassLoader();
1.680 + if (system == null) {
1.681 + return getBootstrapResource(name);
1.682 + }
1.683 + return system.getResource(name);
1.684 + }
1.685 +
1.686 + /**
1.687 + * Finds all resources of the specified name from the search path used to
1.688 + * load classes. The resources thus found are returned as an
1.689 + * {@link java.util.Enumeration <tt>Enumeration</tt>} of {@link
1.690 + * java.net.URL <tt>URL</tt>} objects.
1.691 + *
1.692 + * <p> The search order is described in the documentation for {@link
1.693 + * #getSystemResource(String)}. </p>
1.694 + *
1.695 + * @param name
1.696 + * The resource name
1.697 + *
1.698 + * @return An enumeration of resource {@link java.net.URL <tt>URL</tt>}
1.699 + * objects
1.700 + *
1.701 + * @throws IOException
1.702 + * If I/O errors occur
1.703 +
1.704 + * @since 1.2
1.705 + */
1.706 + public static Enumeration<URL> getSystemResources(String name)
1.707 + throws IOException
1.708 + {
1.709 + ClassLoader system = getSystemClassLoader();
1.710 + if (system == null) {
1.711 + return getBootstrapResources(name);
1.712 + }
1.713 + return system.getResources(name);
1.714 + }
1.715 +
1.716 +
1.717 +
1.718 + /**
1.719 + * Returns an input stream for reading the specified resource.
1.720 + *
1.721 + * <p> The search order is described in the documentation for {@link
1.722 + * #getResource(String)}. </p>
1.723 + *
1.724 + * @param name
1.725 + * The resource name
1.726 + *
1.727 + * @return An input stream for reading the resource, or <tt>null</tt>
1.728 + * if the resource could not be found
1.729 + *
1.730 + * @since 1.1
1.731 + */
1.732 + public InputStream getResourceAsStream(String name) {
1.733 + URL url = getResource(name);
1.734 + try {
1.735 + return url != null ? url.openStream() : null;
1.736 + } catch (IOException e) {
1.737 + return null;
1.738 + }
1.739 + }
1.740 +
1.741 + /**
1.742 + * Open for reading, a resource of the specified name from the search path
1.743 + * used to load classes. This method locates the resource through the
1.744 + * system class loader (see {@link #getSystemClassLoader()}). </p>
1.745 + *
1.746 + * @param name
1.747 + * The resource name
1.748 + *
1.749 + * @return An input stream for reading the resource, or <tt>null</tt>
1.750 + * if the resource could not be found
1.751 + *
1.752 + * @since 1.1
1.753 + */
1.754 + public static InputStream getSystemResourceAsStream(String name) {
1.755 + URL url = getSystemResource(name);
1.756 + try {
1.757 + return url != null ? url.openStream() : null;
1.758 + } catch (IOException e) {
1.759 + return null;
1.760 + }
1.761 + }
1.762 +
1.763 +
1.764 + // -- Hierarchy --
1.765 +
1.766 + /**
1.767 + * Returns the parent class loader for delegation. Some implementations may
1.768 + * use <tt>null</tt> to represent the bootstrap class loader. This method
1.769 + * will return <tt>null</tt> in such implementations if this class loader's
1.770 + * parent is the bootstrap class loader.
1.771 + *
1.772 + * <p> If a security manager is present, and the invoker's class loader is
1.773 + * not <tt>null</tt> and is not an ancestor of this class loader, then this
1.774 + * method invokes the security manager's {@link
1.775 + * SecurityManager#checkPermission(java.security.Permission)
1.776 + * <tt>checkPermission</tt>} method with a {@link
1.777 + * RuntimePermission#RuntimePermission(String)
1.778 + * <tt>RuntimePermission("getClassLoader")</tt>} permission to verify
1.779 + * access to the parent class loader is permitted. If not, a
1.780 + * <tt>SecurityException</tt> will be thrown. </p>
1.781 + *
1.782 + * @return The parent <tt>ClassLoader</tt>
1.783 + *
1.784 + * @throws SecurityException
1.785 + * If a security manager exists and its <tt>checkPermission</tt>
1.786 + * method doesn't allow access to this class loader's parent class
1.787 + * loader.
1.788 + *
1.789 + * @since 1.2
1.790 + */
1.791 + public final ClassLoader getParent() {
1.792 + throw new SecurityException();
1.793 + }
1.794 +
1.795 + /**
1.796 + * Returns the system class loader for delegation. This is the default
1.797 + * delegation parent for new <tt>ClassLoader</tt> instances, and is
1.798 + * typically the class loader used to start the application.
1.799 + *
1.800 + * <p> This method is first invoked early in the runtime's startup
1.801 + * sequence, at which point it creates the system class loader and sets it
1.802 + * as the context class loader of the invoking <tt>Thread</tt>.
1.803 + *
1.804 + * <p> The default system class loader is an implementation-dependent
1.805 + * instance of this class.
1.806 + *
1.807 + * <p> If the system property "<tt>java.system.class.loader</tt>" is defined
1.808 + * when this method is first invoked then the value of that property is
1.809 + * taken to be the name of a class that will be returned as the system
1.810 + * class loader. The class is loaded using the default system class loader
1.811 + * and must define a public constructor that takes a single parameter of
1.812 + * type <tt>ClassLoader</tt> which is used as the delegation parent. An
1.813 + * instance is then created using this constructor with the default system
1.814 + * class loader as the parameter. The resulting class loader is defined
1.815 + * to be the system class loader.
1.816 + *
1.817 + * <p> If a security manager is present, and the invoker's class loader is
1.818 + * not <tt>null</tt> and the invoker's class loader is not the same as or
1.819 + * an ancestor of the system class loader, then this method invokes the
1.820 + * security manager's {@link
1.821 + * SecurityManager#checkPermission(java.security.Permission)
1.822 + * <tt>checkPermission</tt>} method with a {@link
1.823 + * RuntimePermission#RuntimePermission(String)
1.824 + * <tt>RuntimePermission("getClassLoader")</tt>} permission to verify
1.825 + * access to the system class loader. If not, a
1.826 + * <tt>SecurityException</tt> will be thrown. </p>
1.827 + *
1.828 + * @return The system <tt>ClassLoader</tt> for delegation, or
1.829 + * <tt>null</tt> if none
1.830 + *
1.831 + * @throws SecurityException
1.832 + * If a security manager exists and its <tt>checkPermission</tt>
1.833 + * method doesn't allow access to the system class loader.
1.834 + *
1.835 + * @throws IllegalStateException
1.836 + * If invoked recursively during the construction of the class
1.837 + * loader specified by the "<tt>java.system.class.loader</tt>"
1.838 + * property.
1.839 + *
1.840 + * @throws Error
1.841 + * If the system property "<tt>java.system.class.loader</tt>"
1.842 + * is defined but the named class could not be loaded, the
1.843 + * provider class does not define the required constructor, or an
1.844 + * exception is thrown by that constructor when it is invoked. The
1.845 + * underlying cause of the error can be retrieved via the
1.846 + * {@link Throwable#getCause()} method.
1.847 + *
1.848 + * @revised 1.4
1.849 + */
1.850 + public static ClassLoader getSystemClassLoader() {
1.851 + throw new SecurityException();
1.852 + }
1.853 +
1.854 + // Returns true if the specified class loader can be found in this class
1.855 + // loader's delegation chain.
1.856 + boolean isAncestor(ClassLoader cl) {
1.857 + ClassLoader acl = this;
1.858 + do {
1.859 + acl = acl.parent;
1.860 + if (cl == acl) {
1.861 + return true;
1.862 + }
1.863 + } while (acl != null);
1.864 + return false;
1.865 + }
1.866 +
1.867 + private boolean checkName(String name) {
1.868 + throw new UnsupportedOperationException();
1.869 + }
1.870 +
1.871 + private Class findBootstrapClassOrNull(String name) {
1.872 + throw new UnsupportedOperationException();
1.873 + }
1.874 +
1.875 + private static URL getBootstrapResource(String name) {
1.876 + throw new UnsupportedOperationException();
1.877 + }
1.878 +
1.879 + private static Enumeration<URL> getBootstrapResources(String name) {
1.880 + throw new UnsupportedOperationException();
1.881 + }
1.882 +
1.883 + private static class CompoundEnumeration implements Enumeration<URL> {
1.884 + private URL next;
1.885 + private int index;
1.886 + private final Enumeration[] arr;
1.887 +
1.888 + public CompoundEnumeration(Enumeration[] arr) {
1.889 + this.arr = arr;
1.890 + this.index = 0;
1.891 + }
1.892 +
1.893 + public boolean hasMoreElements() {
1.894 + if (next == null) {
1.895 + if (arr[index].hasMoreElements()) {
1.896 + next = (URL) arr[index].nextElement();
1.897 + } else {
1.898 + if (index < arr.length) {
1.899 + index++;
1.900 + return hasMoreElements();
1.901 + }
1.902 + }
1.903 + }
1.904 + return next != null;
1.905 + }
1.906 +
1.907 + public URL nextElement() {
1.908 + if (!hasMoreElements()) {
1.909 + throw new NoSuchElementException();
1.910 + }
1.911 + URL r = next;
1.912 + next = null;
1.913 + return r;
1.914 + }
1.915 +
1.916 + }
1.917 +}