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