1 /* 2 * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package java.lang; 26 27 import java.io.InputStream; 28 import java.io.IOException; 29 import java.io.File; 30 import java.lang.reflect.Constructor; 31 import java.lang.reflect.InvocationTargetException; 32 import java.net.MalformedURLException; 33 import java.net.URL; 34 import java.security.AccessController; 35 import java.security.AccessControlContext; 36 import java.security.CodeSource; 37 import java.security.Policy; 38 import java.security.PrivilegedAction; 39 import java.security.PrivilegedActionException; 40 import java.security.PrivilegedExceptionAction; 41 import java.security.ProtectionDomain; 42 import java.security.cert.Certificate; 43 import java.util.Collections; 44 import java.util.Enumeration; 45 import java.util.HashMap; 46 import java.util.HashSet; 47 import java.util.Set; 48 import java.util.Stack; 49 import java.util.Map; 50 import java.util.Vector; 51 import java.util.Hashtable; 52 import java.util.WeakHashMap; 53 import java.util.concurrent.ConcurrentHashMap; 54 import sun.misc.BootClassLoaderHook; 55 import sun.misc.ClassFileTransformer; 56 import sun.misc.CompoundEnumeration; 57 import sun.misc.Resource; 58 import sun.misc.URLClassPath; 59 import sun.misc.VM; 60 import sun.reflect.Reflection; 61 import sun.security.util.SecurityConstants; 62 63 /** 64 * A class loader is an object that is responsible for loading classes. The 65 * class <tt>ClassLoader</tt> is an abstract class. Given the <a 66 * href="#name">binary name</a> of a class, a class loader should attempt to 67 * locate or generate data that constitutes a definition for the class. A 68 * typical strategy is to transform the name into a file name and then read a 69 * "class file" of that name from a file system. 70 * 71 * <p> Every {@link Class <tt>Class</tt>} object contains a {@link 72 * Class#getClassLoader() reference} to the <tt>ClassLoader</tt> that defined 73 * it. 74 * 75 * <p> <tt>Class</tt> objects for array classes are not created by class 76 * loaders, but are created automatically as required by the Java runtime. 77 * The class loader for an array class, as returned by {@link 78 * Class#getClassLoader()} is the same as the class loader for its element 79 * type; if the element type is a primitive type, then the array class has no 80 * class loader. 81 * 82 * <p> Applications implement subclasses of <tt>ClassLoader</tt> in order to 83 * extend the manner in which the Java virtual machine dynamically loads 84 * classes. 85 * 86 * <p> Class loaders may typically be used by security managers to indicate 87 * security domains. 88 * 89 * <p> The <tt>ClassLoader</tt> class uses a delegation model to search for 90 * classes and resources. Each instance of <tt>ClassLoader</tt> has an 91 * associated parent class loader. When requested to find a class or 92 * resource, a <tt>ClassLoader</tt> instance will delegate the search for the 93 * class or resource to its parent class loader before attempting to find the 94 * class or resource itself. The virtual machine's built-in class loader, 95 * called the "bootstrap class loader", does not itself have a parent but may 96 * serve as the parent of a <tt>ClassLoader</tt> instance. 97 * 98 * <p> Class loaders that support concurrent loading of classes are known as 99 * <em>parallel capable</em> class loaders and are required to register 100 * themselves at their class initialization time by invoking the 101 * {@link 102 * #registerAsParallelCapable <tt>ClassLoader.registerAsParallelCapable</tt>} 103 * method. Note that the <tt>ClassLoader</tt> class is registered as parallel 104 * capable by default. However, its subclasses still need to register themselves 105 * if they are parallel capable. <br> 106 * In environments in which the delegation model is not strictly 107 * hierarchical, class loaders need to be parallel capable, otherwise class 108 * loading can lead to deadlocks because the loader lock is held for the 109 * duration of the class loading process (see {@link #loadClass 110 * <tt>loadClass</tt>} methods). 111 * 112 * <p> Normally, the Java virtual machine loads classes from the local file 113 * system in a platform-dependent manner. For example, on UNIX systems, the 114 * virtual machine loads classes from the directory defined by the 115 * <tt>CLASSPATH</tt> environment variable. 116 * 117 * <p> However, some classes may not originate from a file; they may originate 118 * from other sources, such as the network, or they could be constructed by an 119 * application. The method {@link #defineClass(String, byte[], int, int) 120 * <tt>defineClass</tt>} converts an array of bytes into an instance of class 121 * <tt>Class</tt>. Instances of this newly defined class can be created using 122 * {@link Class#newInstance <tt>Class.newInstance</tt>}. 123 * 124 * <p> The methods and constructors of objects created by a class loader may 125 * reference other classes. To determine the class(es) referred to, the Java 126 * virtual machine invokes the {@link #loadClass <tt>loadClass</tt>} method of 127 * the class loader that originally created the class. 128 * 129 * <p> For example, an application could create a network class loader to 130 * download class files from a server. Sample code might look like: 131 * 132 * <blockquote><pre> 133 * ClassLoader loader = new NetworkClassLoader(host, port); 134 * Object main = loader.loadClass("Main", true).newInstance(); 135 * . . . 136 * </pre></blockquote> 137 * 138 * <p> The network class loader subclass must define the methods {@link 139 * #findClass <tt>findClass</tt>} and <tt>loadClassData</tt> to load a class 140 * from the network. Once it has downloaded the bytes that make up the class, 141 * it should use the method {@link #defineClass <tt>defineClass</tt>} to 142 * create a class instance. A sample implementation is: 143 * 144 * <blockquote><pre> 145 * class NetworkClassLoader extends ClassLoader { 146 * String host; 147 * int port; 148 * 149 * public Class findClass(String name) { 150 * byte[] b = loadClassData(name); 151 * return defineClass(name, b, 0, b.length); 152 * } 153 * 154 * private byte[] loadClassData(String name) { 155 * // load the class data from the connection 156 * . . . 157 * } 158 * } 159 * </pre></blockquote> 160 * 161 * <h4> <a name="name">Binary names</a> </h4> 162 * 163 * <p> Any class name provided as a {@link String} parameter to methods in 164 * <tt>ClassLoader</tt> must be a binary name as defined by the <a 165 * href="http://java.sun.com/docs/books/jls/">Java Language Specification</a>. 166 * 167 * <p> Examples of valid class names include: 168 * <blockquote><pre> 169 * "java.lang.String" 170 * "javax.swing.JSpinner$DefaultEditor" 171 * "java.security.KeyStore$Builder$FileBuilder$1" 172 * "java.net.URLClassLoader$3$1" 173 * </pre></blockquote> 174 * 175 * @see #resolveClass(Class) 176 * @since 1.0 177 */ 178 public abstract class ClassLoader { 179 180 private static native void registerNatives(); 181 static { 182 registerNatives(); 183 } 184 185 // The parent class loader for delegation 186 // Note: VM hardcoded the offset of this field, thus all new fields 187 // must be added *after* it. 188 private final ClassLoader parent; 189 190 /** 191 * Encapsulates the set of parallel capable loader types. 192 */ 193 private static class ParallelLoaders { 194 private ParallelLoaders() {} 195 196 // the set of parallel capable loader types 197 private static final Set<Class<? extends ClassLoader>> loaderTypes = 198 Collections.newSetFromMap( 199 new WeakHashMap<Class<? extends ClassLoader>, Boolean>()); 200 static { 201 synchronized (loaderTypes) { loaderTypes.add(ClassLoader.class); } 202 } 203 204 /** 205 * Registers the given class loader type as parallel capabale. 206 * Returns {@code true} is successfully registered; {@code false} if 207 * loader's super class is not registered. 208 */ 209 static boolean register(Class<? extends ClassLoader> c) { 210 synchronized (loaderTypes) { 211 if (loaderTypes.contains(c.getSuperclass())) { 212 // register the class loader as parallel capable 213 // if and only if all of its super classes are. 214 // Note: given current classloading sequence, if 215 // the immediate super class is parallel capable, 216 // all the super classes higher up must be too. 217 loaderTypes.add(c); 218 return true; 219 } else { 220 return false; 221 } 222 } 223 } 224 225 /** 226 * Returns {@code true} if the given class loader type is 227 * registered as parallel capable. 228 */ 229 static boolean isRegistered(Class<? extends ClassLoader> c) { 230 synchronized (loaderTypes) { 231 return loaderTypes.contains(c); 232 } 233 } 234 } 235 236 // Maps class name to the corresponding lock object when the current 237 // class loader is parallel capable. 238 // Note: VM also uses this field to decide if the current class loader 239 // is parallel capable and the appropriate lock object for class loading. 240 private final ConcurrentHashMap<String, Object> parallelLockMap; 241 242 // Hashtable that maps packages to certs 243 private final Map <String, Certificate[]> package2certs; 244 245 // Shared among all packages with unsigned classes 246 private static final Certificate[] nocerts = new Certificate[0]; 247 248 // The classes loaded by this class loader. The only purpose of this table 249 // is to keep the classes from being GC'ed until the loader is GC'ed. 250 private final Vector<Class<?>> classes = new Vector<Class<?>>(); 251 252 // The "default" domain. Set as the default ProtectionDomain on newly 253 // created classes. 254 private final ProtectionDomain defaultDomain = 255 new ProtectionDomain(new CodeSource(null, (Certificate[]) null), 256 null, this, null); 257 258 // The initiating protection domains for all classes loaded by this loader 259 private final Set<ProtectionDomain> domains; 260 261 // Invoked by the VM to record every loaded class with this loader. 262 void addClass(Class c) { 263 classes.addElement(c); 264 } 265 266 // The packages defined in this class loader. Each package name is mapped 267 // to its corresponding Package object. 268 // @GuardedBy("itself") 269 private final HashMap<String, Package> packages = 270 new HashMap<String, Package>(); 271 272 private static Void checkCreateClassLoader() { 273 SecurityManager security = System.getSecurityManager(); 274 if (security != null) { 275 security.checkCreateClassLoader(); 276 } 277 return null; 278 } 279 280 private ClassLoader(Void unused, ClassLoader parent) { 281 this.parent = parent; 282 if (ParallelLoaders.isRegistered(this.getClass())) { 283 parallelLockMap = new ConcurrentHashMap<String, Object>(); 284 package2certs = new ConcurrentHashMap<String, Certificate[]>(); 285 domains = 286 Collections.synchronizedSet(new HashSet<ProtectionDomain>()); 287 assertionLock = new Object(); 288 } else { 289 // no finer-grained lock; lock on the classloader instance 290 parallelLockMap = null; 291 package2certs = new Hashtable<String, Certificate[]>(); 292 domains = new HashSet<ProtectionDomain>(); 293 assertionLock = this; 294 } 295 } 296 297 /** 298 * Creates a new class loader using the specified parent class loader for 299 * delegation. 300 * 301 * <p> If there is a security manager, its {@link 302 * SecurityManager#checkCreateClassLoader() 303 * <tt>checkCreateClassLoader</tt>} method is invoked. This may result in 304 * a security exception. </p> 305 * 306 * @param parent 307 * The parent class loader 308 * 309 * @throws SecurityException 310 * If a security manager exists and its 311 * <tt>checkCreateClassLoader</tt> method doesn't allow creation 312 * of a new class loader. 313 * 314 * @since 1.2 315 */ 316 protected ClassLoader(ClassLoader parent) { 317 this(checkCreateClassLoader(), parent); 318 } 319 320 /** 321 * Creates a new class loader using the <tt>ClassLoader</tt> returned by 322 * the method {@link #getSystemClassLoader() 323 * <tt>getSystemClassLoader()</tt>} as the parent class loader. 324 * 325 * <p> If there is a security manager, its {@link 326 * SecurityManager#checkCreateClassLoader() 327 * <tt>checkCreateClassLoader</tt>} method is invoked. This may result in 328 * a security exception. </p> 329 * 330 * @throws SecurityException 331 * If a security manager exists and its 332 * <tt>checkCreateClassLoader</tt> method doesn't allow creation 333 * of a new class loader. 334 */ 335 protected ClassLoader() { 336 this(checkCreateClassLoader(), getSystemClassLoader()); 337 } 338 339 // -- Class -- 340 341 /** 342 * Loads the class with the specified <a href="#name">binary name</a>. 343 * This method searches for classes in the same manner as the {@link 344 * #loadClass(String, boolean)} method. It is invoked by the Java virtual 345 * machine to resolve class references. Invoking this method is equivalent 346 * to invoking {@link #loadClass(String, boolean) <tt>loadClass(name, 347 * false)</tt>}. </p> 348 * 349 * @param name 350 * The <a href="#name">binary name</a> of the class 351 * 352 * @return The resulting <tt>Class</tt> object 353 * 354 * @throws ClassNotFoundException 355 * If the class was not found 356 */ 357 public Class<?> loadClass(String name) throws ClassNotFoundException { 358 return loadClass(name, false); 359 } 360 361 /** 362 * Loads the class with the specified <a href="#name">binary name</a>. The 363 * default implementation of this method searches for classes in the 364 * following order: 365 * 366 * <p><ol> 367 * 368 * <li><p> Invoke {@link #findLoadedClass(String)} to check if the class 369 * has already been loaded. </p></li> 370 * 371 * <li><p> Invoke the {@link #loadClass(String) <tt>loadClass</tt>} method 372 * on the parent class loader. If the parent is <tt>null</tt> the class 373 * loader built-in to the virtual machine is used, instead. </p></li> 374 * 375 * <li><p> Invoke the {@link #findClass(String)} method to find the 376 * class. </p></li> 377 * 378 * </ol> 379 * 380 * <p> If the class was found using the above steps, and the 381 * <tt>resolve</tt> flag is true, this method will then invoke the {@link 382 * #resolveClass(Class)} method on the resulting <tt>Class</tt> object. 383 * 384 * <p> Subclasses of <tt>ClassLoader</tt> are encouraged to override {@link 385 * #findClass(String)}, rather than this method. </p> 386 * 387 * <p> Unless overridden, this method synchronizes on the result of 388 * {@link #getClassLoadingLock <tt>getClassLoadingLock</tt>} method 389 * during the entire class loading process. 390 * 391 * @param name 392 * The <a href="#name">binary name</a> of the class 393 * 394 * @param resolve 395 * If <tt>true</tt> then resolve the class 396 * 397 * @return The resulting <tt>Class</tt> object 398 * 399 * @throws ClassNotFoundException 400 * If the class could not be found 401 */ 402 protected Class<?> loadClass(String name, boolean resolve) 403 throws ClassNotFoundException 404 { 405 synchronized (getClassLoadingLock(name)) { 406 // First, check if the class has already been loaded 407 Class c = findLoadedClass(name); 408 if (c == null) { 409 long t0 = System.nanoTime(); 410 try { 411 if (parent != null) { 412 c = parent.loadClass(name, false); 413 } else { 414 c = findBootstrapClassOrNull(name); 415 } 416 } catch (ClassNotFoundException e) { 417 // ClassNotFoundException thrown if class not found 418 // from the non-null parent class loader 419 } 420 421 if (c == null) { 422 // If still not found, then invoke findClass in order 423 // to find the class. 424 long t1 = System.nanoTime(); 425 c = findClass(name); 426 427 // this is the defining class loader; record the stats 428 sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0); 429 sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1); 430 sun.misc.PerfCounter.getFindClasses().increment(); 431 } 432 } 433 if (resolve) { 434 resolveClass(c); 435 } 436 return c; 437 } 438 } 439 440 /** 441 * Returns the lock object for class loading operations. 442 * For backward compatibility, the default implementation of this method 443 * behaves as follows. If this ClassLoader object is registered as 444 * parallel capable, the method returns a dedicated object associated 445 * with the specified class name. Otherwise, the method returns this 446 * ClassLoader object. </p> 447 * 448 * @param className 449 * The name of the to-be-loaded class 450 * 451 * @return the lock for class loading operations 452 * 453 * @throws NullPointerException 454 * If registered as parallel capable and <tt>className</tt> is null 455 * 456 * @see #loadClass(String, boolean) 457 * 458 * @since 1.7 459 */ 460 protected Object getClassLoadingLock(String className) { 461 Object lock = this; 462 if (parallelLockMap != null) { 463 Object newLock = new Object(); 464 lock = parallelLockMap.putIfAbsent(className, newLock); 465 if (lock == null) { 466 lock = newLock; 467 } 468 } 469 return lock; 470 } 471 472 // This method is invoked by the virtual machine to load a class. 473 private Class loadClassInternal(String name) 474 throws ClassNotFoundException 475 { 476 // For backward compatibility, explicitly lock on 'this' when 477 // the current class loader is not parallel capable. 478 if (parallelLockMap == null) { 479 synchronized (this) { 480 return loadClass(name); 481 } 482 } else { 483 return loadClass(name); 484 } 485 } 486 487 // Invoked by the VM after loading class with this loader. 488 private void checkPackageAccess(Class cls, ProtectionDomain pd) { 489 final SecurityManager sm = System.getSecurityManager(); 490 if (sm != null) { 491 final String name = cls.getName(); 492 final int i = name.lastIndexOf('.'); 493 if (i != -1) { 494 AccessController.doPrivileged(new PrivilegedAction<Void>() { 495 public Void run() { 496 sm.checkPackageAccess(name.substring(0, i)); 497 return null; 498 } 499 }, new AccessControlContext(new ProtectionDomain[] {pd})); 500 } 501 } 502 domains.add(pd); 503 } 504 505 /** 506 * Finds the class with the specified <a href="#name">binary name</a>. 507 * This method should be overridden by class loader implementations that 508 * follow the delegation model for loading classes, and will be invoked by 509 * the {@link #loadClass <tt>loadClass</tt>} method after checking the 510 * parent class loader for the requested class. The default implementation 511 * throws a <tt>ClassNotFoundException</tt>. </p> 512 * 513 * @param name 514 * The <a href="#name">binary name</a> of the class 515 * 516 * @return The resulting <tt>Class</tt> object 517 * 518 * @throws ClassNotFoundException 519 * If the class could not be found 520 * 521 * @since 1.2 522 */ 523 protected Class<?> findClass(String name) throws ClassNotFoundException { 524 throw new ClassNotFoundException(name); 525 } 526 527 /** 528 * Converts an array of bytes into an instance of class <tt>Class</tt>. 529 * Before the <tt>Class</tt> can be used it must be resolved. This method 530 * is deprecated in favor of the version that takes a <a 531 * href="#name">binary name</a> as its first argument, and is more secure. 532 * 533 * @param b 534 * The bytes that make up the class data. The bytes in positions 535 * <tt>off</tt> through <tt>off+len-1</tt> should have the format 536 * of a valid class file as defined by the <a 537 * href="http://java.sun.com/docs/books/vmspec/">Java Virtual 538 * Machine Specification</a>. 539 * 540 * @param off 541 * The start offset in <tt>b</tt> of the class data 542 * 543 * @param len 544 * The length of the class data 545 * 546 * @return The <tt>Class</tt> object that was created from the specified 547 * class data 548 * 549 * @throws ClassFormatError 550 * If the data did not contain a valid class 551 * 552 * @throws IndexOutOfBoundsException 553 * If either <tt>off</tt> or <tt>len</tt> is negative, or if 554 * <tt>off+len</tt> is greater than <tt>b.length</tt>. 555 * 556 * @throws SecurityException 557 * If an attempt is made to add this class to a package that 558 * contains classes that were signed by a different set of 559 * certificates than this class, or if an attempt is made 560 * to define a class in a package with a fully-qualified name 561 * that starts with "{@code java.}". 562 * 563 * @see #loadClass(String, boolean) 564 * @see #resolveClass(Class) 565 * 566 * @deprecated Replaced by {@link #defineClass(String, byte[], int, int) 567 * defineClass(String, byte[], int, int)} 568 */ 569 @Deprecated 570 protected final Class<?> defineClass(byte[] b, int off, int len) 571 throws ClassFormatError 572 { 573 return defineClass(null, b, off, len, null); 574 } 575 576 /** 577 * Converts an array of bytes into an instance of class <tt>Class</tt>. 578 * Before the <tt>Class</tt> can be used it must be resolved. 579 * 580 * <p> This method assigns a default {@link java.security.ProtectionDomain 581 * <tt>ProtectionDomain</tt>} to the newly defined class. The 582 * <tt>ProtectionDomain</tt> is effectively granted the same set of 583 * permissions returned when {@link 584 * java.security.Policy#getPermissions(java.security.CodeSource) 585 * <tt>Policy.getPolicy().getPermissions(new CodeSource(null, null))</tt>} 586 * is invoked. The default domain is created on the first invocation of 587 * {@link #defineClass(String, byte[], int, int) <tt>defineClass</tt>}, 588 * and re-used on subsequent invocations. 589 * 590 * <p> To assign a specific <tt>ProtectionDomain</tt> to the class, use 591 * the {@link #defineClass(String, byte[], int, int, 592 * java.security.ProtectionDomain) <tt>defineClass</tt>} method that takes a 593 * <tt>ProtectionDomain</tt> as one of its arguments. </p> 594 * 595 * @param name 596 * The expected <a href="#name">binary name</a> of the class, or 597 * <tt>null</tt> if not known 598 * 599 * @param b 600 * The bytes that make up the class data. The bytes in positions 601 * <tt>off</tt> through <tt>off+len-1</tt> should have the format 602 * of a valid class file as defined by the <a 603 * href="http://java.sun.com/docs/books/vmspec/">Java Virtual 604 * Machine Specification</a>. 605 * 606 * @param off 607 * The start offset in <tt>b</tt> of the class data 608 * 609 * @param len 610 * The length of the class data 611 * 612 * @return The <tt>Class</tt> object that was created from the specified 613 * class data. 614 * 615 * @throws ClassFormatError 616 * If the data did not contain a valid class 617 * 618 * @throws IndexOutOfBoundsException 619 * If either <tt>off</tt> or <tt>len</tt> is negative, or if 620 * <tt>off+len</tt> is greater than <tt>b.length</tt>. 621 * 622 * @throws SecurityException 623 * If an attempt is made to add this class to a package that 624 * contains classes that were signed by a different set of 625 * certificates than this class (which is unsigned), or if 626 * <tt>name</tt> begins with "<tt>java.</tt>". 627 * 628 * @see #loadClass(String, boolean) 629 * @see #resolveClass(Class) 630 * @see java.security.CodeSource 631 * @see java.security.SecureClassLoader 632 * 633 * @since 1.1 634 */ 635 protected final Class<?> defineClass(String name, byte[] b, int off, int len) 636 throws ClassFormatError 637 { 638 return defineClass(name, b, off, len, null); 639 } 640 641 /* Determine protection domain, and check that: 642 - not define java.* class, 643 - signer of this class matches signers for the rest of the classes in 644 package. 645 */ 646 private ProtectionDomain preDefineClass(String name, 647 ProtectionDomain pd) 648 { 649 if (!checkName(name)) 650 throw new NoClassDefFoundError("IllegalName: " + name); 651 652 if ((name != null) && name.startsWith("java.")) { 653 throw new SecurityException 654 ("Prohibited package name: " + 655 name.substring(0, name.lastIndexOf('.'))); 656 } 657 if (pd == null) { 658 pd = defaultDomain; 659 } 660 661 if (name != null) checkCerts(name, pd.getCodeSource()); 662 663 return pd; 664 } 665 666 private String defineClassSourceLocation(ProtectionDomain pd) 667 { 668 CodeSource cs = pd.getCodeSource(); 669 String source = null; 670 if (cs != null && cs.getLocation() != null) { 671 source = cs.getLocation().toString(); 672 } 673 return source; 674 } 675 676 private Class defineTransformedClass(String name, byte[] b, int off, int len, 677 ProtectionDomain pd, 678 ClassFormatError cfe, String source) 679 throws ClassFormatError 680 { 681 // Class format error - try to transform the bytecode and 682 // define the class again 683 // 684 ClassFileTransformer[] transformers = 685 ClassFileTransformer.getTransformers(); 686 Class c = null; 687 688 if (transformers != null) { 689 for (ClassFileTransformer transformer : transformers) { 690 try { 691 // Transform byte code using transformer 692 byte[] tb = transformer.transform(b, off, len); 693 c = defineClass1(name, tb, 0, tb.length, 694 pd, source); 695 break; 696 } catch (ClassFormatError cfe2) { 697 // If ClassFormatError occurs, try next transformer 698 } 699 } 700 } 701 702 // Rethrow original ClassFormatError if unable to transform 703 // bytecode to well-formed 704 // 705 if (c == null) 706 throw cfe; 707 708 return c; 709 } 710 711 private void postDefineClass(Class c, ProtectionDomain pd) 712 { 713 if (pd.getCodeSource() != null) { 714 Certificate certs[] = pd.getCodeSource().getCertificates(); 715 if (certs != null) 716 setSigners(c, certs); 717 } 718 } 719 720 /** 721 * Converts an array of bytes into an instance of class <tt>Class</tt>, 722 * with an optional <tt>ProtectionDomain</tt>. If the domain is 723 * <tt>null</tt>, then a default domain will be assigned to the class as 724 * specified in the documentation for {@link #defineClass(String, byte[], 725 * int, int)}. Before the class can be used it must be resolved. 726 * 727 * <p> The first class defined in a package determines the exact set of 728 * certificates that all subsequent classes defined in that package must 729 * contain. The set of certificates for a class is obtained from the 730 * {@link java.security.CodeSource <tt>CodeSource</tt>} within the 731 * <tt>ProtectionDomain</tt> of the class. Any classes added to that 732 * package must contain the same set of certificates or a 733 * <tt>SecurityException</tt> will be thrown. Note that if 734 * <tt>name</tt> is <tt>null</tt>, this check is not performed. 735 * You should always pass in the <a href="#name">binary name</a> of the 736 * class you are defining as well as the bytes. This ensures that the 737 * class you are defining is indeed the class you think it is. 738 * 739 * <p> The specified <tt>name</tt> cannot begin with "<tt>java.</tt>", since 740 * all classes in the "<tt>java.*</tt> packages can only be defined by the 741 * bootstrap class loader. If <tt>name</tt> is not <tt>null</tt>, it 742 * must be equal to the <a href="#name">binary name</a> of the class 743 * specified by the byte array "<tt>b</tt>", otherwise a {@link 744 * <tt>NoClassDefFoundError</tt>} will be thrown. </p> 745 * 746 * @param name 747 * The expected <a href="#name">binary name</a> of the class, or 748 * <tt>null</tt> if not known 749 * 750 * @param b 751 * The bytes that make up the class data. The bytes in positions 752 * <tt>off</tt> through <tt>off+len-1</tt> should have the format 753 * of a valid class file as defined by the <a 754 * href="http://java.sun.com/docs/books/vmspec/">Java Virtual 755 * Machine Specification</a>. 756 * 757 * @param off 758 * The start offset in <tt>b</tt> of the class data 759 * 760 * @param len 761 * The length of the class data 762 * 763 * @param protectionDomain 764 * The ProtectionDomain of the class 765 * 766 * @return The <tt>Class</tt> object created from the data, 767 * and optional <tt>ProtectionDomain</tt>. 768 * 769 * @throws ClassFormatError 770 * If the data did not contain a valid class 771 * 772 * @throws NoClassDefFoundError 773 * If <tt>name</tt> is not equal to the <a href="#name">binary 774 * name</a> of the class specified by <tt>b</tt> 775 * 776 * @throws IndexOutOfBoundsException 777 * If either <tt>off</tt> or <tt>len</tt> is negative, or if 778 * <tt>off+len</tt> is greater than <tt>b.length</tt>. 779 * 780 * @throws SecurityException 781 * If an attempt is made to add this class to a package that 782 * contains classes that were signed by a different set of 783 * certificates than this class, or if <tt>name</tt> begins with 784 * "<tt>java.</tt>". 785 */ 786 protected final Class<?> defineClass(String name, byte[] b, int off, int len, 787 ProtectionDomain protectionDomain) 788 throws ClassFormatError 789 { 790 protectionDomain = preDefineClass(name, protectionDomain); 791 792 Class c = null; 793 String source = defineClassSourceLocation(protectionDomain); 794 795 try { 796 c = defineClass1(name, b, off, len, protectionDomain, source); 797 } catch (ClassFormatError cfe) { 798 c = defineTransformedClass(name, b, off, len, protectionDomain, cfe, 799 source); 800 } 801 802 postDefineClass(c, protectionDomain); 803 return c; 804 } 805 806 /** 807 * Converts a {@link java.nio.ByteBuffer <tt>ByteBuffer</tt>} 808 * into an instance of class <tt>Class</tt>, 809 * with an optional <tt>ProtectionDomain</tt>. If the domain is 810 * <tt>null</tt>, then a default domain will be assigned to the class as 811 * specified in the documentation for {@link #defineClass(String, byte[], 812 * int, int)}. Before the class can be used it must be resolved. 813 * 814 * <p>The rules about the first class defined in a package determining the 815 * set of certificates for the package, and the restrictions on class names 816 * are identical to those specified in the documentation for {@link 817 * #defineClass(String, byte[], int, int, ProtectionDomain)}. 818 * 819 * <p> An invocation of this method of the form 820 * <i>cl</i><tt>.defineClass(</tt><i>name</i><tt>,</tt> 821 * <i>bBuffer</i><tt>,</tt> <i>pd</i><tt>)</tt> yields exactly the same 822 * result as the statements 823 * 824 * <blockquote><tt> 825 * ...<br> 826 * byte[] temp = new byte[</tt><i>bBuffer</i><tt>.{@link 827 * java.nio.ByteBuffer#remaining remaining}()];<br> 828 * </tt><i>bBuffer</i><tt>.{@link java.nio.ByteBuffer#get(byte[]) 829 * get}(temp);<br> 830 * return {@link #defineClass(String, byte[], int, int, ProtectionDomain) 831 * </tt><i>cl</i><tt>.defineClass}(</tt><i>name</i><tt>, temp, 0, 832 * temp.length, </tt><i>pd</i><tt>);<br> 833 * </tt></blockquote> 834 * 835 * @param name 836 * The expected <a href="#name">binary name</a>. of the class, or 837 * <tt>null</tt> if not known 838 * 839 * @param b 840 * The bytes that make up the class data. The bytes from positions 841 * <tt>b.position()</tt> through <tt>b.position() + b.limit() -1 842 * </tt> should have the format of a valid class file as defined by 843 * the <a href="http://java.sun.com/docs/books/vmspec/">Java Virtual 844 * Machine Specification</a>. 845 * 846 * @param protectionDomain 847 * The ProtectionDomain of the class, or <tt>null</tt>. 848 * 849 * @return The <tt>Class</tt> object created from the data, 850 * and optional <tt>ProtectionDomain</tt>. 851 * 852 * @throws ClassFormatError 853 * If the data did not contain a valid class. 854 * 855 * @throws NoClassDefFoundError 856 * If <tt>name</tt> is not equal to the <a href="#name">binary 857 * name</a> of the class specified by <tt>b</tt> 858 * 859 * @throws SecurityException 860 * If an attempt is made to add this class to a package that 861 * contains classes that were signed by a different set of 862 * certificates than this class, or if <tt>name</tt> begins with 863 * "<tt>java.</tt>". 864 * 865 * @see #defineClass(String, byte[], int, int, ProtectionDomain) 866 * 867 * @since 1.5 868 */ 869 protected final Class<?> defineClass(String name, java.nio.ByteBuffer b, 870 ProtectionDomain protectionDomain) 871 throws ClassFormatError 872 { 873 int len = b.remaining(); 874 875 // Use byte[] if not a direct ByteBufer: 876 if (!b.isDirect()) { 877 if (b.hasArray()) { 878 return defineClass(name, b.array(), 879 b.position() + b.arrayOffset(), len, 880 protectionDomain); 881 } else { 882 // no array, or read-only array 883 byte[] tb = new byte[len]; 884 b.get(tb); // get bytes out of byte buffer. 885 return defineClass(name, tb, 0, len, protectionDomain); 886 } 887 } 888 889 protectionDomain = preDefineClass(name, protectionDomain); 890 891 Class c = null; 892 String source = defineClassSourceLocation(protectionDomain); 893 894 try { 895 c = defineClass2(name, b, b.position(), len, protectionDomain, 896 source); 897 } catch (ClassFormatError cfe) { 898 byte[] tb = new byte[len]; 899 b.get(tb); // get bytes out of byte buffer. 900 c = defineTransformedClass(name, tb, 0, len, protectionDomain, cfe, 901 source); 902 } 903 904 postDefineClass(c, protectionDomain); 905 return c; 906 } 907 908 private native Class defineClass0(String name, byte[] b, int off, int len, 909 ProtectionDomain pd); 910 911 private native Class defineClass1(String name, byte[] b, int off, int len, 912 ProtectionDomain pd, String source); 913 914 private native Class defineClass2(String name, java.nio.ByteBuffer b, 915 int off, int len, ProtectionDomain pd, 916 String source); 917 918 // true if the name is null or has the potential to be a valid binary name 919 private boolean checkName(String name) { 920 if ((name == null) || (name.length() == 0)) 921 return true; 922 if ((name.indexOf('/') != -1) 923 || (!VM.allowArraySyntax() && (name.charAt(0) == '['))) 924 return false; 925 return true; 926 } 927 928 private void checkCerts(String name, CodeSource cs) { 929 int i = name.lastIndexOf('.'); 930 String pname = (i == -1) ? "" : name.substring(0, i); 931 932 Certificate[] certs = null; 933 if (cs != null) { 934 certs = cs.getCertificates(); 935 } 936 Certificate[] pcerts = null; 937 if (parallelLockMap == null) { 938 synchronized (this) { 939 pcerts = package2certs.get(pname); 940 if (pcerts == null) { 941 package2certs.put(pname, (certs == null? nocerts:certs)); 942 } 943 } 944 } else { 945 pcerts = ((ConcurrentHashMap<String, Certificate[]>)package2certs). 946 putIfAbsent(pname, (certs == null? nocerts:certs)); 947 } 948 if (pcerts != null && !compareCerts(pcerts, certs)) { 949 throw new SecurityException("class \""+ name + 950 "\"'s signer information does not match signer information of other classes in the same package"); 951 } 952 } 953 954 /** 955 * check to make sure the certs for the new class (certs) are the same as 956 * the certs for the first class inserted in the package (pcerts) 957 */ 958 private boolean compareCerts(Certificate[] pcerts, 959 Certificate[] certs) 960 { 961 // certs can be null, indicating no certs. 962 if ((certs == null) || (certs.length == 0)) { 963 return pcerts.length == 0; 964 } 965 966 // the length must be the same at this point 967 if (certs.length != pcerts.length) 968 return false; 969 970 // go through and make sure all the certs in one array 971 // are in the other and vice-versa. 972 boolean match; 973 for (int i = 0; i < certs.length; i++) { 974 match = false; 975 for (int j = 0; j < pcerts.length; j++) { 976 if (certs[i].equals(pcerts[j])) { 977 match = true; 978 break; 979 } 980 } 981 if (!match) return false; 982 } 983 984 // now do the same for pcerts 985 for (int i = 0; i < pcerts.length; i++) { 986 match = false; 987 for (int j = 0; j < certs.length; j++) { 988 if (pcerts[i].equals(certs[j])) { 989 match = true; 990 break; 991 } 992 } 993 if (!match) return false; 994 } 995 996 return true; 997 } 998 999 /** 1000 * Links the specified class. This (misleadingly named) method may be 1001 * used by a class loader to link a class. If the class <tt>c</tt> has 1002 * already been linked, then this method simply returns. Otherwise, the 1003 * class is linked as described in the "Execution" chapter of the <a 1004 * href="http://java.sun.com/docs/books/jls/">Java Language 1005 * Specification</a>. 1006 * </p> 1007 * 1008 * @param c 1009 * The class to link 1010 * 1011 * @throws NullPointerException 1012 * If <tt>c</tt> is <tt>null</tt>. 1013 * 1014 * @see #defineClass(String, byte[], int, int) 1015 */ 1016 protected final void resolveClass(Class<?> c) { 1017 resolveClass0(c); 1018 } 1019 1020 private native void resolveClass0(Class c); 1021 1022 /** 1023 * Finds a class with the specified <a href="#name">binary name</a>, 1024 * loading it if necessary. 1025 * 1026 * <p> This method loads the class through the system class loader (see 1027 * {@link #getSystemClassLoader()}). The <tt>Class</tt> object returned 1028 * might have more than one <tt>ClassLoader</tt> associated with it. 1029 * Subclasses of <tt>ClassLoader</tt> need not usually invoke this method, 1030 * because most class loaders need to override just {@link 1031 * #findClass(String)}. </p> 1032 * 1033 * @param name 1034 * The <a href="#name">binary name</a> of the class 1035 * 1036 * @return The <tt>Class</tt> object for the specified <tt>name</tt> 1037 * 1038 * @throws ClassNotFoundException 1039 * If the class could not be found 1040 * 1041 * @see #ClassLoader(ClassLoader) 1042 * @see #getParent() 1043 */ 1044 protected final Class<?> findSystemClass(String name) 1045 throws ClassNotFoundException 1046 { 1047 ClassLoader system = getSystemClassLoader(); 1048 if (system == null) { 1049 if (!checkName(name)) 1050 throw new ClassNotFoundException(name); 1051 Class cls = findBootstrapClass(name); 1052 if (cls == null) { 1053 throw new ClassNotFoundException(name); 1054 } 1055 return cls; 1056 } 1057 return system.loadClass(name); 1058 } 1059 1060 /** 1061 * Returns a class loaded by the bootstrap class loader; 1062 * or return null if not found. 1063 */ 1064 private Class findBootstrapClassOrNull(String name) 1065 { 1066 if (!checkName(name)) return null; 1067 1068 return findBootstrapClass(name); 1069 } 1070 1071 // return null if not found 1072 private native Class findBootstrapClass(String name); 1073 1074 /** 1075 * Returns the class with the given <a href="#name">binary name</a> if this 1076 * loader has been recorded by the Java virtual machine as an initiating 1077 * loader of a class with that <a href="#name">binary name</a>. Otherwise 1078 * <tt>null</tt> is returned. </p> 1079 * 1080 * @param name 1081 * The <a href="#name">binary name</a> of the class 1082 * 1083 * @return The <tt>Class</tt> object, or <tt>null</tt> if the class has 1084 * not been loaded 1085 * 1086 * @since 1.1 1087 */ 1088 protected final Class<?> findLoadedClass(String name) { 1089 if (!checkName(name)) 1090 return null; 1091 return findLoadedClass0(name); 1092 } 1093 1094 private native final Class findLoadedClass0(String name); 1095 1096 /** 1097 * Sets the signers of a class. This should be invoked after defining a 1098 * class. </p> 1099 * 1100 * @param c 1101 * The <tt>Class</tt> object 1102 * 1103 * @param signers 1104 * The signers for the class 1105 * 1106 * @since 1.1 1107 */ 1108 protected final void setSigners(Class<?> c, Object[] signers) { 1109 c.setSigners(signers); 1110 } 1111 1112 1113 // -- Resource -- 1114 1115 /** 1116 * Finds the resource with the given name. A resource is some data 1117 * (images, audio, text, etc) that can be accessed by class code in a way 1118 * that is independent of the location of the code. 1119 * 1120 * <p> The name of a resource is a '<tt>/</tt>'-separated path name that 1121 * identifies the resource. 1122 * 1123 * <p> This method will first search the parent class loader for the 1124 * resource; if the parent is <tt>null</tt> the path of the class loader 1125 * built-in to the virtual machine is searched. That failing, this method 1126 * will invoke {@link #findResource(String)} to find the resource. </p> 1127 * 1128 * @param name 1129 * The resource name 1130 * 1131 * @return A <tt>URL</tt> object for reading the resource, or 1132 * <tt>null</tt> if the resource could not be found or the invoker 1133 * doesn't have adequate privileges to get the resource. 1134 * 1135 * @since 1.1 1136 */ 1137 public URL getResource(String name) { 1138 URL url; 1139 if (parent != null) { 1140 url = parent.getResource(name); 1141 } else { 1142 url = getBootstrapResource(name); 1143 } 1144 if (url == null) { 1145 url = findResource(name); 1146 } 1147 return url; 1148 } 1149 1150 /** 1151 * Finds all the resources with the given name. A resource is some data 1152 * (images, audio, text, etc) that can be accessed by class code in a way 1153 * that is independent of the location of the code. 1154 * 1155 * <p>The name of a resource is a <tt>/</tt>-separated path name that 1156 * identifies the resource. 1157 * 1158 * <p> The search order is described in the documentation for {@link 1159 * #getResource(String)}. </p> 1160 * 1161 * @param name 1162 * The resource name 1163 * 1164 * @return An enumeration of {@link java.net.URL <tt>URL</tt>} objects for 1165 * the resource. If no resources could be found, the enumeration 1166 * will be empty. Resources that the class loader doesn't have 1167 * access to will not be in the enumeration. 1168 * 1169 * @throws IOException 1170 * If I/O errors occur 1171 * 1172 * @see #findResources(String) 1173 * 1174 * @since 1.2 1175 */ 1176 public Enumeration<URL> getResources(String name) throws IOException { 1177 Enumeration[] tmp = new Enumeration[2]; 1178 if (parent != null) { 1179 tmp[0] = parent.getResources(name); 1180 } else { 1181 tmp[0] = getBootstrapResources(name); 1182 } 1183 tmp[1] = findResources(name); 1184 1185 return new CompoundEnumeration<URL>(tmp); 1186 } 1187 1188 /** 1189 * Finds the resource with the given name. Class loader implementations 1190 * should override this method to specify where to find resources. </p> 1191 * 1192 * @param name 1193 * The resource name 1194 * 1195 * @return A <tt>URL</tt> object for reading the resource, or 1196 * <tt>null</tt> if the resource could not be found 1197 * 1198 * @since 1.2 1199 */ 1200 protected URL findResource(String name) { 1201 return null; 1202 } 1203 1204 /** 1205 * Returns an enumeration of {@link java.net.URL <tt>URL</tt>} objects 1206 * representing all the resources with the given name. Class loader 1207 * implementations should override this method to specify where to load 1208 * resources from. </p> 1209 * 1210 * @param name 1211 * The resource name 1212 * 1213 * @return An enumeration of {@link java.net.URL <tt>URL</tt>} objects for 1214 * the resources 1215 * 1216 * @throws IOException 1217 * If I/O errors occur 1218 * 1219 * @since 1.2 1220 */ 1221 protected Enumeration<URL> findResources(String name) throws IOException { 1222 return java.util.Collections.emptyEnumeration(); 1223 } 1224 1225 // index 0: java.lang.ClassLoader.class 1226 // index 1: the immediate caller of index 0. 1227 // index 2: the immediate caller of index 1. 1228 private static native Class<? extends ClassLoader> getCaller(int index); 1229 1230 /** 1231 * Registers the caller as parallel capable.</p> 1232 * The registration succeeds if and only if all of the following 1233 * conditions are met: <br> 1234 * 1. no instance of the caller has been created</p> 1235 * 2. all of the super classes (except class Object) of the caller are 1236 * registered as parallel capable</p> 1237 * Note that once a class loader is registered as parallel capable, there 1238 * is no way to change it back. </p> 1239 * 1240 * @return true if the caller is successfully registered as 1241 * parallel capable and false if otherwise. 1242 * 1243 * @since 1.7 1244 */ 1245 protected static boolean registerAsParallelCapable() { 1246 return ParallelLoaders.register(getCaller(1)); 1247 } 1248 1249 /** 1250 * Find a resource of the specified name from the search path used to load 1251 * classes. This method locates the resource through the system class 1252 * loader (see {@link #getSystemClassLoader()}). </p> 1253 * 1254 * @param name 1255 * The resource name 1256 * 1257 * @return A {@link java.net.URL <tt>URL</tt>} object for reading the 1258 * resource, or <tt>null</tt> if the resource could not be found 1259 * 1260 * @since 1.1 1261 */ 1262 public static URL getSystemResource(String name) { 1263 ClassLoader system = getSystemClassLoader(); 1264 if (system == null) { 1265 return getBootstrapResource(name); 1266 } 1267 return system.getResource(name); 1268 } 1269 1270 /** 1271 * Finds all resources of the specified name from the search path used to 1272 * load classes. The resources thus found are returned as an 1273 * {@link java.util.Enumeration <tt>Enumeration</tt>} of {@link 1274 * java.net.URL <tt>URL</tt>} objects. 1275 * 1276 * <p> The search order is described in the documentation for {@link 1277 * #getSystemResource(String)}. </p> 1278 * 1279 * @param name 1280 * The resource name 1281 * 1282 * @return An enumeration of resource {@link java.net.URL <tt>URL</tt>} 1283 * objects 1284 * 1285 * @throws IOException 1286 * If I/O errors occur 1287 1288 * @since 1.2 1289 */ 1290 public static Enumeration<URL> getSystemResources(String name) 1291 throws IOException 1292 { 1293 ClassLoader system = getSystemClassLoader(); 1294 if (system == null) { 1295 return getBootstrapResources(name); 1296 } 1297 return system.getResources(name); 1298 } 1299 1300 /** 1301 * Find resources from the VM's built-in classloader. 1302 */ 1303 private static URL getBootstrapResource(String name) { 1304 BootClassLoaderHook.preLoadResource(name); 1305 URLClassPath ucp = getBootstrapClassPath(); 1306 Resource res = ucp.getResource(name); 1307 return res != null ? res.getURL() : null; 1308 } 1309 1310 /** 1311 * Find resources from the VM's built-in classloader. 1312 */ 1313 private static Enumeration<URL> getBootstrapResources(String name) 1314 throws IOException 1315 { 1316 final Enumeration<Resource> e = 1317 getBootstrapClassPath().getResources(name); 1318 return new Enumeration<URL> () { 1319 public URL nextElement() { 1320 return e.nextElement().getURL(); 1321 } 1322 public boolean hasMoreElements() { 1323 return e.hasMoreElements(); 1324 } 1325 }; 1326 } 1327 1328 // Returns the URLClassPath that is used for finding system resources. 1329 static URLClassPath getBootstrapClassPath() { 1330 return sun.misc.Launcher.getBootstrapClassPath(); 1331 } 1332 1333 1334 /** 1335 * Returns an input stream for reading the specified resource. 1336 * 1337 * <p> The search order is described in the documentation for {@link 1338 * #getResource(String)}. </p> 1339 * 1340 * @param name 1341 * The resource name 1342 * 1343 * @return An input stream for reading the resource, or <tt>null</tt> 1344 * if the resource could not be found 1345 * 1346 * @since 1.1 1347 */ 1348 public InputStream getResourceAsStream(String name) { 1349 URL url = getResource(name); 1350 try { 1351 return url != null ? url.openStream() : null; 1352 } catch (IOException e) { 1353 return null; 1354 } 1355 } 1356 1357 /** 1358 * Open for reading, a resource of the specified name from the search path 1359 * used to load classes. This method locates the resource through the 1360 * system class loader (see {@link #getSystemClassLoader()}). </p> 1361 * 1362 * @param name 1363 * The resource name 1364 * 1365 * @return An input stream for reading the resource, or <tt>null</tt> 1366 * if the resource could not be found 1367 * 1368 * @since 1.1 1369 */ 1370 public static InputStream getSystemResourceAsStream(String name) { 1371 URL url = getSystemResource(name); 1372 try { 1373 return url != null ? url.openStream() : null; 1374 } catch (IOException e) { 1375 return null; 1376 } 1377 } 1378 1379 1380 // -- Hierarchy -- 1381 1382 /** 1383 * Returns the parent class loader for delegation. Some implementations may 1384 * use <tt>null</tt> to represent the bootstrap class loader. This method 1385 * will return <tt>null</tt> in such implementations if this class loader's 1386 * parent is the bootstrap class loader. 1387 * 1388 * <p> If a security manager is present, and the invoker's class loader is 1389 * not <tt>null</tt> and is not an ancestor of this class loader, then this 1390 * method invokes the security manager's {@link 1391 * SecurityManager#checkPermission(java.security.Permission) 1392 * <tt>checkPermission</tt>} method with a {@link 1393 * RuntimePermission#RuntimePermission(String) 1394 * <tt>RuntimePermission("getClassLoader")</tt>} permission to verify 1395 * access to the parent class loader is permitted. If not, a 1396 * <tt>SecurityException</tt> will be thrown. </p> 1397 * 1398 * @return The parent <tt>ClassLoader</tt> 1399 * 1400 * @throws SecurityException 1401 * If a security manager exists and its <tt>checkPermission</tt> 1402 * method doesn't allow access to this class loader's parent class 1403 * loader. 1404 * 1405 * @since 1.2 1406 */ 1407 public final ClassLoader getParent() { 1408 if (parent == null) 1409 return null; 1410 SecurityManager sm = System.getSecurityManager(); 1411 if (sm != null) { 1412 ClassLoader ccl = getCallerClassLoader(); 1413 if (ccl != null && !isAncestor(ccl)) { 1414 sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); 1415 } 1416 } 1417 return parent; 1418 } 1419 1420 /** 1421 * Returns the system class loader for delegation. This is the default 1422 * delegation parent for new <tt>ClassLoader</tt> instances, and is 1423 * typically the class loader used to start the application. 1424 * 1425 * <p> This method is first invoked early in the runtime's startup 1426 * sequence, at which point it creates the system class loader and sets it 1427 * as the context class loader of the invoking <tt>Thread</tt>. 1428 * 1429 * <p> The default system class loader is an implementation-dependent 1430 * instance of this class. 1431 * 1432 * <p> If the system property "<tt>java.system.class.loader</tt>" is defined 1433 * when this method is first invoked then the value of that property is 1434 * taken to be the name of a class that will be returned as the system 1435 * class loader. The class is loaded using the default system class loader 1436 * and must define a public constructor that takes a single parameter of 1437 * type <tt>ClassLoader</tt> which is used as the delegation parent. An 1438 * instance is then created using this constructor with the default system 1439 * class loader as the parameter. The resulting class loader is defined 1440 * to be the system class loader. 1441 * 1442 * <p> If a security manager is present, and the invoker's class loader is 1443 * not <tt>null</tt> and the invoker's class loader is not the same as or 1444 * an ancestor of the system class loader, then this method invokes the 1445 * security manager's {@link 1446 * SecurityManager#checkPermission(java.security.Permission) 1447 * <tt>checkPermission</tt>} method with a {@link 1448 * RuntimePermission#RuntimePermission(String) 1449 * <tt>RuntimePermission("getClassLoader")</tt>} permission to verify 1450 * access to the system class loader. If not, a 1451 * <tt>SecurityException</tt> will be thrown. </p> 1452 * 1453 * @return The system <tt>ClassLoader</tt> for delegation, or 1454 * <tt>null</tt> if none 1455 * 1456 * @throws SecurityException 1457 * If a security manager exists and its <tt>checkPermission</tt> 1458 * method doesn't allow access to the system class loader. 1459 * 1460 * @throws IllegalStateException 1461 * If invoked recursively during the construction of the class 1462 * loader specified by the "<tt>java.system.class.loader</tt>" 1463 * property. 1464 * 1465 * @throws Error 1466 * If the system property "<tt>java.system.class.loader</tt>" 1467 * is defined but the named class could not be loaded, the 1468 * provider class does not define the required constructor, or an 1469 * exception is thrown by that constructor when it is invoked. The 1470 * underlying cause of the error can be retrieved via the 1471 * {@link Throwable#getCause()} method. 1472 * 1473 * @revised 1.4 1474 */ 1475 public static ClassLoader getSystemClassLoader() { 1476 initSystemClassLoader(); 1477 if (scl == null) { 1478 return null; 1479 } 1480 SecurityManager sm = System.getSecurityManager(); 1481 if (sm != null) { 1482 ClassLoader ccl = getCallerClassLoader(); 1483 if (ccl != null && ccl != scl && !scl.isAncestor(ccl)) { 1484 sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); 1485 } 1486 } 1487 return scl; 1488 } 1489 1490 private static synchronized void initSystemClassLoader() { 1491 if (!sclSet) { 1492 if (scl != null) 1493 throw new IllegalStateException("recursive invocation"); 1494 sun.misc.Launcher l = sun.misc.Launcher.getLauncher(); 1495 if (l != null) { 1496 Throwable oops = null; 1497 scl = l.getClassLoader(); 1498 try { 1499 scl = AccessController.doPrivileged( 1500 new SystemClassLoaderAction(scl)); 1501 } catch (PrivilegedActionException pae) { 1502 oops = pae.getCause(); 1503 if (oops instanceof InvocationTargetException) { 1504 oops = oops.getCause(); 1505 } 1506 } 1507 if (oops != null) { 1508 if (oops instanceof Error) { 1509 throw (Error) oops; 1510 } else { 1511 // wrap the exception 1512 throw new Error(oops); 1513 } 1514 } 1515 } 1516 sclSet = true; 1517 } 1518 } 1519 1520 // Returns true if the specified class loader can be found in this class 1521 // loader's delegation chain. 1522 boolean isAncestor(ClassLoader cl) { 1523 ClassLoader acl = this; 1524 do { 1525 acl = acl.parent; 1526 if (cl == acl) { 1527 return true; 1528 } 1529 } while (acl != null); 1530 return false; 1531 } 1532 1533 // Returns the invoker's class loader, or null if none. 1534 // NOTE: This must always be invoked when there is exactly one intervening 1535 // frame from the core libraries on the stack between this method's 1536 // invocation and the desired invoker. 1537 static ClassLoader getCallerClassLoader() { 1538 // NOTE use of more generic Reflection.getCallerClass() 1539 Class caller = Reflection.getCallerClass(3); 1540 // This can be null if the VM is requesting it 1541 if (caller == null) { 1542 return null; 1543 } 1544 // Circumvent security check since this is package-private 1545 return caller.getClassLoader0(); 1546 } 1547 1548 // The class loader for the system 1549 // @GuardedBy("ClassLoader.class") 1550 private static ClassLoader scl; 1551 1552 // Set to true once the system class loader has been set 1553 // @GuardedBy("ClassLoader.class") 1554 private static boolean sclSet; 1555 1556 1557 // -- Package -- 1558 1559 /** 1560 * Defines a package by name in this <tt>ClassLoader</tt>. This allows 1561 * class loaders to define the packages for their classes. Packages must 1562 * be created before the class is defined, and package names must be 1563 * unique within a class loader and cannot be redefined or changed once 1564 * created. </p> 1565 * 1566 * @param name 1567 * The package name 1568 * 1569 * @param specTitle 1570 * The specification title 1571 * 1572 * @param specVersion 1573 * The specification version 1574 * 1575 * @param specVendor 1576 * The specification vendor 1577 * 1578 * @param implTitle 1579 * The implementation title 1580 * 1581 * @param implVersion 1582 * The implementation version 1583 * 1584 * @param implVendor 1585 * The implementation vendor 1586 * 1587 * @param sealBase 1588 * If not <tt>null</tt>, then this package is sealed with 1589 * respect to the given code source {@link java.net.URL 1590 * <tt>URL</tt>} object. Otherwise, the package is not sealed. 1591 * 1592 * @return The newly defined <tt>Package</tt> object 1593 * 1594 * @throws IllegalArgumentException 1595 * If package name duplicates an existing package either in this 1596 * class loader or one of its ancestors 1597 * 1598 * @since 1.2 1599 */ 1600 protected Package definePackage(String name, String specTitle, 1601 String specVersion, String specVendor, 1602 String implTitle, String implVersion, 1603 String implVendor, URL sealBase) 1604 throws IllegalArgumentException 1605 { 1606 synchronized (packages) { 1607 Package pkg = getPackage(name); 1608 if (pkg != null) { 1609 throw new IllegalArgumentException(name); 1610 } 1611 pkg = new Package(name, specTitle, specVersion, specVendor, 1612 implTitle, implVersion, implVendor, 1613 sealBase, this); 1614 packages.put(name, pkg); 1615 return pkg; 1616 } 1617 } 1618 1619 /** 1620 * Returns a <tt>Package</tt> that has been defined by this class loader 1621 * or any of its ancestors. </p> 1622 * 1623 * @param name 1624 * The package name 1625 * 1626 * @return The <tt>Package</tt> corresponding to the given name, or 1627 * <tt>null</tt> if not found 1628 * 1629 * @since 1.2 1630 */ 1631 protected Package getPackage(String name) { 1632 synchronized (packages) { 1633 Package pkg = packages.get(name); 1634 if (pkg == null) { 1635 if (parent != null) { 1636 pkg = parent.getPackage(name); 1637 } else { 1638 pkg = Package.getSystemPackage(name); 1639 } 1640 if (pkg != null) { 1641 packages.put(name, pkg); 1642 } 1643 } 1644 return pkg; 1645 } 1646 } 1647 1648 /** 1649 * Returns all of the <tt>Packages</tt> defined by this class loader and 1650 * its ancestors. </p> 1651 * 1652 * @return The array of <tt>Package</tt> objects defined by this 1653 * <tt>ClassLoader</tt> 1654 * 1655 * @since 1.2 1656 */ 1657 protected Package[] getPackages() { 1658 Map<String, Package> map; 1659 synchronized (packages) { 1660 map = new HashMap<String, Package>(packages); 1661 } 1662 Package[] pkgs; 1663 if (parent != null) { 1664 pkgs = parent.getPackages(); 1665 } else { 1666 pkgs = Package.getSystemPackages(); 1667 } 1668 if (pkgs != null) { 1669 for (int i = 0; i < pkgs.length; i++) { 1670 String pkgName = pkgs[i].getName(); 1671 if (map.get(pkgName) == null) { 1672 map.put(pkgName, pkgs[i]); 1673 } 1674 } 1675 } 1676 return map.values().toArray(new Package[map.size()]); 1677 } 1678 1679 1680 // -- Native library access -- 1681 1682 /** 1683 * Returns the absolute path name of a native library. The VM invokes this 1684 * method to locate the native libraries that belong to classes loaded with 1685 * this class loader. If this method returns <tt>null</tt>, the VM 1686 * searches the library along the path specified as the 1687 * "<tt>java.library.path</tt>" property. </p> 1688 * 1689 * @param libname 1690 * The library name 1691 * 1692 * @return The absolute path of the native library 1693 * 1694 * @see System#loadLibrary(String) 1695 * @see System#mapLibraryName(String) 1696 * 1697 * @since 1.2 1698 */ 1699 protected String findLibrary(String libname) { 1700 return null; 1701 } 1702 1703 /** 1704 * The inner class NativeLibrary denotes a loaded native library instance. 1705 * Every classloader contains a vector of loaded native libraries in the 1706 * private field <tt>nativeLibraries</tt>. The native libraries loaded 1707 * into the system are entered into the <tt>systemNativeLibraries</tt> 1708 * vector. 1709 * 1710 * <p> Every native library requires a particular version of JNI. This is 1711 * denoted by the private <tt>jniVersion</tt> field. This field is set by 1712 * the VM when it loads the library, and used by the VM to pass the correct 1713 * version of JNI to the native methods. </p> 1714 * 1715 * @see ClassLoader 1716 * @since 1.2 1717 */ 1718 static class NativeLibrary { 1719 // opaque handle to native library, used in native code. 1720 long handle; 1721 // the version of JNI environment the native library requires. 1722 private int jniVersion; 1723 // the class from which the library is loaded, also indicates 1724 // the loader this native library belongs. 1725 private Class fromClass; 1726 // the canonicalized name of the native library. 1727 String name; 1728 1729 native void load(String name); 1730 native long find(String name); 1731 native void unload(); 1732 1733 public NativeLibrary(Class fromClass, String name) { 1734 this.name = name; 1735 this.fromClass = fromClass; 1736 } 1737 1738 protected void finalize() { 1739 synchronized (loadedLibraryNames) { 1740 if (fromClass.getClassLoader() != null && handle != 0) { 1741 /* remove the native library name */ 1742 int size = loadedLibraryNames.size(); 1743 for (int i = 0; i < size; i++) { 1744 if (name.equals(loadedLibraryNames.elementAt(i))) { 1745 loadedLibraryNames.removeElementAt(i); 1746 break; 1747 } 1748 } 1749 /* unload the library. */ 1750 ClassLoader.nativeLibraryContext.push(this); 1751 try { 1752 unload(); 1753 } finally { 1754 ClassLoader.nativeLibraryContext.pop(); 1755 } 1756 } 1757 } 1758 } 1759 // Invoked in the VM to determine the context class in 1760 // JNI_Load/JNI_Unload 1761 static Class getFromClass() { 1762 return ClassLoader.nativeLibraryContext.peek().fromClass; 1763 } 1764 } 1765 1766 // All native library names we've loaded. 1767 private static Vector<String> loadedLibraryNames 1768 = new Vector<String>(); 1769 1770 // Native libraries belonging to system classes. 1771 private static Vector<NativeLibrary> systemNativeLibraries 1772 = new Vector<NativeLibrary>(); 1773 1774 // Native libraries associated with the class loader. 1775 private Vector<NativeLibrary> nativeLibraries 1776 = new Vector<NativeLibrary>(); 1777 1778 // native libraries being loaded/unloaded. 1779 private static Stack<NativeLibrary> nativeLibraryContext 1780 = new Stack<NativeLibrary>(); 1781 1782 // The paths searched for libraries 1783 private static String usr_paths[]; 1784 private static String sys_paths[]; 1785 1786 private static String[] initializePath(String propname) { 1787 String ldpath = System.getProperty(propname, ""); 1788 String ps = File.pathSeparator; 1789 int ldlen = ldpath.length(); 1790 int i, j, n; 1791 // Count the separators in the path 1792 i = ldpath.indexOf(ps); 1793 n = 0; 1794 while (i >= 0) { 1795 n++; 1796 i = ldpath.indexOf(ps, i + 1); 1797 } 1798 1799 // allocate the array of paths - n :'s = n + 1 path elements 1800 String[] paths = new String[n + 1]; 1801 1802 // Fill the array with paths from the ldpath 1803 n = i = 0; 1804 j = ldpath.indexOf(ps); 1805 while (j >= 0) { 1806 if (j - i > 0) { 1807 paths[n++] = ldpath.substring(i, j); 1808 } else if (j - i == 0) { 1809 paths[n++] = "."; 1810 } 1811 i = j + 1; 1812 j = ldpath.indexOf(ps, i); 1813 } 1814 paths[n] = ldpath.substring(i, ldlen); 1815 return paths; 1816 } 1817 1818 // Invoked in the java.lang.Runtime class to implement load and loadLibrary. 1819 static void loadLibrary(Class fromClass, String name, 1820 boolean isAbsolute) { 1821 BootClassLoaderHook.preLoadLibrary(name); 1822 ClassLoader loader = 1823 (fromClass == null) ? null : fromClass.getClassLoader(); 1824 if (sys_paths == null) { 1825 usr_paths = initializePath("java.library.path"); 1826 sys_paths = initializePath("sun.boot.library.path"); 1827 } 1828 if (isAbsolute) { 1829 if (loadLibrary0(fromClass, new File(name))) { 1830 return; 1831 } 1832 throw new UnsatisfiedLinkError("Can't load library: " + name); 1833 } 1834 if (loader != null) { 1835 String libfilename = loader.findLibrary(name); 1836 if (libfilename != null) { 1837 File libfile = new File(libfilename); 1838 if (!libfile.isAbsolute()) { 1839 throw new UnsatisfiedLinkError( 1840 "ClassLoader.findLibrary failed to return an absolute path: " + libfilename); 1841 } 1842 if (loadLibrary0(fromClass, libfile)) { 1843 return; 1844 } 1845 throw new UnsatisfiedLinkError("Can't load " + libfilename); 1846 } 1847 } 1848 for (int i = 0 ; i < sys_paths.length ; i++) { 1849 File libfile = new File(sys_paths[i], System.mapLibraryName(name)); 1850 if (loadLibrary0(fromClass, libfile)) { 1851 return; 1852 } 1853 } 1854 if (loader != null) { 1855 for (int i = 0 ; i < usr_paths.length ; i++) { 1856 File libfile = new File(usr_paths[i], 1857 System.mapLibraryName(name)); 1858 if (loadLibrary0(fromClass, libfile)) { 1859 return; 1860 } 1861 } 1862 } 1863 // Oops, it failed 1864 throw new UnsatisfiedLinkError("no " + name + " in java.library.path"); 1865 } 1866 1867 private static boolean loadLibrary0(Class fromClass, final File file) { 1868 boolean exists = AccessController.doPrivileged( 1869 new PrivilegedAction<Object>() { 1870 public Object run() { 1871 return file.exists() ? Boolean.TRUE : null; 1872 }}) 1873 != null; 1874 if (!exists) { 1875 return false; 1876 } 1877 String name; 1878 try { 1879 name = file.getCanonicalPath(); 1880 } catch (IOException e) { 1881 return false; 1882 } 1883 ClassLoader loader = 1884 (fromClass == null) ? null : fromClass.getClassLoader(); 1885 Vector<NativeLibrary> libs = 1886 loader != null ? loader.nativeLibraries : systemNativeLibraries; 1887 synchronized (libs) { 1888 int size = libs.size(); 1889 for (int i = 0; i < size; i++) { 1890 NativeLibrary lib = libs.elementAt(i); 1891 if (name.equals(lib.name)) { 1892 return true; 1893 } 1894 } 1895 1896 synchronized (loadedLibraryNames) { 1897 if (loadedLibraryNames.contains(name)) { 1898 throw new UnsatisfiedLinkError 1899 ("Native Library " + 1900 name + 1901 " already loaded in another classloader"); 1902 } 1903 /* If the library is being loaded (must be by the same thread, 1904 * because Runtime.load and Runtime.loadLibrary are 1905 * synchronous). The reason is can occur is that the JNI_OnLoad 1906 * function can cause another loadLibrary invocation. 1907 * 1908 * Thus we can use a static stack to hold the list of libraries 1909 * we are loading. 1910 * 1911 * If there is a pending load operation for the library, we 1912 * immediately return success; otherwise, we raise 1913 * UnsatisfiedLinkError. 1914 */ 1915 int n = nativeLibraryContext.size(); 1916 for (int i = 0; i < n; i++) { 1917 NativeLibrary lib = nativeLibraryContext.elementAt(i); 1918 if (name.equals(lib.name)) { 1919 if (loader == lib.fromClass.getClassLoader()) { 1920 return true; 1921 } else { 1922 throw new UnsatisfiedLinkError 1923 ("Native Library " + 1924 name + 1925 " is being loaded in another classloader"); 1926 } 1927 } 1928 } 1929 NativeLibrary lib = new NativeLibrary(fromClass, name); 1930 nativeLibraryContext.push(lib); 1931 try { 1932 lib.load(name); 1933 } finally { 1934 nativeLibraryContext.pop(); 1935 } 1936 if (lib.handle != 0) { 1937 loadedLibraryNames.addElement(name); 1938 libs.addElement(lib); 1939 return true; 1940 } 1941 return false; 1942 } 1943 } 1944 } 1945 1946 // Invoked in the VM class linking code. 1947 static long findNative(ClassLoader loader, String name) { 1948 Vector<NativeLibrary> libs = 1949 loader != null ? loader.nativeLibraries : systemNativeLibraries; 1950 synchronized (libs) { 1951 int size = libs.size(); 1952 for (int i = 0; i < size; i++) { 1953 NativeLibrary lib = libs.elementAt(i); 1954 long entry = lib.find(name); 1955 if (entry != 0) 1956 return entry; 1957 } 1958 } 1959 return 0; 1960 } 1961 1962 1963 // -- Assertion management -- 1964 1965 final Object assertionLock; 1966 1967 // The default toggle for assertion checking. 1968 // @GuardedBy("assertionLock") 1969 private boolean defaultAssertionStatus = false; 1970 1971 // Maps String packageName to Boolean package default assertion status Note 1972 // that the default package is placed under a null map key. If this field 1973 // is null then we are delegating assertion status queries to the VM, i.e., 1974 // none of this ClassLoader's assertion status modification methods have 1975 // been invoked. 1976 // @GuardedBy("assertionLock") 1977 private Map<String, Boolean> packageAssertionStatus = null; 1978 1979 // Maps String fullyQualifiedClassName to Boolean assertionStatus If this 1980 // field is null then we are delegating assertion status queries to the VM, 1981 // i.e., none of this ClassLoader's assertion status modification methods 1982 // have been invoked. 1983 // @GuardedBy("assertionLock") 1984 Map<String, Boolean> classAssertionStatus = null; 1985 1986 /** 1987 * Sets the default assertion status for this class loader. This setting 1988 * determines whether classes loaded by this class loader and initialized 1989 * in the future will have assertions enabled or disabled by default. 1990 * This setting may be overridden on a per-package or per-class basis by 1991 * invoking {@link #setPackageAssertionStatus(String, boolean)} or {@link 1992 * #setClassAssertionStatus(String, boolean)}. </p> 1993 * 1994 * @param enabled 1995 * <tt>true</tt> if classes loaded by this class loader will 1996 * henceforth have assertions enabled by default, <tt>false</tt> 1997 * if they will have assertions disabled by default. 1998 * 1999 * @since 1.4 2000 */ 2001 public void setDefaultAssertionStatus(boolean enabled) { 2002 synchronized (assertionLock) { 2003 if (classAssertionStatus == null) 2004 initializeJavaAssertionMaps(); 2005 2006 defaultAssertionStatus = enabled; 2007 } 2008 } 2009 2010 /** 2011 * Sets the package default assertion status for the named package. The 2012 * package default assertion status determines the assertion status for 2013 * classes initialized in the future that belong to the named package or 2014 * any of its "subpackages". 2015 * 2016 * <p> A subpackage of a package named p is any package whose name begins 2017 * with "<tt>p.</tt>". For example, <tt>javax.swing.text</tt> is a 2018 * subpackage of <tt>javax.swing</tt>, and both <tt>java.util</tt> and 2019 * <tt>java.lang.reflect</tt> are subpackages of <tt>java</tt>. 2020 * 2021 * <p> In the event that multiple package defaults apply to a given class, 2022 * the package default pertaining to the most specific package takes 2023 * precedence over the others. For example, if <tt>javax.lang</tt> and 2024 * <tt>javax.lang.reflect</tt> both have package defaults associated with 2025 * them, the latter package default applies to classes in 2026 * <tt>javax.lang.reflect</tt>. 2027 * 2028 * <p> Package defaults take precedence over the class loader's default 2029 * assertion status, and may be overridden on a per-class basis by invoking 2030 * {@link #setClassAssertionStatus(String, boolean)}. </p> 2031 * 2032 * @param packageName 2033 * The name of the package whose package default assertion status 2034 * is to be set. A <tt>null</tt> value indicates the unnamed 2035 * package that is "current" 2036 * (<a href="http://java.sun.com/docs/books/jls/">Java Language 2037 * Specification</a>, section 7.4.2). 2038 * 2039 * @param enabled 2040 * <tt>true</tt> if classes loaded by this classloader and 2041 * belonging to the named package or any of its subpackages will 2042 * have assertions enabled by default, <tt>false</tt> if they will 2043 * have assertions disabled by default. 2044 * 2045 * @since 1.4 2046 */ 2047 public void setPackageAssertionStatus(String packageName, 2048 boolean enabled) { 2049 synchronized (assertionLock) { 2050 if (packageAssertionStatus == null) 2051 initializeJavaAssertionMaps(); 2052 2053 packageAssertionStatus.put(packageName, enabled); 2054 } 2055 } 2056 2057 /** 2058 * Sets the desired assertion status for the named top-level class in this 2059 * class loader and any nested classes contained therein. This setting 2060 * takes precedence over the class loader's default assertion status, and 2061 * over any applicable per-package default. This method has no effect if 2062 * the named class has already been initialized. (Once a class is 2063 * initialized, its assertion status cannot change.) 2064 * 2065 * <p> If the named class is not a top-level class, this invocation will 2066 * have no effect on the actual assertion status of any class. </p> 2067 * 2068 * @param className 2069 * The fully qualified class name of the top-level class whose 2070 * assertion status is to be set. 2071 * 2072 * @param enabled 2073 * <tt>true</tt> if the named class is to have assertions 2074 * enabled when (and if) it is initialized, <tt>false</tt> if the 2075 * class is to have assertions disabled. 2076 * 2077 * @since 1.4 2078 */ 2079 public void setClassAssertionStatus(String className, boolean enabled) { 2080 synchronized (assertionLock) { 2081 if (classAssertionStatus == null) 2082 initializeJavaAssertionMaps(); 2083 2084 classAssertionStatus.put(className, enabled); 2085 } 2086 } 2087 2088 /** 2089 * Sets the default assertion status for this class loader to 2090 * <tt>false</tt> and discards any package defaults or class assertion 2091 * status settings associated with the class loader. This method is 2092 * provided so that class loaders can be made to ignore any command line or 2093 * persistent assertion status settings and "start with a clean slate." 2094 * </p> 2095 * 2096 * @since 1.4 2097 */ 2098 public void clearAssertionStatus() { 2099 /* 2100 * Whether or not "Java assertion maps" are initialized, set 2101 * them to empty maps, effectively ignoring any present settings. 2102 */ 2103 synchronized (assertionLock) { 2104 classAssertionStatus = new HashMap<String, Boolean>(); 2105 packageAssertionStatus = new HashMap<String, Boolean>(); 2106 defaultAssertionStatus = false; 2107 } 2108 } 2109 2110 /** 2111 * Returns the assertion status that would be assigned to the specified 2112 * class if it were to be initialized at the time this method is invoked. 2113 * If the named class has had its assertion status set, the most recent 2114 * setting will be returned; otherwise, if any package default assertion 2115 * status pertains to this class, the most recent setting for the most 2116 * specific pertinent package default assertion status is returned; 2117 * otherwise, this class loader's default assertion status is returned. 2118 * </p> 2119 * 2120 * @param className 2121 * The fully qualified class name of the class whose desired 2122 * assertion status is being queried. 2123 * 2124 * @return The desired assertion status of the specified class. 2125 * 2126 * @see #setClassAssertionStatus(String, boolean) 2127 * @see #setPackageAssertionStatus(String, boolean) 2128 * @see #setDefaultAssertionStatus(boolean) 2129 * 2130 * @since 1.4 2131 */ 2132 boolean desiredAssertionStatus(String className) { 2133 synchronized (assertionLock) { 2134 // assert classAssertionStatus != null; 2135 // assert packageAssertionStatus != null; 2136 2137 // Check for a class entry 2138 Boolean result = classAssertionStatus.get(className); 2139 if (result != null) 2140 return result.booleanValue(); 2141 2142 // Check for most specific package entry 2143 int dotIndex = className.lastIndexOf("."); 2144 if (dotIndex < 0) { // default package 2145 result = packageAssertionStatus.get(null); 2146 if (result != null) 2147 return result.booleanValue(); 2148 } 2149 while(dotIndex > 0) { 2150 className = className.substring(0, dotIndex); 2151 result = packageAssertionStatus.get(className); 2152 if (result != null) 2153 return result.booleanValue(); 2154 dotIndex = className.lastIndexOf(".", dotIndex-1); 2155 } 2156 2157 // Return the classloader default 2158 return defaultAssertionStatus; 2159 } 2160 } 2161 2162 // Set up the assertions with information provided by the VM. 2163 // Note: Should only be called inside a synchronized block 2164 private void initializeJavaAssertionMaps() { 2165 // assert Thread.holdsLock(assertionLock); 2166 2167 classAssertionStatus = new HashMap<String, Boolean>(); 2168 packageAssertionStatus = new HashMap<String, Boolean>(); 2169 AssertionStatusDirectives directives = retrieveDirectives(); 2170 2171 for(int i = 0; i < directives.classes.length; i++) 2172 classAssertionStatus.put(directives.classes[i], 2173 directives.classEnabled[i]); 2174 2175 for(int i = 0; i < directives.packages.length; i++) 2176 packageAssertionStatus.put(directives.packages[i], 2177 directives.packageEnabled[i]); 2178 2179 defaultAssertionStatus = directives.deflt; 2180 } 2181 2182 // Retrieves the assertion directives from the VM. 2183 private static native AssertionStatusDirectives retrieveDirectives(); 2184 } 2185 2186 2187 class SystemClassLoaderAction 2188 implements PrivilegedExceptionAction<ClassLoader> { 2189 private ClassLoader parent; 2190 2191 SystemClassLoaderAction(ClassLoader parent) { 2192 this.parent = parent; 2193 } 2194 2195 public ClassLoader run() throws Exception { 2196 String cls = System.getProperty("java.system.class.loader"); 2197 if (cls == null) { 2198 return parent; 2199 } 2200 2201 Constructor ctor = Class.forName(cls, true, parent) 2202 .getDeclaredConstructor(new Class[] { ClassLoader.class }); 2203 ClassLoader sys = (ClassLoader) ctor.newInstance( 2204 new Object[] { parent }); 2205 Thread.currentThread().setContextClassLoader(sys); 2206 return sys; 2207 } 2208 }