0001 /*
0002 * Copyright 1994-2005 Sun Microsystems, Inc. All Rights Reserved.
0003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004 *
0005 * This code is free software; you can redistribute it and/or modify it
0006 * under the terms of the GNU General Public License version 2 only, as
0007 * published by the Free Software Foundation. Sun designates this
0008 * particular file as subject to the "Classpath" exception as provided
0009 * by Sun in the LICENSE file that accompanied this code.
0010 *
0011 * This code is distributed in the hope that it will be useful, but WITHOUT
0012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0014 * version 2 for more details (a copy is included in the LICENSE file that
0015 * accompanied this code).
0016 *
0017 * You should have received a copy of the GNU General Public License version
0018 * 2 along with this work; if not, write to the Free Software Foundation,
0019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020 *
0021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022 * CA 95054 USA or visit www.sun.com if you need additional information or
0023 * have any questions.
0024 */
0025 package java.lang;
0026
0027 import java.io.InputStream;
0028 import java.io.IOException;
0029 import java.io.File;
0030 import java.lang.reflect.Constructor;
0031 import java.lang.reflect.InvocationTargetException;
0032 import java.net.MalformedURLException;
0033 import java.net.URL;
0034 import java.security.AccessController;
0035 import java.security.AccessControlContext;
0036 import java.security.CodeSource;
0037 import java.security.Policy;
0038 import java.security.PrivilegedAction;
0039 import java.security.PrivilegedActionException;
0040 import java.security.PrivilegedExceptionAction;
0041 import java.security.ProtectionDomain;
0042 import java.util.Enumeration;
0043 import java.util.Hashtable;
0044 import java.util.HashMap;
0045 import java.util.HashSet;
0046 import java.util.Set;
0047 import java.util.Stack;
0048 import java.util.Map;
0049 import java.util.Vector;
0050 import sun.misc.ClassFileTransformer;
0051 import sun.misc.CompoundEnumeration;
0052 import sun.misc.Resource;
0053 import sun.misc.URLClassPath;
0054 import sun.misc.VM;
0055 import sun.reflect.Reflection;
0056 import sun.security.util.SecurityConstants;
0057
0058 /**
0059 * A class loader is an object that is responsible for loading classes. The
0060 * class <tt>ClassLoader</tt> is an abstract class. Given the <a
0061 * href="#name">binary name</a> of a class, a class loader should attempt to
0062 * locate or generate data that constitutes a definition for the class. A
0063 * typical strategy is to transform the name into a file name and then read a
0064 * "class file" of that name from a file system.
0065 *
0066 * <p> Every {@link Class <tt>Class</tt>} object contains a {@link
0067 * Class#getClassLoader() reference} to the <tt>ClassLoader</tt> that defined
0068 * it.
0069 *
0070 * <p> <tt>Class</tt> objects for array classes are not created by class
0071 * loaders, but are created automatically as required by the Java runtime.
0072 * The class loader for an array class, as returned by {@link
0073 * Class#getClassLoader()} is the same as the class loader for its element
0074 * type; if the element type is a primitive type, then the array class has no
0075 * class loader.
0076 *
0077 * <p> Applications implement subclasses of <tt>ClassLoader</tt> in order to
0078 * extend the manner in which the Java virtual machine dynamically loads
0079 * classes.
0080 *
0081 * <p> Class loaders may typically be used by security managers to indicate
0082 * security domains.
0083 *
0084 * <p> The <tt>ClassLoader</tt> class uses a delegation model to search for
0085 * classes and resources. Each instance of <tt>ClassLoader</tt> has an
0086 * associated parent class loader. When requested to find a class or
0087 * resource, a <tt>ClassLoader</tt> instance will delegate the search for the
0088 * class or resource to its parent class loader before attempting to find the
0089 * class or resource itself. The virtual machine's built-in class loader,
0090 * called the "bootstrap class loader", does not itself have a parent but may
0091 * serve as the parent of a <tt>ClassLoader</tt> instance.
0092 *
0093 * <p> Normally, the Java virtual machine loads classes from the local file
0094 * system in a platform-dependent manner. For example, on UNIX systems, the
0095 * virtual machine loads classes from the directory defined by the
0096 * <tt>CLASSPATH</tt> environment variable.
0097 *
0098 * <p> However, some classes may not originate from a file; they may originate
0099 * from other sources, such as the network, or they could be constructed by an
0100 * application. The method {@link #defineClass(String, byte[], int, int)
0101 * <tt>defineClass</tt>} converts an array of bytes into an instance of class
0102 * <tt>Class</tt>. Instances of this newly defined class can be created using
0103 * {@link Class#newInstance <tt>Class.newInstance</tt>}.
0104 *
0105 * <p> The methods and constructors of objects created by a class loader may
0106 * reference other classes. To determine the class(es) referred to, the Java
0107 * virtual machine invokes the {@link #loadClass <tt>loadClass</tt>} method of
0108 * the class loader that originally created the class.
0109 *
0110 * <p> For example, an application could create a network class loader to
0111 * download class files from a server. Sample code might look like:
0112 *
0113 * <blockquote><pre>
0114 * ClassLoader loader = new NetworkClassLoader(host, port);
0115 * Object main = loader.loadClass("Main", true).newInstance();
0116 * . . .
0117 * </pre></blockquote>
0118 *
0119 * <p> The network class loader subclass must define the methods {@link
0120 * #findClass <tt>findClass</tt>} and <tt>loadClassData</tt> to load a class
0121 * from the network. Once it has downloaded the bytes that make up the class,
0122 * it should use the method {@link #defineClass <tt>defineClass</tt>} to
0123 * create a class instance. A sample implementation is:
0124 *
0125 * <blockquote><pre>
0126 * class NetworkClassLoader extends ClassLoader {
0127 * String host;
0128 * int port;
0129 *
0130 * public Class findClass(String name) {
0131 * byte[] b = loadClassData(name);
0132 * return defineClass(name, b, 0, b.length);
0133 * }
0134 *
0135 * private byte[] loadClassData(String name) {
0136 * // load the class data from the connection
0137 * . . .
0138 * }
0139 * }
0140 * </pre></blockquote>
0141 *
0142 * <h4> <a name="name">Binary names</a> </h4>
0143 *
0144 * <p> Any class name provided as a {@link String} parameter to methods in
0145 * <tt>ClassLoader</tt> must be a binary name as defined by the <a
0146 * href="http://java.sun.com/docs/books/jls/">Java Language Specification</a>.
0147 *
0148 * <p> Examples of valid class names include:
0149 * <blockquote><pre>
0150 * "java.lang.String"
0151 * "javax.swing.JSpinner$DefaultEditor"
0152 * "java.security.KeyStore$Builder$FileBuilder$1"
0153 * "java.net.URLClassLoader$3$1"
0154 * </pre></blockquote>
0155 *
0156 * @version 1.195, 05/05/07
0157 * @see #resolveClass(Class)
0158 * @since 1.0
0159 */
0160 public abstract class ClassLoader {
0161
0162 private static native void registerNatives();
0163
0164 static {
0165 registerNatives();
0166 }
0167
0168 // If initialization succeed this is set to true and security checks will
0169 // succeed. Otherwise the object is not initialized and the object is
0170 // useless.
0171 private boolean initialized = false;
0172
0173 // The parent class loader for delegation
0174 private ClassLoader parent;
0175
0176 // Hashtable that maps packages to certs
0177 private Hashtable package2certs = new Hashtable(11);
0178
0179 // Shared among all packages with unsigned classes
0180 java.security.cert.Certificate[] nocerts;
0181
0182 // The classes loaded by this class loader. The only purpose of this table
0183 // is to keep the classes from being GC'ed until the loader is GC'ed.
0184 private Vector classes = new Vector();
0185
0186 // The initiating protection domains for all classes loaded by this loader
0187 private Set domains = new HashSet();
0188
0189 // Invoked by the VM to record every loaded class with this loader.
0190 void addClass(Class c) {
0191 classes.addElement(c);
0192 }
0193
0194 // The packages defined in this class loader. Each package name is mapped
0195 // to its corresponding Package object.
0196 private HashMap packages = new HashMap();
0197
0198 /**
0199 * Creates a new class loader using the specified parent class loader for
0200 * delegation.
0201 *
0202 * <p> If there is a security manager, its {@link
0203 * SecurityManager#checkCreateClassLoader()
0204 * <tt>checkCreateClassLoader</tt>} method is invoked. This may result in
0205 * a security exception. </p>
0206 *
0207 * @param parent
0208 * The parent class loader
0209 *
0210 * @throws SecurityException
0211 * If a security manager exists and its
0212 * <tt>checkCreateClassLoader</tt> method doesn't allow creation
0213 * of a new class loader.
0214 *
0215 * @since 1.2
0216 */
0217 protected ClassLoader(ClassLoader parent) {
0218 SecurityManager security = System.getSecurityManager();
0219 if (security != null) {
0220 security.checkCreateClassLoader();
0221 }
0222 this .parent = parent;
0223 initialized = true;
0224 }
0225
0226 /**
0227 * Creates a new class loader using the <tt>ClassLoader</tt> returned by
0228 * the method {@link #getSystemClassLoader()
0229 * <tt>getSystemClassLoader()</tt>} as the parent class loader.
0230 *
0231 * <p> If there is a security manager, its {@link
0232 * SecurityManager#checkCreateClassLoader()
0233 * <tt>checkCreateClassLoader</tt>} method is invoked. This may result in
0234 * a security exception. </p>
0235 *
0236 * @throws SecurityException
0237 * If a security manager exists and its
0238 * <tt>checkCreateClassLoader</tt> method doesn't allow creation
0239 * of a new class loader.
0240 */
0241 protected ClassLoader() {
0242 SecurityManager security = System.getSecurityManager();
0243 if (security != null) {
0244 security.checkCreateClassLoader();
0245 }
0246 this .parent = getSystemClassLoader();
0247 initialized = true;
0248 }
0249
0250 // -- Class --
0251
0252 /**
0253 * Loads the class with the specified <a href="#name">binary name</a>.
0254 * This method searches for classes in the same manner as the {@link
0255 * #loadClass(String, boolean)} method. It is invoked by the Java virtual
0256 * machine to resolve class references. Invoking this method is equivalent
0257 * to invoking {@link #loadClass(String, boolean) <tt>loadClass(name,
0258 * false)</tt>}. </p>
0259 *
0260 * @param name
0261 * The <a href="#name">binary name</a> of the class
0262 *
0263 * @return The resulting <tt>Class</tt> object
0264 *
0265 * @throws ClassNotFoundException
0266 * If the class was not found
0267 */
0268 public Class<?> loadClass(String name)
0269 throws ClassNotFoundException {
0270 return loadClass(name, false);
0271 }
0272
0273 /**
0274 * Loads the class with the specified <a href="#name">binary name</a>. The
0275 * default implementation of this method searches for classes in the
0276 * following order:
0277 *
0278 * <p><ol>
0279 *
0280 * <li><p> Invoke {@link #findLoadedClass(String)} to check if the class
0281 * has already been loaded. </p></li>
0282 *
0283 * <li><p> Invoke the {@link #loadClass(String) <tt>loadClass</tt>} method
0284 * on the parent class loader. If the parent is <tt>null</tt> the class
0285 * loader built-in to the virtual machine is used, instead. </p></li>
0286 *
0287 * <li><p> Invoke the {@link #findClass(String)} method to find the
0288 * class. </p></li>
0289 *
0290 * </ol>
0291 *
0292 * <p> If the class was found using the above steps, and the
0293 * <tt>resolve</tt> flag is true, this method will then invoke the {@link
0294 * #resolveClass(Class)} method on the resulting <tt>Class</tt> object.
0295 *
0296 * <p> Subclasses of <tt>ClassLoader</tt> are encouraged to override {@link
0297 * #findClass(String)}, rather than this method. </p>
0298 *
0299 * @param name
0300 * The <a href="#name">binary name</a> of the class
0301 *
0302 * @param resolve
0303 * If <tt>true</tt> then resolve the class
0304 *
0305 * @return The resulting <tt>Class</tt> object
0306 *
0307 * @throws ClassNotFoundException
0308 * If the class could not be found
0309 */
0310 protected synchronized Class<?> loadClass(String name,
0311 boolean resolve) throws ClassNotFoundException {
0312 // First, check if the class has already been loaded
0313 Class c = findLoadedClass(name);
0314 if (c == null) {
0315 try {
0316 if (parent != null) {
0317 c = parent.loadClass(name, false);
0318 } else {
0319 c = findBootstrapClass0(name);
0320 }
0321 } catch (ClassNotFoundException e) {
0322 // If still not found, then invoke findClass in order
0323 // to find the class.
0324 c = findClass(name);
0325 }
0326 }
0327 if (resolve) {
0328 resolveClass(c);
0329 }
0330 return c;
0331 }
0332
0333 // This method is invoked by the virtual machine to load a class.
0334 private synchronized Class loadClassInternal(String name)
0335 throws ClassNotFoundException {
0336 return loadClass(name);
0337 }
0338
0339 private void checkPackageAccess(Class cls, ProtectionDomain pd) {
0340 final SecurityManager sm = System.getSecurityManager();
0341 if (sm != null) {
0342 final String name = cls.getName();
0343 final int i = name.lastIndexOf('.');
0344 if (i != -1) {
0345 AccessController.doPrivileged(new PrivilegedAction() {
0346 public Object run() {
0347 sm.checkPackageAccess(name.substring(0, i));
0348 return null;
0349 }
0350 }, new AccessControlContext(
0351 new ProtectionDomain[] { pd }));
0352 }
0353 }
0354 domains.add(pd);
0355 }
0356
0357 /**
0358 * Finds the class with the specified <a href="#name">binary name</a>.
0359 * This method should be overridden by class loader implementations that
0360 * follow the delegation model for loading classes, and will be invoked by
0361 * the {@link #loadClass <tt>loadClass</tt>} method after checking the
0362 * parent class loader for the requested class. The default implementation
0363 * throws a <tt>ClassNotFoundException</tt>. </p>
0364 *
0365 * @param name
0366 * The <a href="#name">binary name</a> of the class
0367 *
0368 * @return The resulting <tt>Class</tt> object
0369 *
0370 * @throws ClassNotFoundException
0371 * If the class could not be found
0372 *
0373 * @since 1.2
0374 */
0375 protected Class<?> findClass(String name)
0376 throws ClassNotFoundException {
0377 throw new ClassNotFoundException(name);
0378 }
0379
0380 /**
0381 * Converts an array of bytes into an instance of class <tt>Class</tt>.
0382 * Before the <tt>Class</tt> can be used it must be resolved. This method
0383 * is deprecated in favor of the version that takes a <a
0384 * href="#name">binary name</a> as its first argument, and is more secure.
0385 *
0386 * @param b
0387 * The bytes that make up the class data. The bytes in positions
0388 * <tt>off</tt> through <tt>off+len-1</tt> should have the format
0389 * of a valid class file as defined by the <a
0390 * href="http://java.sun.com/docs/books/vmspec/">Java Virtual
0391 * Machine Specification</a>.
0392 *
0393 * @param off
0394 * The start offset in <tt>b</tt> of the class data
0395 *
0396 * @param len
0397 * The length of the class data
0398 *
0399 * @return The <tt>Class</tt> object that was created from the specified
0400 * class data
0401 *
0402 * @throws ClassFormatError
0403 * If the data did not contain a valid class
0404 *
0405 * @throws IndexOutOfBoundsException
0406 * If either <tt>off</tt> or <tt>len</tt> is negative, or if
0407 * <tt>off+len</tt> is greater than <tt>b.length</tt>.
0408 *
0409 * @see #loadClass(String, boolean)
0410 * @see #resolveClass(Class)
0411 *
0412 * @deprecated Replaced by {@link #defineClass(String, byte[], int, int)
0413 * defineClass(String, byte[], int, int)}
0414 */
0415 @Deprecated
0416 protected final Class<?> defineClass(byte[] b, int off, int len)
0417 throws ClassFormatError {
0418 return defineClass(null, b, off, len, null);
0419 }
0420
0421 /**
0422 * Converts an array of bytes into an instance of class <tt>Class</tt>.
0423 * Before the <tt>Class</tt> can be used it must be resolved.
0424 *
0425 * <p> This method assigns a default {@link java.security.ProtectionDomain
0426 * <tt>ProtectionDomain</tt>} to the newly defined class. The
0427 * <tt>ProtectionDomain</tt> is effectively granted the same set of
0428 * permissions returned when {@link
0429 * java.security.Policy#getPermissions(java.security.CodeSource)
0430 * <tt>Policy.getPolicy().getPermissions(new CodeSource(null, null))</tt>}
0431 * is invoked. The default domain is created on the first invocation of
0432 * {@link #defineClass(String, byte[], int, int) <tt>defineClass</tt>},
0433 * and re-used on subsequent invocations.
0434 *
0435 * <p> To assign a specific <tt>ProtectionDomain</tt> to the class, use
0436 * the {@link #defineClass(String, byte[], int, int,
0437 * java.security.ProtectionDomain) <tt>defineClass</tt>} method that takes a
0438 * <tt>ProtectionDomain</tt> as one of its arguments. </p>
0439 *
0440 * @param name
0441 * The expected <a href="#name">binary name</a> of the class, or
0442 * <tt>null</tt> if not known
0443 *
0444 * @param b
0445 * The bytes that make up the class data. The bytes in positions
0446 * <tt>off</tt> through <tt>off+len-1</tt> should have the format
0447 * of a valid class file as defined by the <a
0448 * href="http://java.sun.com/docs/books/vmspec/">Java Virtual
0449 * Machine Specification</a>.
0450 *
0451 * @param off
0452 * The start offset in <tt>b</tt> of the class data
0453 *
0454 * @param len
0455 * The length of the class data
0456 *
0457 * @return The <tt>Class</tt> object that was created from the specified
0458 * class data.
0459 *
0460 * @throws ClassFormatError
0461 * If the data did not contain a valid class
0462 *
0463 * @throws IndexOutOfBoundsException
0464 * If either <tt>off</tt> or <tt>len</tt> is negative, or if
0465 * <tt>off+len</tt> is greater than <tt>b.length</tt>.
0466 *
0467 * @throws SecurityException
0468 * If an attempt is made to add this class to a package that
0469 * contains classes that were signed by a different set of
0470 * certificates than this class (which is unsigned), or if
0471 * <tt>name</tt> begins with "<tt>java.</tt>".
0472 *
0473 * @see #loadClass(String, boolean)
0474 * @see #resolveClass(Class)
0475 * @see java.security.CodeSource
0476 * @see java.security.SecureClassLoader
0477 *
0478 * @since 1.1
0479 */
0480 protected final Class<?> defineClass(String name, byte[] b,
0481 int off, int len) throws ClassFormatError {
0482 return defineClass(name, b, off, len, null);
0483 }
0484
0485 /* Determine protection domain, and check that:
0486 - not define java.* class,
0487 - signer of this class matches signers for the rest of the classes in package.
0488 */
0489 private ProtectionDomain preDefineClass(String name,
0490 ProtectionDomain protectionDomain) {
0491 if (!checkName(name))
0492 throw new NoClassDefFoundError("IllegalName: " + name);
0493
0494 if ((name != null) && name.startsWith("java.")) {
0495 throw new SecurityException("Prohibited package name: "
0496 + name.substring(0, name.lastIndexOf('.')));
0497 }
0498 if (protectionDomain == null) {
0499 protectionDomain = getDefaultDomain();
0500 }
0501
0502 if (name != null)
0503 checkCerts(name, protectionDomain.getCodeSource());
0504
0505 return protectionDomain;
0506 }
0507
0508 private String defineClassSourceLocation(
0509 ProtectionDomain protectionDomain) {
0510 CodeSource cs = protectionDomain.getCodeSource();
0511 String source = null;
0512 if (cs != null && cs.getLocation() != null) {
0513 source = cs.getLocation().toString();
0514 }
0515 return source;
0516 }
0517
0518 private Class defineTransformedClass(String name, byte[] b,
0519 int off, int len, ProtectionDomain protectionDomain,
0520 ClassFormatError cfe, String source)
0521 throws ClassFormatError {
0522 // Class format error - try to transform the bytecode and
0523 // define the class again
0524 //
0525 Object[] transformers = ClassFileTransformer.getTransformers();
0526 Class c = null;
0527
0528 for (int i = 0; transformers != null && i < transformers.length; i++) {
0529 try {
0530 // Transform byte code using transformer
0531 byte[] tb = ((ClassFileTransformer) transformers[i])
0532 .transform(b, off, len);
0533 c = defineClass1(name, tb, 0, tb.length,
0534 protectionDomain, source);
0535 break;
0536 } catch (ClassFormatError cfe2) {
0537 // If ClassFormatError occurs, try next transformer
0538 }
0539 }
0540
0541 // Rethrow original ClassFormatError if unable to transform
0542 // bytecode to well-formed
0543 //
0544 if (c == null)
0545 throw cfe;
0546
0547 return c;
0548 }
0549
0550 private void postDefineClass(Class c,
0551 ProtectionDomain protectionDomain) {
0552 if (protectionDomain.getCodeSource() != null) {
0553 java.security.cert.Certificate certs[] = protectionDomain
0554 .getCodeSource().getCertificates();
0555 if (certs != null)
0556 setSigners(c, certs);
0557 }
0558 }
0559
0560 /**
0561 * Converts an array of bytes into an instance of class <tt>Class</tt>,
0562 * with an optional <tt>ProtectionDomain</tt>. If the domain is
0563 * <tt>null</tt>, then a default domain will be assigned to the class as
0564 * specified in the documentation for {@link #defineClass(String, byte[],
0565 * int, int)}. Before the class can be used it must be resolved.
0566 *
0567 * <p> The first class defined in a package determines the exact set of
0568 * certificates that all subsequent classes defined in that package must
0569 * contain. The set of certificates for a class is obtained from the
0570 * {@link java.security.CodeSource <tt>CodeSource</tt>} within the
0571 * <tt>ProtectionDomain</tt> of the class. Any classes added to that
0572 * package must contain the same set of certificates or a
0573 * <tt>SecurityException</tt> will be thrown. Note that if
0574 * <tt>name</tt> is <tt>null</tt>, this check is not performed.
0575 * You should always pass in the <a href="#name">binary name</a> of the
0576 * class you are defining as well as the bytes. This ensures that the
0577 * class you are defining is indeed the class you think it is.
0578 *
0579 * <p> The specified <tt>name</tt> cannot begin with "<tt>java.</tt>", since
0580 * all classes in the "<tt>java.*</tt> packages can only be defined by the
0581 * bootstrap class loader. If <tt>name</tt> is not <tt>null</tt>, it
0582 * must be equal to the <a href="#name">binary name</a> of the class
0583 * specified by the byte array "<tt>b</tt>", otherwise a {@link
0584 * <tt>NoClassDefFoundError</tt>} will be thrown. </p>
0585 *
0586 * @param name
0587 * The expected <a href="#name">binary name</a> of the class, or
0588 * <tt>null</tt> if not known
0589 *
0590 * @param b
0591 * The bytes that make up the class data. The bytes in positions
0592 * <tt>off</tt> through <tt>off+len-1</tt> should have the format
0593 * of a valid class file as defined by the <a
0594 * href="http://java.sun.com/docs/books/vmspec/">Java Virtual
0595 * Machine Specification</a>.
0596 *
0597 * @param off
0598 * The start offset in <tt>b</tt> of the class data
0599 *
0600 * @param len
0601 * The length of the class data
0602 *
0603 * @param protectionDomain
0604 * The ProtectionDomain of the class
0605 *
0606 * @return The <tt>Class</tt> object created from the data,
0607 * and optional <tt>ProtectionDomain</tt>.
0608 *
0609 * @throws ClassFormatError
0610 * If the data did not contain a valid class
0611 *
0612 * @throws NoClassDefFoundError
0613 * If <tt>name</tt> is not equal to the <a href="#name">binary
0614 * name</a> of the class specified by <tt>b</tt>
0615 *
0616 * @throws IndexOutOfBoundsException
0617 * If either <tt>off</tt> or <tt>len</tt> is negative, or if
0618 * <tt>off+len</tt> is greater than <tt>b.length</tt>.
0619 *
0620 * @throws SecurityException
0621 * If an attempt is made to add this class to a package that
0622 * contains classes that were signed by a different set of
0623 * certificates than this class, or if <tt>name</tt> begins with
0624 * "<tt>java.</tt>".
0625 */
0626 protected final Class<?> defineClass(String name, byte[] b,
0627 int off, int len, ProtectionDomain protectionDomain)
0628 throws ClassFormatError {
0629 check();
0630 protectionDomain = preDefineClass(name, protectionDomain);
0631
0632 Class c = null;
0633 String source = defineClassSourceLocation(protectionDomain);
0634
0635 try {
0636 c = defineClass1(name, b, off, len, protectionDomain,
0637 source);
0638 } catch (ClassFormatError cfe) {
0639 c = defineTransformedClass(name, b, off, len,
0640 protectionDomain, cfe, source);
0641 }
0642
0643 postDefineClass(c, protectionDomain);
0644 return c;
0645 }
0646
0647 /**
0648 * Converts a {@link java.nio.ByteBuffer <tt>ByteBuffer</tt>}
0649 * into an instance of class <tt>Class</tt>,
0650 * with an optional <tt>ProtectionDomain</tt>. If the domain is
0651 * <tt>null</tt>, then a default domain will be assigned to the class as
0652 * specified in the documentation for {@link #defineClass(String, byte[],
0653 * int, int)}. Before the class can be used it must be resolved.
0654 *
0655 * <p>The rules about the first class defined in a package determining the set of
0656 * certificates for the package, and the restrictions on class names are identical
0657 * to those specified in the documentation for {@link #defineClass(String, byte[],
0658 * int, int, ProtectionDomain)}.
0659 *
0660 * <p> An invocation of this method of the form
0661 * <i>cl</i><tt>.defineClass(</tt><i>name</i><tt>,</tt>
0662 * <i>bBuffer</i><tt>,</tt> <i>pd</i><tt>)</tt> yields exactly the same
0663 * result as the statements
0664 *
0665 * <blockquote><tt>
0666 * ...<br>
0667 * byte[] temp = new byte[</tt><i>bBuffer</i><tt>.{@link java.nio.ByteBuffer#remaining
0668 * remaining}()];<br>
0669 * </tt><i>bBuffer</i><tt>.{@link java.nio.ByteBuffer#get(byte[])
0670 * get}(temp);<br>
0671 * return {@link #defineClass(String, byte[], int, int, ProtectionDomain)
0672 * </tt><i>cl</i><tt>.defineClass}(</tt><i>name</i><tt>, temp, 0, temp.length, </tt><i>pd</i><tt>);<br>
0673 * </tt></blockquote>
0674 *
0675 * @param name
0676 * The expected <a href="#name">binary name</a. of the class, or
0677 * <tt>null</tt> if not known
0678 *
0679 * @param b
0680 * The bytes that make up the class data. The bytes from positions
0681 * <tt>b.position()</tt> through <tt>b.position() + b.limit() -1 </tt>
0682 * should have the format of a valid class file as defined by the <a
0683 * href="http://java.sun.com/docs/books/vmspec/">Java Virtual
0684 * Machine Specification</a>.
0685 *
0686 * @param protectionDomain
0687 * The ProtectionDomain of the class, or <tt>null</tt>.
0688 *
0689 * @return The <tt>Class</tt> object created from the data,
0690 * and optional <tt>ProtectionDomain</tt>.
0691 *
0692 * @throws ClassFormatError
0693 * If the data did not contain a valid class.
0694 *
0695 * @throws NoClassDefFoundError
0696 * If <tt>name</tt> is not equal to the <a href="#name">binary
0697 * name</a> of the class specified by <tt>b</tt>
0698 *
0699 * @throws SecurityException
0700 * If an attempt is made to add this class to a package that
0701 * contains classes that were signed by a different set of
0702 * certificates than this class, or if <tt>name</tt> begins with
0703 * "<tt>java.</tt>".
0704 *
0705 * @see #defineClass(String, byte[], int, int, ProtectionDomain)
0706 *
0707 * @since 1.5
0708 */
0709 protected final Class<?> defineClass(String name,
0710 java.nio.ByteBuffer b, ProtectionDomain protectionDomain)
0711 throws ClassFormatError {
0712 check();
0713
0714 int len = b.remaining();
0715
0716 // Use byte[] if not a direct ByteBufer:
0717 if (!b.isDirect()) {
0718 if (b.hasArray()) {
0719 return defineClass(name, b.array(), b.position()
0720 + b.arrayOffset(), len, protectionDomain);
0721 } else {
0722 // no array, or read-only array
0723 byte[] tb = new byte[len];
0724 b.get(tb); // get bytes out of byte buffer.
0725 return defineClass(name, tb, 0, len, protectionDomain);
0726 }
0727 }
0728
0729 protectionDomain = preDefineClass(name, protectionDomain);
0730
0731 Class c = null;
0732 String source = defineClassSourceLocation(protectionDomain);
0733
0734 try {
0735 c = defineClass2(name, b, b.position(), len,
0736 protectionDomain, source);
0737 } catch (ClassFormatError cfe) {
0738 byte[] tb = new byte[len];
0739 b.get(tb); // get bytes out of byte buffer.
0740 c = defineTransformedClass(name, tb, 0, len,
0741 protectionDomain, cfe, source);
0742 }
0743
0744 postDefineClass(c, protectionDomain);
0745 return c;
0746 }
0747
0748 private native Class defineClass0(String name, byte[] b, int off,
0749 int len, ProtectionDomain pd);
0750
0751 private native Class defineClass1(String name, byte[] b, int off,
0752 int len, ProtectionDomain pd, String source);
0753
0754 private native Class defineClass2(String name,
0755 java.nio.ByteBuffer b, int off, int len,
0756 ProtectionDomain pd, String source);
0757
0758 // true if the name is null or has the potential to be a valid binary name
0759 private boolean checkName(String name) {
0760 if ((name == null) || (name.length() == 0))
0761 return true;
0762 if ((name.indexOf('/') != -1)
0763 || (!VM.allowArraySyntax() && (name.charAt(0) == '[')))
0764 return false;
0765 return true;
0766 }
0767
0768 private synchronized void checkCerts(String name, CodeSource cs) {
0769 int i = name.lastIndexOf('.');
0770 String pname = (i == -1) ? "" : name.substring(0, i);
0771 java.security.cert.Certificate[] pcerts = (java.security.cert.Certificate[]) package2certs
0772 .get(pname);
0773 if (pcerts == null) {
0774 // first class in this package gets to define which
0775 // certificates must be the same for all other classes
0776 // in this package
0777 if (cs != null) {
0778 pcerts = cs.getCertificates();
0779 }
0780 if (pcerts == null) {
0781 if (nocerts == null)
0782 nocerts = new java.security.cert.Certificate[0];
0783 pcerts = nocerts;
0784 }
0785 package2certs.put(pname, pcerts);
0786 } else {
0787 java.security.cert.Certificate[] certs = null;
0788 if (cs != null) {
0789 certs = cs.getCertificates();
0790 }
0791
0792 if (!compareCerts(pcerts, certs)) {
0793 throw new SecurityException(
0794 "class \""
0795 + name
0796 + "\"'s signer information does not match signer information of other classes in the same package");
0797 }
0798 }
0799 }
0800
0801 /**
0802 * check to make sure the certs for the new class (certs) are the same as
0803 * the certs for the first class inserted in the package (pcerts)
0804 */
0805 private boolean compareCerts(
0806 java.security.cert.Certificate[] pcerts,
0807 java.security.cert.Certificate[] certs) {
0808 // certs can be null, indicating no certs.
0809 if ((certs == null) || (certs.length == 0)) {
0810 return pcerts.length == 0;
0811 }
0812
0813 // the length must be the same at this point
0814 if (certs.length != pcerts.length)
0815 return false;
0816
0817 // go through and make sure all the certs in one array
0818 // are in the other and vice-versa.
0819 boolean match;
0820 for (int i = 0; i < certs.length; i++) {
0821 match = false;
0822 for (int j = 0; j < pcerts.length; j++) {
0823 if (certs[i].equals(pcerts[j])) {
0824 match = true;
0825 break;
0826 }
0827 }
0828 if (!match)
0829 return false;
0830 }
0831
0832 // now do the same for pcerts
0833 for (int i = 0; i < pcerts.length; i++) {
0834 match = false;
0835 for (int j = 0; j < certs.length; j++) {
0836 if (pcerts[i].equals(certs[j])) {
0837 match = true;
0838 break;
0839 }
0840 }
0841 if (!match)
0842 return false;
0843 }
0844
0845 return true;
0846 }
0847
0848 /**
0849 * Links the specified class. This (misleadingly named) method may be
0850 * used by a class loader to link a class. If the class <tt>c</tt> has
0851 * already been linked, then this method simply returns. Otherwise, the
0852 * class is linked as described in the "Execution" chapter of the <a
0853 * href="http://java.sun.com/docs/books/jls/">Java Language
0854 * Specification</a>.
0855 * </p>
0856 *
0857 * @param c
0858 * The class to link
0859 *
0860 * @throws NullPointerException
0861 * If <tt>c</tt> is <tt>null</tt>.
0862 *
0863 * @see #defineClass(String, byte[], int, int)
0864 */
0865 protected final void resolveClass(Class<?> c) {
0866 check();
0867 resolveClass0(c);
0868 }
0869
0870 private native void resolveClass0(Class c);
0871
0872 /**
0873 * Finds a class with the specified <a href="#name">binary name</a>,
0874 * loading it if necessary.
0875 *
0876 * <p> This method loads the class through the system class loader (see
0877 * {@link #getSystemClassLoader()}). The <tt>Class</tt> object returned
0878 * might have more than one <tt>ClassLoader</tt> associated with it.
0879 * Subclasses of <tt>ClassLoader</tt> need not usually invoke this method,
0880 * because most class loaders need to override just {@link
0881 * #findClass(String)}. </p>
0882 *
0883 * @param name
0884 * The <a href="#name">binary name</a> of the class
0885 *
0886 * @return The <tt>Class</tt> object for the specified <tt>name</tt>
0887 *
0888 * @throws ClassNotFoundException
0889 * If the class could not be found
0890 *
0891 * @see #ClassLoader(ClassLoader)
0892 * @see #getParent()
0893 */
0894 protected final Class<?> findSystemClass(String name)
0895 throws ClassNotFoundException {
0896 check();
0897 ClassLoader system = getSystemClassLoader();
0898 if (system == null) {
0899 if (!checkName(name))
0900 throw new ClassNotFoundException(name);
0901 return findBootstrapClass(name);
0902 }
0903 return system.loadClass(name);
0904 }
0905
0906 private Class findBootstrapClass0(String name)
0907 throws ClassNotFoundException {
0908 check();
0909 if (!checkName(name))
0910 throw new ClassNotFoundException(name);
0911 return findBootstrapClass(name);
0912 }
0913
0914 private native Class findBootstrapClass(String name)
0915 throws ClassNotFoundException;
0916
0917 // Check to make sure the class loader has been initialized.
0918 private void check() {
0919 if (!initialized) {
0920 throw new SecurityException(
0921 "ClassLoader object not initialized");
0922 }
0923 }
0924
0925 /**
0926 * Returns the class with the given <a href="#name">binary name</a> if this
0927 * loader has been recorded by the Java virtual machine as an initiating
0928 * loader of a class with that <a href="#name">binary name</a>. Otherwise
0929 * <tt>null</tt> is returned. </p>
0930 *
0931 * @param name
0932 * The <a href="#name">binary name</a> of the class
0933 *
0934 * @return The <tt>Class</tt> object, or <tt>null</tt> if the class has
0935 * not been loaded
0936 *
0937 * @since 1.1
0938 */
0939 protected final Class<?> findLoadedClass(String name) {
0940 check();
0941 if (!checkName(name))
0942 return null;
0943 return findLoadedClass0(name);
0944 }
0945
0946 private native final Class findLoadedClass0(String name);
0947
0948 /**
0949 * Sets the signers of a class. This should be invoked after defining a
0950 * class. </p>
0951 *
0952 * @param c
0953 * The <tt>Class</tt> object
0954 *
0955 * @param signers
0956 * The signers for the class
0957 *
0958 * @since 1.1
0959 */
0960 protected final void setSigners(Class<?> c, Object[] signers) {
0961 check();
0962 c.setSigners(signers);
0963 }
0964
0965 // -- Resource --
0966
0967 /**
0968 * Finds the resource with the given name. A resource is some data
0969 * (images, audio, text, etc) that can be accessed by class code in a way
0970 * that is independent of the location of the code.
0971 *
0972 * <p> The name of a resource is a '<tt>/</tt>'-separated path name that
0973 * identifies the resource.
0974 *
0975 * <p> This method will first search the parent class loader for the
0976 * resource; if the parent is <tt>null</tt> the path of the class loader
0977 * built-in to the virtual machine is searched. That failing, this method
0978 * will invoke {@link #findResource(String)} to find the resource. </p>
0979 *
0980 * @param name
0981 * The resource name
0982 *
0983 * @return A <tt>URL</tt> object for reading the resource, or
0984 * <tt>null</tt> if the resource could not be found or the invoker
0985 * doesn't have adequate privileges to get the resource.
0986 *
0987 * @since 1.1
0988 */
0989 public URL getResource(String name) {
0990 URL url;
0991 if (parent != null) {
0992 url = parent.getResource(name);
0993 } else {
0994 url = getBootstrapResource(name);
0995 }
0996 if (url == null) {
0997 url = findResource(name);
0998 }
0999 return url;
1000 }
1001
1002 /**
1003 * Finds all the resources with the given name. A resource is some data
1004 * (images, audio, text, etc) that can be accessed by class code in a way
1005 * that is independent of the location of the code.
1006 *
1007 * <p>The name of a resource is a <tt>/</tt>-separated path name that
1008 * identifies the resource.
1009 *
1010 * <p> The search order is described in the documentation for {@link
1011 * #getResource(String)}. </p>
1012 *
1013 * @param name
1014 * The resource name
1015 *
1016 * @return An enumeration of {@link java.net.URL <tt>URL</tt>} objects for
1017 * the resource. If no resources could be found, the enumeration
1018 * will be empty. Resources that the class loader doesn't have
1019 * access to will not be in the enumeration.
1020 *
1021 * @throws IOException
1022 * If I/O errors occur
1023 *
1024 * @see #findResources(String)
1025 *
1026 * @since 1.2
1027 */
1028 public Enumeration<URL> getResources(String name)
1029 throws IOException {
1030 Enumeration[] tmp = new Enumeration[2];
1031 if (parent != null) {
1032 tmp[0] = parent.getResources(name);
1033 } else {
1034 tmp[0] = getBootstrapResources(name);
1035 }
1036 tmp[1] = findResources(name);
1037
1038 return new CompoundEnumeration(tmp);
1039 }
1040
1041 /**
1042 * Finds the resource with the given name. Class loader implementations
1043 * should override this method to specify where to find resources. </p>
1044 *
1045 * @param name
1046 * The resource name
1047 *
1048 * @return A <tt>URL</tt> object for reading the resource, or
1049 * <tt>null</tt> if the resource could not be found
1050 *
1051 * @since 1.2
1052 */
1053 protected URL findResource(String name) {
1054 return null;
1055 }
1056
1057 /**
1058 * Returns an enumeration of {@link java.net.URL <tt>URL</tt>} objects
1059 * representing all the resources with the given name. Class loader
1060 * implementations should override this method to specify where to load
1061 * resources from. </p>
1062 *
1063 * @param name
1064 * The resource name
1065 *
1066 * @return An enumeration of {@link java.net.URL <tt>URL</tt>} objects for
1067 * the resources
1068 *
1069 * @throws IOException
1070 * If I/O errors occur
1071 *
1072 * @since 1.2
1073 */
1074 protected Enumeration<URL> findResources(String name)
1075 throws IOException {
1076 return new CompoundEnumeration(new Enumeration[0]);
1077 }
1078
1079 /**
1080 * Find a resource of the specified name from the search path used to load
1081 * classes. This method locates the resource through the system class
1082 * loader (see {@link #getSystemClassLoader()}). </p>
1083 *
1084 * @param name
1085 * The resource name
1086 *
1087 * @return A {@link java.net.URL <tt>URL</tt>} object for reading the
1088 * resource, or <tt>null</tt> if the resource could not be found
1089 *
1090 * @since 1.1
1091 */
1092 public static URL getSystemResource(String name) {
1093 ClassLoader system = getSystemClassLoader();
1094 if (system == null) {
1095 return getBootstrapResource(name);
1096 }
1097 return system.getResource(name);
1098 }
1099
1100 /**
1101 * Finds all resources of the specified name from the search path used to
1102 * load classes. The resources thus found are returned as an
1103 * {@link java.util.Enumeration <tt>Enumeration</tt>} of {@link
1104 * java.net.URL <tt>URL</tt>} objects.
1105 *
1106 * <p> The search order is described in the documentation for {@link
1107 * #getSystemResource(String)}. </p>
1108 *
1109 * @param name
1110 * The resource name
1111 *
1112 * @return An enumeration of resource {@link java.net.URL <tt>URL</tt>}
1113 * objects
1114 *
1115 * @throws IOException
1116 * If I/O errors occur
1117
1118 * @since 1.2
1119 */
1120 public static Enumeration<URL> getSystemResources(String name)
1121 throws IOException {
1122 ClassLoader system = getSystemClassLoader();
1123 if (system == null) {
1124 return getBootstrapResources(name);
1125 }
1126 return system.getResources(name);
1127 }
1128
1129 /**
1130 * Find resources from the VM's built-in classloader.
1131 */
1132 private static URL getBootstrapResource(String name) {
1133 URLClassPath ucp = getBootstrapClassPath();
1134 Resource res = ucp.getResource(name);
1135 return res != null ? res.getURL() : null;
1136 }
1137
1138 /**
1139 * Find resources from the VM's built-in classloader.
1140 */
1141 private static Enumeration getBootstrapResources(String name)
1142 throws IOException {
1143 final Enumeration e = getBootstrapClassPath()
1144 .getResources(name);
1145 return new Enumeration() {
1146 public Object nextElement() {
1147 return ((Resource) e.nextElement()).getURL();
1148 }
1149
1150 public boolean hasMoreElements() {
1151 return e.hasMoreElements();
1152 }
1153 };
1154 }
1155
1156 // Returns the URLClassPath that is used for finding system resources.
1157 static URLClassPath getBootstrapClassPath() {
1158 if (bootstrapClassPath == null) {
1159 bootstrapClassPath = sun.misc.Launcher
1160 .getBootstrapClassPath();
1161 }
1162 return bootstrapClassPath;
1163 }
1164
1165 private static URLClassPath bootstrapClassPath;
1166
1167 /**
1168 * Returns an input stream for reading the specified resource.
1169 *
1170 * <p> The search order is described in the documentation for {@link
1171 * #getResource(String)}. </p>
1172 *
1173 * @param name
1174 * The resource name
1175 *
1176 * @return An input stream for reading the resource, or <tt>null</tt>
1177 * if the resource could not be found
1178 *
1179 * @since 1.1
1180 */
1181 public InputStream getResourceAsStream(String name) {
1182 URL url = getResource(name);
1183 try {
1184 return url != null ? url.openStream() : null;
1185 } catch (IOException e) {
1186 return null;
1187 }
1188 }
1189
1190 /**
1191 * Open for reading, a resource of the specified name from the search path
1192 * used to load classes. This method locates the resource through the
1193 * system class loader (see {@link #getSystemClassLoader()}). </p>
1194 *
1195 * @param name
1196 * The resource name
1197 *
1198 * @return An input stream for reading the resource, or <tt>null</tt>
1199 * if the resource could not be found
1200 *
1201 * @since 1.1
1202 */
1203 public static InputStream getSystemResourceAsStream(String name) {
1204 URL url = getSystemResource(name);
1205 try {
1206 return url != null ? url.openStream() : null;
1207 } catch (IOException e) {
1208 return null;
1209 }
1210 }
1211
1212 // -- Hierarchy --
1213
1214 /**
1215 * Returns the parent class loader for delegation. Some implementations may
1216 * use <tt>null</tt> to represent the bootstrap class loader. This method
1217 * will return <tt>null</tt> in such implementations if this class loader's
1218 * parent is the bootstrap class loader.
1219 *
1220 * <p> If a security manager is present, and the invoker's class loader is
1221 * not <tt>null</tt> and is not an ancestor of this class loader, then this
1222 * method invokes the security manager's {@link
1223 * SecurityManager#checkPermission(java.security.Permission)
1224 * <tt>checkPermission</tt>} method with a {@link
1225 * RuntimePermission#RuntimePermission(String)
1226 * <tt>RuntimePermission("getClassLoader")</tt>} permission to verify
1227 * access to the parent class loader is permitted. If not, a
1228 * <tt>SecurityException</tt> will be thrown. </p>
1229 *
1230 * @return The parent <tt>ClassLoader</tt>
1231 *
1232 * @throws SecurityException
1233 * If a security manager exists and its <tt>checkPermission</tt>
1234 * method doesn't allow access to this class loader's parent class
1235 * loader.
1236 *
1237 * @since 1.2
1238 */
1239 public final ClassLoader getParent() {
1240 if (parent == null)
1241 return null;
1242 SecurityManager sm = System.getSecurityManager();
1243 if (sm != null) {
1244 ClassLoader ccl = getCallerClassLoader();
1245 if (ccl != null && !isAncestor(ccl)) {
1246 sm
1247 .checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
1248 }
1249 }
1250 return parent;
1251 }
1252
1253 /**
1254 * Returns the system class loader for delegation. This is the default
1255 * delegation parent for new <tt>ClassLoader</tt> instances, and is
1256 * typically the class loader used to start the application.
1257 *
1258 * <p> This method is first invoked early in the runtime's startup
1259 * sequence, at which point it creates the system class loader and sets it
1260 * as the context class loader of the invoking <tt>Thread</tt>.
1261 *
1262 * <p> The default system class loader is an implementation-dependent
1263 * instance of this class.
1264 *
1265 * <p> If the system property "<tt>java.system.class.loader</tt>" is defined
1266 * when this method is first invoked then the value of that property is
1267 * taken to be the name of a class that will be returned as the system
1268 * class loader. The class is loaded using the default system class loader
1269 * and must define a public constructor that takes a single parameter of
1270 * type <tt>ClassLoader</tt> which is used as the delegation parent. An
1271 * instance is then created using this constructor with the default system
1272 * class loader as the parameter. The resulting class loader is defined
1273 * to be the system class loader.
1274 *
1275 * <p> If a security manager is present, and the invoker's class loader is
1276 * not <tt>null</tt> and the invoker's class loader is not the same as or
1277 * an ancestor of the system class loader, then this method invokes the
1278 * security manager's {@link
1279 * SecurityManager#checkPermission(java.security.Permission)
1280 * <tt>checkPermission</tt>} method with a {@link
1281 * RuntimePermission#RuntimePermission(String)
1282 * <tt>RuntimePermission("getClassLoader")</tt>} permission to verify
1283 * access to the system class loader. If not, a
1284 * <tt>SecurityException</tt> will be thrown. </p>
1285 *
1286 * @return The system <tt>ClassLoader</tt> for delegation, or
1287 * <tt>null</tt> if none
1288 *
1289 * @throws SecurityException
1290 * If a security manager exists and its <tt>checkPermission</tt>
1291 * method doesn't allow access to the system class loader.
1292 *
1293 * @throws IllegalStateException
1294 * If invoked recursively during the construction of the class
1295 * loader specified by the "<tt>java.system.class.loader</tt>"
1296 * property.
1297 *
1298 * @throws Error
1299 * If the system property "<tt>java.system.class.loader</tt>"
1300 * is defined but the named class could not be loaded, the
1301 * provider class does not define the required constructor, or an
1302 * exception is thrown by that constructor when it is invoked. The
1303 * underlying cause of the error can be retrieved via the
1304 * {@link Throwable#getCause()} method.
1305 *
1306 * @revised 1.4
1307 */
1308 public static ClassLoader getSystemClassLoader() {
1309 initSystemClassLoader();
1310 if (scl == null) {
1311 return null;
1312 }
1313 SecurityManager sm = System.getSecurityManager();
1314 if (sm != null) {
1315 ClassLoader ccl = getCallerClassLoader();
1316 if (ccl != null && ccl != scl && !scl.isAncestor(ccl)) {
1317 sm
1318 .checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
1319 }
1320 }
1321 return scl;
1322 }
1323
1324 private static synchronized void initSystemClassLoader() {
1325 if (!sclSet) {
1326 if (scl != null)
1327 throw new IllegalStateException("recursive invocation");
1328 sun.misc.Launcher l = sun.misc.Launcher.getLauncher();
1329 if (l != null) {
1330 Throwable oops = null;
1331 scl = l.getClassLoader();
1332 try {
1333 PrivilegedExceptionAction a;
1334 a = new SystemClassLoaderAction(scl);
1335 scl = (ClassLoader) AccessController
1336 .doPrivileged(a);
1337 } catch (PrivilegedActionException pae) {
1338 oops = pae.getCause();
1339 if (oops instanceof InvocationTargetException) {
1340 oops = oops.getCause();
1341 }
1342 }
1343 if (oops != null) {
1344 if (oops instanceof Error) {
1345 throw (Error) oops;
1346 } else {
1347 // wrap the exception
1348 throw new Error(oops);
1349 }
1350 }
1351 }
1352 sclSet = true;
1353 }
1354 }
1355
1356 // Returns true if the specified class loader can be found in this class
1357 // loader's delegation chain.
1358 boolean isAncestor(ClassLoader cl) {
1359 ClassLoader acl = this ;
1360 do {
1361 acl = acl.parent;
1362 if (cl == acl) {
1363 return true;
1364 }
1365 } while (acl != null);
1366 return false;
1367 }
1368
1369 // Returns the invoker's class loader, or null if none.
1370 // NOTE: This must always be invoked when there is exactly one intervening
1371 // frame from the core libraries on the stack between this method's
1372 // invocation and the desired invoker.
1373 static ClassLoader getCallerClassLoader() {
1374 // NOTE use of more generic Reflection.getCallerClass()
1375 Class caller = Reflection.getCallerClass(3);
1376 // This can be null if the VM is requesting it
1377 if (caller == null) {
1378 return null;
1379 }
1380 // Circumvent security check since this is package-private
1381 return caller.getClassLoader0();
1382 }
1383
1384 // The class loader for the system
1385 private static ClassLoader scl;
1386
1387 // Set to true once the system class loader has been set
1388 private static boolean sclSet;
1389
1390 // -- Package --
1391
1392 /**
1393 * Defines a package by name in this <tt>ClassLoader</tt>. This allows
1394 * class loaders to define the packages for their classes. Packages must
1395 * be created before the class is defined, and package names must be
1396 * unique within a class loader and cannot be redefined or changed once
1397 * created. </p>
1398 *
1399 * @param name
1400 * The package name
1401 *
1402 * @param specTitle
1403 * The specification title
1404 *
1405 * @param specVersion
1406 * The specification version
1407 *
1408 * @param specVendor
1409 * The specification vendor
1410 *
1411 * @param implTitle
1412 * The implementation title
1413 *
1414 * @param implVersion
1415 * The implementation version
1416 *
1417 * @param implVendor
1418 * The implementation vendor
1419 *
1420 * @param sealBase
1421 * If not <tt>null</tt>, then this package is sealed with
1422 * respect to the given code source {@link java.net.URL
1423 * <tt>URL</tt>} object. Otherwise, the package is not sealed.
1424 *
1425 * @return The newly defined <tt>Package</tt> object
1426 *
1427 * @throws IllegalArgumentException
1428 * If package name duplicates an existing package either in this
1429 * class loader or one of its ancestors
1430 *
1431 * @since 1.2
1432 */
1433 protected Package definePackage(String name, String specTitle,
1434 String specVersion, String specVendor, String implTitle,
1435 String implVersion, String implVendor, URL sealBase)
1436 throws IllegalArgumentException {
1437 synchronized (packages) {
1438 Package pkg = getPackage(name);
1439 if (pkg != null) {
1440 throw new IllegalArgumentException(name);
1441 }
1442 pkg = new Package(name, specTitle, specVersion, specVendor,
1443 implTitle, implVersion, implVendor, sealBase, this );
1444 packages.put(name, pkg);
1445 return pkg;
1446 }
1447 }
1448
1449 /**
1450 * Returns a <tt>Package</tt> that has been defined by this class loader
1451 * or any of its ancestors. </p>
1452 *
1453 * @param name
1454 * The package name
1455 *
1456 * @return The <tt>Package</tt> corresponding to the given name, or
1457 * <tt>null</tt> if not found
1458 *
1459 * @since 1.2
1460 */
1461 protected Package getPackage(String name) {
1462 synchronized (packages) {
1463 Package pkg = (Package) packages.get(name);
1464 if (pkg == null) {
1465 if (parent != null) {
1466 pkg = parent.getPackage(name);
1467 } else {
1468 pkg = Package.getSystemPackage(name);
1469 }
1470 if (pkg != null) {
1471 packages.put(name, pkg);
1472 }
1473 }
1474 return pkg;
1475 }
1476 }
1477
1478 /**
1479 * Returns all of the <tt>Packages</tt> defined by this class loader and
1480 * its ancestors. </p>
1481 *
1482 * @return The array of <tt>Package</tt> objects defined by this
1483 * <tt>ClassLoader</tt>
1484 *
1485 * @since 1.2
1486 */
1487 protected Package[] getPackages() {
1488 Map map;
1489 synchronized (packages) {
1490 map = (Map) packages.clone();
1491 }
1492 Package[] pkgs;
1493 if (parent != null) {
1494 pkgs = parent.getPackages();
1495 } else {
1496 pkgs = Package.getSystemPackages();
1497 }
1498 if (pkgs != null) {
1499 for (int i = 0; i < pkgs.length; i++) {
1500 String pkgName = pkgs[i].getName();
1501 if (map.get(pkgName) == null) {
1502 map.put(pkgName, pkgs[i]);
1503 }
1504 }
1505 }
1506 return (Package[]) map.values()
1507 .toArray(new Package[map.size()]);
1508 }
1509
1510 // -- Native library access --
1511
1512 /**
1513 * Returns the absolute path name of a native library. The VM invokes this
1514 * method to locate the native libraries that belong to classes loaded with
1515 * this class loader. If this method returns <tt>null</tt>, the VM
1516 * searches the library along the path specified as the
1517 * "<tt>java.library.path</tt>" property. </p>
1518 *
1519 * @param libname
1520 * The library name
1521 *
1522 * @return The absolute path of the native library
1523 *
1524 * @see System#loadLibrary(String)
1525 * @see System#mapLibraryName(String)
1526 *
1527 * @since 1.2
1528 */
1529 protected String findLibrary(String libname) {
1530 return null;
1531 }
1532
1533 /**
1534 * The inner class NativeLibrary denotes a loaded native library instance.
1535 * Every classloader contains a vector of loaded native libraries in the
1536 * private field <tt>nativeLibraries</tt>. The native libraries loaded
1537 * into the system are entered into the <tt>systemNativeLibraries</tt>
1538 * vector.
1539 *
1540 * <p> Every native library requires a particular version of JNI. This is
1541 * denoted by the private <tt>jniVersion</tt> field. This field is set by
1542 * the VM when it loads the library, and used by the VM to pass the correct
1543 * version of JNI to the native methods. </p>
1544 *
1545 * @version 1.195 05/05/07
1546 * @see ClassLoader
1547 * @since 1.2
1548 */
1549 static class NativeLibrary {
1550 // opaque handle to native library, used in native code.
1551 long handle;
1552 // the version of JNI environment the native library requires.
1553 private int jniVersion;
1554 // the class from which the library is loaded, also indicates
1555 // the loader this native library belongs.
1556 private Class fromClass;
1557 // the canonicalized name of the native library.
1558 String name;
1559
1560 native void load(String name);
1561
1562 native long find(String name);
1563
1564 native void unload();
1565
1566 public NativeLibrary(Class fromClass, String name) {
1567 this .name = name;
1568 this .fromClass = fromClass;
1569 }
1570
1571 protected void finalize() {
1572 synchronized (loadedLibraryNames) {
1573 if (fromClass.getClassLoader() != null && handle != 0) {
1574 /* remove the native library name */
1575 int size = loadedLibraryNames.size();
1576 for (int i = 0; i < size; i++) {
1577 if (name
1578 .equals(loadedLibraryNames.elementAt(i))) {
1579 loadedLibraryNames.removeElementAt(i);
1580 break;
1581 }
1582 }
1583 /* unload the library. */
1584 ClassLoader.nativeLibraryContext.push(this );
1585 try {
1586 unload();
1587 } finally {
1588 ClassLoader.nativeLibraryContext.pop();
1589 }
1590 }
1591 }
1592 }
1593
1594 // Invoked in the VM to determine the context class in
1595 // JNI_Load/JNI_Unload
1596 static Class getFromClass() {
1597 return ((NativeLibrary) (ClassLoader.nativeLibraryContext
1598 .peek())).fromClass;
1599 }
1600 }
1601
1602 // The "default" domain. Set as the default ProtectionDomain on newly
1603 // created classes.
1604 private ProtectionDomain defaultDomain = null;
1605
1606 // Returns (and initializes) the default domain.
1607 private synchronized ProtectionDomain getDefaultDomain() {
1608 if (defaultDomain == null) {
1609 CodeSource cs = new CodeSource(null,
1610 (java.security.cert.Certificate[]) null);
1611 defaultDomain = new ProtectionDomain(cs, null, this , null);
1612 }
1613 return defaultDomain;
1614 }
1615
1616 // All native library names we've loaded.
1617 private static Vector loadedLibraryNames = new Vector();
1618 // Native libraries belonging to system classes.
1619 private static Vector systemNativeLibraries = new Vector();
1620 // Native libraries associated with the class loader.
1621 private Vector nativeLibraries = new Vector();
1622
1623 // native libraries being loaded/unloaded.
1624 private static Stack nativeLibraryContext = new Stack();
1625
1626 // The paths searched for libraries
1627 static private String usr_paths[];
1628 static private String sys_paths[];
1629
1630 private static String[] initializePath(String propname) {
1631 String ldpath = System.getProperty(propname, "");
1632 String ps = File.pathSeparator;
1633 int ldlen = ldpath.length();
1634 int i, j, n;
1635 // Count the separators in the path
1636 i = ldpath.indexOf(ps);
1637 n = 0;
1638 while (i >= 0) {
1639 n++;
1640 i = ldpath.indexOf(ps, i + 1);
1641 }
1642
1643 // allocate the array of paths - n :'s = n + 1 path elements
1644 String[] paths = new String[n + 1];
1645
1646 // Fill the array with paths from the ldpath
1647 n = i = 0;
1648 j = ldpath.indexOf(ps);
1649 while (j >= 0) {
1650 if (j - i > 0) {
1651 paths[n++] = ldpath.substring(i, j);
1652 } else if (j - i == 0) {
1653 paths[n++] = ".";
1654 }
1655 i = j + 1;
1656 j = ldpath.indexOf(ps, i);
1657 }
1658 paths[n] = ldpath.substring(i, ldlen);
1659 return paths;
1660 }
1661
1662 // Invoked in the java.lang.Runtime class to implement load and loadLibrary.
1663 static void loadLibrary(Class fromClass, String name,
1664 boolean isAbsolute) {
1665 ClassLoader loader = (fromClass == null) ? null : fromClass
1666 .getClassLoader();
1667 if (sys_paths == null) {
1668 usr_paths = initializePath("java.library.path");
1669 sys_paths = initializePath("sun.boot.library.path");
1670 }
1671 if (isAbsolute) {
1672 if (loadLibrary0(fromClass, new File(name))) {
1673 return;
1674 }
1675 throw new UnsatisfiedLinkError("Can't load library: "
1676 + name);
1677 }
1678 if (loader != null) {
1679 String libfilename = loader.findLibrary(name);
1680 if (libfilename != null) {
1681 File libfile = new File(libfilename);
1682 if (!libfile.isAbsolute()) {
1683 throw new UnsatisfiedLinkError(
1684 "ClassLoader.findLibrary failed to return an absolute path: "
1685 + libfilename);
1686 }
1687 if (loadLibrary0(fromClass, libfile)) {
1688 return;
1689 }
1690 throw new UnsatisfiedLinkError("Can't load "
1691 + libfilename);
1692 }
1693 }
1694 for (int i = 0; i < sys_paths.length; i++) {
1695 File libfile = new File(sys_paths[i], System
1696 .mapLibraryName(name));
1697 if (loadLibrary0(fromClass, libfile)) {
1698 return;
1699 }
1700 }
1701 if (loader != null) {
1702 for (int i = 0; i < usr_paths.length; i++) {
1703 File libfile = new File(usr_paths[i], System
1704 .mapLibraryName(name));
1705 if (loadLibrary0(fromClass, libfile)) {
1706 return;
1707 }
1708 }
1709 }
1710 // Oops, it failed
1711 throw new UnsatisfiedLinkError("no " + name
1712 + " in java.library.path");
1713 }
1714
1715 private static boolean loadLibrary0(Class fromClass, final File file) {
1716 Boolean exists = (Boolean) AccessController
1717 .doPrivileged(new PrivilegedAction() {
1718 public Object run() {
1719 return new Boolean(file.exists());
1720 }
1721 });
1722 if (!exists.booleanValue()) {
1723 return false;
1724 }
1725 String name;
1726 try {
1727 name = file.getCanonicalPath();
1728 } catch (IOException e) {
1729 return false;
1730 }
1731 ClassLoader loader = (fromClass == null) ? null : fromClass
1732 .getClassLoader();
1733 Vector libs = loader != null ? loader.nativeLibraries
1734 : systemNativeLibraries;
1735 synchronized (libs) {
1736 int size = libs.size();
1737 for (int i = 0; i < size; i++) {
1738 NativeLibrary lib = (NativeLibrary) libs.elementAt(i);
1739 if (name.equals(lib.name)) {
1740 return true;
1741 }
1742 }
1743
1744 synchronized (loadedLibraryNames) {
1745 if (loadedLibraryNames.contains(name)) {
1746 throw new UnsatisfiedLinkError("Native Library "
1747 + name
1748 + " already loaded in another classloader");
1749 }
1750 /* If the library is being loaded (must be by the same thread,
1751 * because Runtime.load and Runtime.loadLibrary are
1752 * synchronous). The reason is can occur is that the JNI_OnLoad
1753 * function can cause another loadLibrary invocation.
1754 *
1755 * Thus we can use a static stack to hold the list of libraries
1756 * we are loading.
1757 *
1758 * If there is a pending load operation for the library, we
1759 * immediately return success; otherwise, we raise
1760 * UnsatisfiedLinkError.
1761 */
1762 int n = nativeLibraryContext.size();
1763 for (int i = 0; i < n; i++) {
1764 NativeLibrary lib = (NativeLibrary) nativeLibraryContext
1765 .elementAt(i);
1766 if (name.equals(lib.name)) {
1767 if (loader == lib.fromClass.getClassLoader()) {
1768 return true;
1769 } else {
1770 throw new UnsatisfiedLinkError(
1771 "Native Library "
1772 + name
1773 + " is being loaded in another classloader");
1774 }
1775 }
1776 }
1777 NativeLibrary lib = new NativeLibrary(fromClass, name);
1778 nativeLibraryContext.push(lib);
1779 try {
1780 lib.load(name);
1781 } finally {
1782 nativeLibraryContext.pop();
1783 }
1784 if (lib.handle != 0) {
1785 loadedLibraryNames.addElement(name);
1786 libs.addElement(lib);
1787 return true;
1788 }
1789 return false;
1790 }
1791 }
1792 }
1793
1794 // Invoked in the VM class linking code.
1795 static long findNative(ClassLoader loader, String name) {
1796 Vector libs = loader != null ? loader.nativeLibraries
1797 : systemNativeLibraries;
1798 synchronized (libs) {
1799 int size = libs.size();
1800 for (int i = 0; i < size; i++) {
1801 NativeLibrary lib = (NativeLibrary) libs.elementAt(i);
1802 long entry = lib.find(name);
1803 if (entry != 0)
1804 return entry;
1805 }
1806 }
1807 return 0;
1808 }
1809
1810 // -- Assertion management --
1811
1812 // The default toggle for assertion checking.
1813 private boolean defaultAssertionStatus = false;
1814
1815 // Maps String packageName to Boolean package default assertion status Note
1816 // that the default package is placed under a null map key. If this field
1817 // is null then we are delegating assertion status queries to the VM, i.e.,
1818 // none of this ClassLoader's assertion status modification methods have
1819 // been invoked.
1820 private Map packageAssertionStatus = null;
1821
1822 // Maps String fullyQualifiedClassName to Boolean assertionStatus If this
1823 // field is null then we are delegating assertion status queries to the VM,
1824 // i.e., none of this ClassLoader's assertion status modification methods
1825 // have been invoked.
1826 Map classAssertionStatus = null;
1827
1828 /**
1829 * Sets the default assertion status for this class loader. This setting
1830 * determines whether classes loaded by this class loader and initialized
1831 * in the future will have assertions enabled or disabled by default.
1832 * This setting may be overridden on a per-package or per-class basis by
1833 * invoking {@link #setPackageAssertionStatus(String, boolean)} or {@link
1834 * #setClassAssertionStatus(String, boolean)}. </p>
1835 *
1836 * @param enabled
1837 * <tt>true</tt> if classes loaded by this class loader will
1838 * henceforth have assertions enabled by default, <tt>false</tt>
1839 * if they will have assertions disabled by default.
1840 *
1841 * @since 1.4
1842 */
1843 public synchronized void setDefaultAssertionStatus(boolean enabled) {
1844 if (classAssertionStatus == null)
1845 initializeJavaAssertionMaps();
1846
1847 defaultAssertionStatus = enabled;
1848 }
1849
1850 /**
1851 * Sets the package default assertion status for the named package. The
1852 * package default assertion status determines the assertion status for
1853 * classes initialized in the future that belong to the named package or
1854 * any of its "subpackages".
1855 *
1856 * <p> A subpackage of a package named p is any package whose name begins
1857 * with "<tt>p.</tt>". For example, <tt>javax.swing.text</tt> is a
1858 * subpackage of <tt>javax.swing</tt>, and both <tt>java.util</tt> and
1859 * <tt>java.lang.reflect</tt> are subpackages of <tt>java</tt>.
1860 *
1861 * <p> In the event that multiple package defaults apply to a given class,
1862 * the package default pertaining to the most specific package takes
1863 * precedence over the others. For example, if <tt>javax.lang</tt> and
1864 * <tt>javax.lang.reflect</tt> both have package defaults associated with
1865 * them, the latter package default applies to classes in
1866 * <tt>javax.lang.reflect</tt>.
1867 *
1868 * <p> Package defaults take precedence over the class loader's default
1869 * assertion status, and may be overridden on a per-class basis by invoking
1870 * {@link #setClassAssertionStatus(String, boolean)}. </p>
1871 *
1872 * @param packageName
1873 * The name of the package whose package default assertion status
1874 * is to be set. A <tt>null</tt> value indicates the unnamed
1875 * package that is "current"
1876 * (<a href="http://java.sun.com/docs/books/jls/">Java Language
1877 * Specification</a>, section 7.4.2).
1878 *
1879 * @param enabled
1880 * <tt>true</tt> if classes loaded by this classloader and
1881 * belonging to the named package or any of its subpackages will
1882 * have assertions enabled by default, <tt>false</tt> if they will
1883 * have assertions disabled by default.
1884 *
1885 * @since 1.4
1886 */
1887 public synchronized void setPackageAssertionStatus(
1888 String packageName, boolean enabled) {
1889 if (packageAssertionStatus == null)
1890 initializeJavaAssertionMaps();
1891
1892 packageAssertionStatus.put(packageName, Boolean
1893 .valueOf(enabled));
1894 }
1895
1896 /**
1897 * Sets the desired assertion status for the named top-level class in this
1898 * class loader and any nested classes contained therein. This setting
1899 * takes precedence over the class loader's default assertion status, and
1900 * over any applicable per-package default. This method has no effect if
1901 * the named class has already been initialized. (Once a class is
1902 * initialized, its assertion status cannot change.)
1903 *
1904 * <p> If the named class is not a top-level class, this invocation will
1905 * have no effect on the actual assertion status of any class. </p>
1906 *
1907 * @param className
1908 * The fully qualified class name of the top-level class whose
1909 * assertion status is to be set.
1910 *
1911 * @param enabled
1912 * <tt>true</tt> if the named class is to have assertions
1913 * enabled when (and if) it is initialized, <tt>false</tt> if the
1914 * class is to have assertions disabled.
1915 *
1916 * @since 1.4
1917 */
1918 public synchronized void setClassAssertionStatus(String className,
1919 boolean enabled) {
1920 if (classAssertionStatus == null)
1921 initializeJavaAssertionMaps();
1922
1923 classAssertionStatus.put(className, Boolean.valueOf(enabled));
1924 }
1925
1926 /**
1927 * Sets the default assertion status for this class loader to
1928 * <tt>false</tt> and discards any package defaults or class assertion
1929 * status settings associated with the class loader. This method is
1930 * provided so that class loaders can be made to ignore any command line or
1931 * persistent assertion status settings and "start with a clean slate."
1932 * </p>
1933 *
1934 * @since 1.4
1935 */
1936 public synchronized void clearAssertionStatus() {
1937 /*
1938 * Whether or not "Java assertion maps" are initialized, set
1939 * them to empty maps, effectively ignoring any present settings.
1940 */
1941 classAssertionStatus = new HashMap();
1942 packageAssertionStatus = new HashMap();
1943
1944 defaultAssertionStatus = false;
1945 }
1946
1947 /**
1948 * Returns the assertion status that would be assigned to the specified
1949 * class if it were to be initialized at the time this method is invoked.
1950 * If the named class has had its assertion status set, the most recent
1951 * setting will be returned; otherwise, if any package default assertion
1952 * status pertains to this class, the most recent setting for the most
1953 * specific pertinent package default assertion status is returned;
1954 * otherwise, this class loader's default assertion status is returned.
1955 * </p>
1956 *
1957 * @param className
1958 * The fully qualified class name of the class whose desired
1959 * assertion status is being queried.
1960 *
1961 * @return The desired assertion status of the specified class.
1962 *
1963 * @see #setClassAssertionStatus(String, boolean)
1964 * @see #setPackageAssertionStatus(String, boolean)
1965 * @see #setDefaultAssertionStatus(boolean)
1966 *
1967 * @since 1.4
1968 */
1969 synchronized boolean desiredAssertionStatus(String className) {
1970 Boolean result;
1971
1972 // assert classAssertionStatus != null;
1973 // assert packageAssertionStatus != null;
1974
1975 // Check for a class entry
1976 result = (Boolean) classAssertionStatus.get(className);
1977 if (result != null)
1978 return result.booleanValue();
1979
1980 // Check for most specific package entry
1981 int dotIndex = className.lastIndexOf(".");
1982 if (dotIndex < 0) { // default package
1983 result = (Boolean) packageAssertionStatus.get(null);
1984 if (result != null)
1985 return result.booleanValue();
1986 }
1987 while (dotIndex > 0) {
1988 className = className.substring(0, dotIndex);
1989 result = (Boolean) packageAssertionStatus.get(className);
1990 if (result != null)
1991 return result.booleanValue();
1992 dotIndex = className.lastIndexOf(".", dotIndex - 1);
1993 }
1994
1995 // Return the classloader default
1996 return defaultAssertionStatus;
1997 }
1998
1999 // Set up the assertions with information provided by the VM.
2000 private void initializeJavaAssertionMaps() {
2001 // assert Thread.holdsLock(this);
2002
2003 classAssertionStatus = new HashMap();
2004 packageAssertionStatus = new HashMap();
2005 AssertionStatusDirectives directives = retrieveDirectives();
2006
2007 for (int i = 0; i < directives.classes.length; i++)
2008 classAssertionStatus.put(directives.classes[i], Boolean
2009 .valueOf(directives.classEnabled[i]));
2010
2011 for (int i = 0; i < directives.packages.length; i++)
2012 packageAssertionStatus.put(directives.packages[i], Boolean
2013 .valueOf(directives.packageEnabled[i]));
2014
2015 defaultAssertionStatus = directives.deflt;
2016 }
2017
2018 // Retrieves the assertion directives from the VM.
2019 private static native AssertionStatusDirectives retrieveDirectives();
2020 }
2021
2022 class SystemClassLoaderAction implements PrivilegedExceptionAction {
2023 private ClassLoader parent;
2024
2025 SystemClassLoaderAction(ClassLoader parent) {
2026 this .parent = parent;
2027 }
2028
2029 public Object run() throws Exception {
2030 ClassLoader sys;
2031 Constructor ctor;
2032 Class c;
2033 Class cp[] = { ClassLoader.class };
2034 Object params[] = { parent };
2035
2036 String cls = System.getProperty("java.system.class.loader");
2037 if (cls == null) {
2038 return parent;
2039 }
2040
2041 c = Class.forName(cls, true, parent);
2042 ctor = c.getDeclaredConstructor(cp);
2043 sys = (ClassLoader) ctor.newInstance(params);
2044 Thread.currentThread().setContextClassLoader(sys);
2045 return sys;
2046 }
2047 }
|