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.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 the <a 164 * href="http://java.sun.com/docs/books/jls/">Java Language Specification</a>. 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 the <a 535 * href="http://java.sun.com/docs/books/vmspec/">Java Virtual 536 * Machine Specification</a>. 537 * 538 * @param off 539 * The start offset in <tt>b</tt> of the class data 540 * 541 * @param len 542 * The length of the class data 543 * 544 * @return The <tt>Class</tt> object that was created from the specified 545 * class data 546 * 547 * @throws ClassFormatError 548 * If the data did not contain a valid class 549 * 550 * @throws IndexOutOfBoundsException 551 * If either <tt>off</tt> or <tt>len</tt> is negative, or if 552 * <tt>off+len</tt> is greater than <tt>b.length</tt>. 553 * 554 * @throws SecurityException 555 * If an attempt is made to add this class to a package that 556 * contains classes that were signed by a different set of 557 * certificates than this class, or if an attempt is made 558 * to define a class in a package with a fully-qualified name 559 * that starts with "{@code java.}". 560 * 561 * @see #loadClass(String, boolean) 562 * @see #resolveClass(Class) 563 * 564 * @deprecated Replaced by {@link #defineClass(String, byte[], int, int) 565 * defineClass(String, byte[], int, int)} 566 */ 567 @Deprecated 568 protected final Class<?> defineClass(byte[] b, int off, int len) 569 throws ClassFormatError 570 { 571 return defineClass(null, b, off, len, null); 572 } 573 574 /** 575 * Converts an array of bytes into an instance of class <tt>Class</tt>. 576 * Before the <tt>Class</tt> can be used it must be resolved. 577 * 578 * <p> This method assigns a default {@link java.security.ProtectionDomain 579 * <tt>ProtectionDomain</tt>} to the newly defined class. The 580 * <tt>ProtectionDomain</tt> is effectively granted the same set of 581 * permissions returned when {@link 582 * java.security.Policy#getPermissions(java.security.CodeSource) 583 * <tt>Policy.getPolicy().getPermissions(new CodeSource(null, null))</tt>} 584 * is invoked. The default domain is created on the first invocation of 585 * {@link #defineClass(String, byte[], int, int) <tt>defineClass</tt>}, 586 * and re-used on subsequent invocations. 587 * 588 * <p> To assign a specific <tt>ProtectionDomain</tt> to the class, use 589 * the {@link #defineClass(String, byte[], int, int, 590 * java.security.ProtectionDomain) <tt>defineClass</tt>} method that takes a 591 * <tt>ProtectionDomain</tt> as one of its arguments. </p> 592 * 593 * @param name 594 * The expected <a href="#name">binary name</a> of the class, or 595 * <tt>null</tt> if not known 596 * 597 * @param b 598 * The bytes that make up the class data. The bytes in positions 599 * <tt>off</tt> through <tt>off+len-1</tt> should have the format 600 * of a valid class file as defined by the <a 601 * href="http://java.sun.com/docs/books/vmspec/">Java Virtual 602 * Machine Specification</a>. 603 * 604 * @param off 605 * The start offset in <tt>b</tt> of the class data 606 * 607 * @param len 608 * The length of the class data 609 * 610 * @return The <tt>Class</tt> object that was created from the specified 611 * class data. 612 * 613 * @throws ClassFormatError 614 * If the data did not contain a valid class 615 * 616 * @throws IndexOutOfBoundsException 617 * If either <tt>off</tt> or <tt>len</tt> is negative, or if 618 * <tt>off+len</tt> is greater than <tt>b.length</tt>. 619 * 620 * @throws SecurityException 621 * If an attempt is made to add this class to a package that 622 * contains classes that were signed by a different set of 623 * certificates than this class (which is unsigned), or if 624 * <tt>name</tt> begins with "<tt>java.</tt>". 625 * 626 * @see #loadClass(String, boolean) 627 * @see #resolveClass(Class) 628 * @see java.security.CodeSource 629 * @see java.security.SecureClassLoader 630 * 631 * @since 1.1 632 */ 633 protected final Class<?> defineClass(String name, byte[] b, int off, int len) 634 throws ClassFormatError 635 { 636 return defineClass(name, b, off, len, null); 637 } 638 639 /* Determine protection domain, and check that: 640 - not define java.* class, 641 - signer of this class matches signers for the rest of the classes in 642 package. 643 */ 644 private ProtectionDomain preDefineClass(String name, 645 ProtectionDomain pd) 646 { 647 if (!checkName(name)) 648 throw new NoClassDefFoundError("IllegalName: " + name); 649 650 if ((name != null) && name.startsWith("java.")) { 651 throw new SecurityException 652 ("Prohibited package name: " + 653 name.substring(0, name.lastIndexOf('.'))); 654 } 655 if (pd == null) { 656 pd = defaultDomain; 657 } 658 659 if (name != null) checkCerts(name, pd.getCodeSource()); 660 661 return pd; 662 } 663 664 private String defineClassSourceLocation(ProtectionDomain pd) 665 { 666 CodeSource cs = pd.getCodeSource(); 667 String source = null; 668 if (cs != null && cs.getLocation() != null) { 669 source = cs.getLocation().toString(); 670 } 671 return source; 672 } 673 674 private Class defineTransformedClass(String name, byte[] b, int off, int len, 675 ProtectionDomain pd, 676 ClassFormatError cfe, String source) 677 throws ClassFormatError 678 { 679 // Class format error - try to transform the bytecode and 680 // define the class again 681 // 682 ClassFileTransformer[] transformers = 683 ClassFileTransformer.getTransformers(); 684 Class c = null; 685 686 if (transformers != null) { 687 for (ClassFileTransformer transformer : transformers) { 688 try { 689 // Transform byte code using transformer 690 byte[] tb = transformer.transform(b, off, len); 691 c = defineClass1(name, tb, 0, tb.length, 692 pd, source); 693 break; 694 } catch (ClassFormatError cfe2) { 695 // If ClassFormatError occurs, try next transformer 696 } 697 } 698 } 699 700 // Rethrow original ClassFormatError if unable to transform 701 // bytecode to well-formed 702 // 703 if (c == null) 704 throw cfe; 705 706 return c; 707 } 708 709 private void postDefineClass(Class c, ProtectionDomain pd) 710 { 711 if (pd.getCodeSource() != null) { 712 Certificate certs[] = pd.getCodeSource().getCertificates(); 713 if (certs != null) 714 setSigners(c, certs); 715 } 716 } 717 718 /** 719 * Converts an array of bytes into an instance of class <tt>Class</tt>, 720 * with an optional <tt>ProtectionDomain</tt>. If the domain is 721 * <tt>null</tt>, then a default domain will be assigned to the class as 722 * specified in the documentation for {@link #defineClass(String, byte[], 723 * int, int)}. Before the class can be used it must be resolved. 724 * 725 * <p> The first class defined in a package determines the exact set of 726 * certificates that all subsequent classes defined in that package must 727 * contain. The set of certificates for a class is obtained from the 728 * {@link java.security.CodeSource <tt>CodeSource</tt>} within the 729 * <tt>ProtectionDomain</tt> of the class. Any classes added to that 730 * package must contain the same set of certificates or a 731 * <tt>SecurityException</tt> will be thrown. Note that if 732 * <tt>name</tt> is <tt>null</tt>, this check is not performed. 733 * You should always pass in the <a href="#name">binary name</a> of the 734 * class you are defining as well as the bytes. This ensures that the 735 * class you are defining is indeed the class you think it is. 736 * 737 * <p> The specified <tt>name</tt> cannot begin with "<tt>java.</tt>", since 738 * all classes in the "<tt>java.*</tt> packages can only be defined by the 739 * bootstrap class loader. If <tt>name</tt> is not <tt>null</tt>, it 740 * must be equal to the <a href="#name">binary name</a> of the class 741 * specified by the byte array "<tt>b</tt>", otherwise a {@link 742 * <tt>NoClassDefFoundError</tt>} will be thrown. </p> 743 * 744 * @param name 745 * The expected <a href="#name">binary name</a> of the class, or 746 * <tt>null</tt> if not known 747 * 748 * @param b 749 * The bytes that make up the class data. The bytes in positions 750 * <tt>off</tt> through <tt>off+len-1</tt> should have the format 751 * of a valid class file as defined by the <a 752 * href="http://java.sun.com/docs/books/vmspec/">Java Virtual 753 * Machine Specification</a>. 754 * 755 * @param off 756 * The start offset in <tt>b</tt> of the class data 757 * 758 * @param len 759 * The length of the class data 760 * 761 * @param protectionDomain 762 * The ProtectionDomain of the class 763 * 764 * @return The <tt>Class</tt> object created from the data, 765 * and optional <tt>ProtectionDomain</tt>. 766 * 767 * @throws ClassFormatError 768 * If the data did not contain a valid class 769 * 770 * @throws NoClassDefFoundError 771 * If <tt>name</tt> is not equal to the <a href="#name">binary 772 * name</a> of the class specified by <tt>b</tt> 773 * 774 * @throws IndexOutOfBoundsException 775 * If either <tt>off</tt> or <tt>len</tt> is negative, or if 776 * <tt>off+len</tt> is greater than <tt>b.length</tt>. 777 * 778 * @throws SecurityException 779 * If an attempt is made to add this class to a package that 780 * contains classes that were signed by a different set of 781 * certificates than this class, or if <tt>name</tt> begins with 782 * "<tt>java.</tt>". 783 */ 784 protected final Class<?> defineClass(String name, byte[] b, int off, int len, 785 ProtectionDomain protectionDomain) 786 throws ClassFormatError 787 { 788 protectionDomain = preDefineClass(name, protectionDomain); 789 790 Class c = null; 791 String source = defineClassSourceLocation(protectionDomain); 792 793 try { 794 c = defineClass1(name, b, off, len, protectionDomain, source); 795 } catch (ClassFormatError cfe) { 796 c = defineTransformedClass(name, b, off, len, protectionDomain, cfe, 797 source); 798 } 799 800 postDefineClass(c, protectionDomain); 801 return c; 802 } 803 804 /** 805 * Converts a {@link java.nio.ByteBuffer <tt>ByteBuffer</tt>} 806 * into an instance of class <tt>Class</tt>, 807 * with an optional <tt>ProtectionDomain</tt>. If the domain is 808 * <tt>null</tt>, then a default domain will be assigned to the class as 809 * specified in the documentation for {@link #defineClass(String, byte[], 810 * int, int)}. Before the class can be used it must be resolved. 811 * 812 * <p>The rules about the first class defined in a package determining the 813 * set of certificates for the package, and the restrictions on class names 814 * are identical to those specified in the documentation for {@link 815 * #defineClass(String, byte[], int, int, ProtectionDomain)}. 816 * 817 * <p> An invocation of this method of the form 818 * <i>cl</i><tt>.defineClass(</tt><i>name</i><tt>,</tt> 819 * <i>bBuffer</i><tt>,</tt> <i>pd</i><tt>)</tt> yields exactly the same 820 * result as the statements 821 * 822 * <blockquote><tt> 823 * ...<br> 824 * byte[] temp = new byte[</tt><i>bBuffer</i><tt>.{@link 825 * java.nio.ByteBuffer#remaining remaining}()];<br> 826 * </tt><i>bBuffer</i><tt>.{@link java.nio.ByteBuffer#get(byte[]) 827 * get}(temp);<br> 828 * return {@link #defineClass(String, byte[], int, int, ProtectionDomain) 829 * </tt><i>cl</i><tt>.defineClass}(</tt><i>name</i><tt>, temp, 0, 830 * temp.length, </tt><i>pd</i><tt>);<br> 831 * </tt></blockquote> 832 * 833 * @param name 834 * The expected <a href="#name">binary name</a>. of the class, or 835 * <tt>null</tt> if not known 836 * 837 * @param b 838 * The bytes that make up the class data. The bytes from positions 839 * <tt>b.position()</tt> through <tt>b.position() + b.limit() -1 840 * </tt> should have the format of a valid class file as defined by 841 * the <a href="http://java.sun.com/docs/books/vmspec/">Java Virtual 842 * Machine Specification</a>. 843 * 844 * @param protectionDomain 845 * The ProtectionDomain of the class, or <tt>null</tt>. 846 * 847 * @return The <tt>Class</tt> object created from the data, 848 * and optional <tt>ProtectionDomain</tt>. 849 * 850 * @throws ClassFormatError 851 * If the data did not contain a valid class. 852 * 853 * @throws NoClassDefFoundError 854 * If <tt>name</tt> is not equal to the <a href="#name">binary 855 * name</a> of the class specified by <tt>b</tt> 856 * 857 * @throws SecurityException 858 * If an attempt is made to add this class to a package that 859 * contains classes that were signed by a different set of 860 * certificates than this class, or if <tt>name</tt> begins with 861 * "<tt>java.</tt>". 862 * 863 * @see #defineClass(String, byte[], int, int, ProtectionDomain) 864 * 865 * @since 1.5 866 */ 867 protected final Class<?> defineClass(String name, java.nio.ByteBuffer b, 868 ProtectionDomain protectionDomain) 869 throws ClassFormatError 870 { 871 int len = b.remaining(); 872 873 // Use byte[] if not a direct ByteBufer: 874 if (!b.isDirect()) { 875 if (b.hasArray()) { 876 return defineClass(name, b.array(), 877 b.position() + b.arrayOffset(), len, 878 protectionDomain); 879 } else { 880 // no array, or read-only array 881 byte[] tb = new byte[len]; 882 b.get(tb); // get bytes out of byte buffer. 883 return defineClass(name, tb, 0, len, protectionDomain); 884 } 885 } 886 887 protectionDomain = preDefineClass(name, protectionDomain); 888 889 Class c = null; 890 String source = defineClassSourceLocation(protectionDomain); 891 892 try { 893 c = defineClass2(name, b, b.position(), len, protectionDomain, 894 source); 895 } catch (ClassFormatError cfe) { 896 byte[] tb = new byte[len]; 897 b.get(tb); // get bytes out of byte buffer. 898 c = defineTransformedClass(name, tb, 0, len, protectionDomain, cfe, 899 source); 900 } 901 902 postDefineClass(c, protectionDomain); 903 return c; 904 } 905 906 private native Class defineClass0(String name, byte[] b, int off, int len, 907 ProtectionDomain pd); 908 909 private native Class defineClass1(String name, byte[] b, int off, int len, 910 ProtectionDomain pd, String source); 911 912 private native Class defineClass2(String name, java.nio.ByteBuffer b, 913 int off, int len, ProtectionDomain pd, 914 String source); 915 916 // true if the name is null or has the potential to be a valid binary name 917 private boolean checkName(String name) { 918 if ((name == null) || (name.length() == 0)) 919 return true; 920 if ((name.indexOf('/') != -1) 921 || (!VM.allowArraySyntax() && (name.charAt(0) == '['))) 922 return false; 923 return true; 924 } 925 926 private void checkCerts(String name, CodeSource cs) { 927 int i = name.lastIndexOf('.'); 928 String pname = (i == -1) ? "" : name.substring(0, i); 929 930 Certificate[] certs = null; 931 if (cs != null) { 932 certs = cs.getCertificates(); 933 } 934 Certificate[] pcerts = null; 935 if (parallelLockMap == null) { 936 synchronized (this) { 937 pcerts = package2certs.get(pname); 938 if (pcerts == null) { 939 package2certs.put(pname, (certs == null? nocerts:certs)); 940 } 941 } 942 } else { 943 pcerts = ((ConcurrentHashMap<String, Certificate[]>)package2certs). 944 putIfAbsent(pname, (certs == null? nocerts:certs)); 945 } 946 if (pcerts != null && !compareCerts(pcerts, certs)) { 947 throw new SecurityException("class \""+ name + 948 "\"'s signer information does not match signer information of other classes in the same package"); 949 } 950 } 951 952 /** 953 * check to make sure the certs for the new class (certs) are the same as 954 * the certs for the first class inserted in the package (pcerts) 955 */ 956 private boolean compareCerts(Certificate[] pcerts, 957 Certificate[] certs) 958 { 959 // certs can be null, indicating no certs. 960 if ((certs == null) || (certs.length == 0)) { 961 return pcerts.length == 0; 962 } 963 964 // the length must be the same at this point 965 if (certs.length != pcerts.length) 966 return false; 967 968 // go through and make sure all the certs in one array 969 // are in the other and vice-versa. 970 boolean match; 971 for (int i = 0; i < certs.length; i++) { 972 match = false; 973 for (int j = 0; j < pcerts.length; j++) { 974 if (certs[i].equals(pcerts[j])) { 975 match = true; 976 break; 977 } 978 } 979 if (!match) return false; 980 } 981 982 // now do the same for pcerts 983 for (int i = 0; i < pcerts.length; i++) { 984 match = false; 985 for (int j = 0; j < certs.length; j++) { 986 if (pcerts[i].equals(certs[j])) { 987 match = true; 988 break; 989 } 990 } 991 if (!match) return false; 992 } 993 994 return true; 995 } 996 997 /** 998 * Links the specified class. This (misleadingly named) method may be 999 * used by a class loader to link a class. If the class <tt>c</tt> has 1000 * already been linked, then this method simply returns. Otherwise, the 1001 * class is linked as described in the "Execution" chapter of the <a 1002 * href="http://java.sun.com/docs/books/jls/">Java Language 1003 * Specification</a>. 1004 * </p> 1005 * 1006 * @param c 1007 * The class to link 1008 * 1009 * @throws NullPointerException 1010 * If <tt>c</tt> is <tt>null</tt>. 1011 * 1012 * @see #defineClass(String, byte[], int, int) 1013 */ 1014 protected final void resolveClass(Class<?> c) { 1015 resolveClass0(c); 1016 } 1017 1018 private native void resolveClass0(Class c); 1019 1020 /** 1021 * Finds a class with the specified <a href="#name">binary name</a>, 1022 * loading it if necessary. 1023 * 1024 * <p> This method loads the class through the system class loader (see 1025 * {@link #getSystemClassLoader()}). The <tt>Class</tt> object returned 1026 * might have more than one <tt>ClassLoader</tt> associated with it. 1027 * Subclasses of <tt>ClassLoader</tt> need not usually invoke this method, 1028 * because most class loaders need to override just {@link 1029 * #findClass(String)}. </p> 1030 * 1031 * @param name 1032 * The <a href="#name">binary name</a> of the class 1033 * 1034 * @return The <tt>Class</tt> object for the specified <tt>name</tt> 1035 * 1036 * @throws ClassNotFoundException 1037 * If the class could not be found 1038 * 1039 * @see #ClassLoader(ClassLoader) 1040 * @see #getParent() 1041 */ 1042 protected final Class<?> findSystemClass(String name) 1043 throws ClassNotFoundException 1044 { 1045 ClassLoader system = getSystemClassLoader(); 1046 if (system == null) { 1047 if (!checkName(name)) 1048 throw new ClassNotFoundException(name); 1049 Class cls = findBootstrapClass(name); 1050 if (cls == null) { 1051 throw new ClassNotFoundException(name); 1052 } 1053 return cls; 1054 } 1055 return system.loadClass(name); 1056 } 1057 1058 /** 1059 * Returns a class loaded by the bootstrap class loader; 1060 * or return null if not found. 1061 */ 1062 private Class findBootstrapClassOrNull(String name) 1063 { 1064 if (!checkName(name)) return null; 1065 1066 return findBootstrapClass(name); 1067 } 1068 1069 // return null if not found 1070 private native Class findBootstrapClass(String name); 1071 1072 /** 1073 * Returns the class with the given <a href="#name">binary name</a> if this 1074 * loader has been recorded by the Java virtual machine as an initiating 1075 * loader of a class with that <a href="#name">binary name</a>. Otherwise 1076 * <tt>null</tt> is returned. </p> 1077 * 1078 * @param name 1079 * The <a href="#name">binary name</a> of the class 1080 * 1081 * @return The <tt>Class</tt> object, or <tt>null</tt> if the class has 1082 * not been loaded 1083 * 1084 * @since 1.1 1085 */ 1086 protected final Class<?> findLoadedClass(String name) { 1087 if (!checkName(name)) 1088 return null; 1089 return findLoadedClass0(name); 1090 } 1091 1092 private native final Class findLoadedClass0(String name); 1093 1094 /** 1095 * Sets the signers of a class. This should be invoked after defining a 1096 * class. </p> 1097 * 1098 * @param c 1099 * The <tt>Class</tt> object 1100 * 1101 * @param signers 1102 * The signers for the class 1103 * 1104 * @since 1.1 1105 */ 1106 protected final void setSigners(Class<?> c, Object[] signers) { 1107 c.setSigners(signers); 1108 } 1109 1110 1111 // -- Resource -- 1112 1113 /** 1114 * Finds the resource with the given name. A resource is some data 1115 * (images, audio, text, etc) that can be accessed by class code in a way 1116 * that is independent of the location of the code. 1117 * 1118 * <p> The name of a resource is a '<tt>/</tt>'-separated path name that 1119 * identifies the resource. 1120 * 1121 * <p> This method will first search the parent class loader for the 1122 * resource; if the parent is <tt>null</tt> the path of the class loader 1123 * built-in to the virtual machine is searched. That failing, this method 1124 * will invoke {@link #findResource(String)} to find the resource. </p> 1125 * 1126 * @param name 1127 * The resource name 1128 * 1129 * @return A <tt>URL</tt> object for reading the resource, or 1130 * <tt>null</tt> if the resource could not be found or the invoker 1131 * doesn't have adequate privileges to get the resource. 1132 * 1133 * @since 1.1 1134 */ 1135 public URL getResource(String name) { 1136 URL url; 1137 if (parent != null) { 1138 url = parent.getResource(name); 1139 } else { 1140 url = getBootstrapResource(name); 1141 } 1142 if (url == null) { 1143 url = findResource(name); 1144 } 1145 return url; 1146 } 1147 1148 /** 1149 * Finds all the resources with the given name. A resource is some data 1150 * (images, audio, text, etc) that can be accessed by class code in a way 1151 * that is independent of the location of the code. 1152 * 1153 * <p>The name of a resource is a <tt>/</tt>-separated path name that 1154 * identifies the resource. 1155 * 1156 * <p> The search order is described in the documentation for {@link 1157 * #getResource(String)}. </p> 1158 * 1159 * @param name 1160 * The resource name 1161 * 1162 * @return An enumeration of {@link java.net.URL <tt>URL</tt>} objects for 1163 * the resource. If no resources could be found, the enumeration 1164 * will be empty. Resources that the class loader doesn't have 1165 * access to will not be in the enumeration. 1166 * 1167 * @throws IOException 1168 * If I/O errors occur 1169 * 1170 * @see #findResources(String) 1171 * 1172 * @since 1.2 1173 */ 1174 public Enumeration<URL> getResources(String name) throws IOException { 1175 Enumeration[] tmp = new Enumeration[2]; 1176 if (parent != null) { 1177 tmp[0] = parent.getResources(name); 1178 } else { 1179 tmp[0] = getBootstrapResources(name); 1180 } 1181 tmp[1] = findResources(name); 1182 1183 return new CompoundEnumeration<>(tmp); 1184 } 1185 1186 /** 1187 * Finds the resource with the given name. Class loader implementations 1188 * should override this method to specify where to find resources. </p> 1189 * 1190 * @param name 1191 * The resource name 1192 * 1193 * @return A <tt>URL</tt> object for reading the resource, or 1194 * <tt>null</tt> if the resource could not be found 1195 * 1196 * @since 1.2 1197 */ 1198 protected URL findResource(String name) { 1199 return null; 1200 } 1201 1202 /** 1203 * Returns an enumeration of {@link java.net.URL <tt>URL</tt>} objects 1204 * representing all the resources with the given name. Class loader 1205 * implementations should override this method to specify where to load 1206 * resources from. </p> 1207 * 1208 * @param name 1209 * The resource name 1210 * 1211 * @return An enumeration of {@link java.net.URL <tt>URL</tt>} objects for 1212 * the resources 1213 * 1214 * @throws IOException 1215 * If I/O errors occur 1216 * 1217 * @since 1.2 1218 */ 1219 protected Enumeration<URL> findResources(String name) throws IOException { 1220 return java.util.Collections.emptyEnumeration(); 1221 } 1222 1223 // index 0: java.lang.ClassLoader.class 1224 // index 1: the immediate caller of index 0. 1225 // index 2: the immediate caller of index 1. 1226 private static native Class<? extends ClassLoader> getCaller(int index); 1227 1228 /** 1229 * Registers the caller as parallel capable.</p> 1230 * The registration succeeds if and only if all of the following 1231 * conditions are met: <br> 1232 * 1. no instance of the caller has been created</p> 1233 * 2. all of the super classes (except class Object) of the caller are 1234 * registered as parallel capable</p> 1235 * Note that once a class loader is registered as parallel capable, there 1236 * is no way to change it back. </p> 1237 * 1238 * @return true if the caller is successfully registered as 1239 * parallel capable and false if otherwise. 1240 * 1241 * @since 1.7 1242 */ 1243 protected static boolean registerAsParallelCapable() { 1244 return ParallelLoaders.register(getCaller(1)); 1245 } 1246 1247 /** 1248 * Find a resource of the specified name from the search path used to load 1249 * classes. This method locates the resource through the system class 1250 * loader (see {@link #getSystemClassLoader()}). </p> 1251 * 1252 * @param name 1253 * The resource name 1254 * 1255 * @return A {@link java.net.URL <tt>URL</tt>} object for reading the 1256 * resource, or <tt>null</tt> if the resource could not be found 1257 * 1258 * @since 1.1 1259 */ 1260 public static URL getSystemResource(String name) { 1261 ClassLoader system = getSystemClassLoader(); 1262 if (system == null) { 1263 return getBootstrapResource(name); 1264 } 1265 return system.getResource(name); 1266 } 1267 1268 /** 1269 * Finds all resources of the specified name from the search path used to 1270 * load classes. The resources thus found are returned as an 1271 * {@link java.util.Enumeration <tt>Enumeration</tt>} of {@link 1272 * java.net.URL <tt>URL</tt>} objects. 1273 * 1274 * <p> The search order is described in the documentation for {@link 1275 * #getSystemResource(String)}. </p> 1276 * 1277 * @param name 1278 * The resource name 1279 * 1280 * @return An enumeration of resource {@link java.net.URL <tt>URL</tt>} 1281 * objects 1282 * 1283 * @throws IOException 1284 * If I/O errors occur 1285 1286 * @since 1.2 1287 */ 1288 public static Enumeration<URL> getSystemResources(String name) 1289 throws IOException 1290 { 1291 ClassLoader system = getSystemClassLoader(); 1292 if (system == null) { 1293 return getBootstrapResources(name); 1294 } 1295 return system.getResources(name); 1296 } 1297 1298 /** 1299 * Find resources from the VM's built-in classloader. 1300 */ 1301 private static URL getBootstrapResource(String name) { 1302 URLClassPath ucp = getBootstrapClassPath(); 1303 Resource res = ucp.getResource(name); 1304 return res != null ? res.getURL() : null; 1305 } 1306 1307 /** 1308 * Find resources from the VM's built-in classloader. 1309 */ 1310 private static Enumeration<URL> getBootstrapResources(String name) 1311 throws IOException 1312 { 1313 final Enumeration<Resource> e = 1314 getBootstrapClassPath().getResources(name); 1315 return new Enumeration<URL> () { 1316 public URL nextElement() { 1317 return e.nextElement().getURL(); 1318 } 1319 public boolean hasMoreElements() { 1320 return e.hasMoreElements(); 1321 } 1322 }; 1323 } 1324 1325 // Returns the URLClassPath that is used for finding system resources. 1326 static URLClassPath getBootstrapClassPath() { 1327 return sun.misc.Launcher.getBootstrapClassPath(); 1328 } 1329 1330 1331 /** 1332 * Returns an input stream for reading the specified resource. 1333 * 1334 * <p> The search order is described in the documentation for {@link 1335 * #getResource(String)}. </p> 1336 * 1337 * @param name 1338 * The resource name 1339 * 1340 * @return An input stream for reading the resource, or <tt>null</tt> 1341 * if the resource could not be found 1342 * 1343 * @since 1.1 1344 */ 1345 public InputStream getResourceAsStream(String name) { 1346 URL url = getResource(name); 1347 try { 1348 return url != null ? url.openStream() : null; 1349 } catch (IOException e) { 1350 return null; 1351 } 1352 } 1353 1354 /** 1355 * Open for reading, a resource of the specified name from the search path 1356 * used to load classes. This method locates the resource through the 1357 * system class loader (see {@link #getSystemClassLoader()}). </p> 1358 * 1359 * @param name 1360 * The resource name 1361 * 1362 * @return An input stream for reading the resource, or <tt>null</tt> 1363 * if the resource could not be found 1364 * 1365 * @since 1.1 1366 */ 1367 public static InputStream getSystemResourceAsStream(String name) { 1368 URL url = getSystemResource(name); 1369 try { 1370 return url != null ? url.openStream() : null; 1371 } catch (IOException e) { 1372 return null; 1373 } 1374 } 1375 1376 1377 // -- Hierarchy -- 1378 1379 /** 1380 * Returns the parent class loader for delegation. Some implementations may 1381 * use <tt>null</tt> to represent the bootstrap class loader. This method 1382 * will return <tt>null</tt> in such implementations if this class loader's 1383 * parent is the bootstrap class loader. 1384 * 1385 * <p> If a security manager is present, and the invoker's class loader is 1386 * not <tt>null</tt> and is not an ancestor of this class loader, then this 1387 * method invokes the security manager's {@link 1388 * SecurityManager#checkPermission(java.security.Permission) 1389 * <tt>checkPermission</tt>} method with a {@link 1390 * RuntimePermission#RuntimePermission(String) 1391 * <tt>RuntimePermission("getClassLoader")</tt>} permission to verify 1392 * access to the parent class loader is permitted. If not, a 1393 * <tt>SecurityException</tt> will be thrown. </p> 1394 * 1395 * @return The parent <tt>ClassLoader</tt> 1396 * 1397 * @throws SecurityException 1398 * If a security manager exists and its <tt>checkPermission</tt> 1399 * method doesn't allow access to this class loader's parent class 1400 * loader. 1401 * 1402 * @since 1.2 1403 */ 1404 public final ClassLoader getParent() { 1405 if (parent == null) 1406 return null; 1407 SecurityManager sm = System.getSecurityManager(); 1408 if (sm != null) { 1409 ClassLoader ccl = getCallerClassLoader(); 1410 if (ccl != null && !isAncestor(ccl)) { 1411 sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); 1412 } 1413 } 1414 return parent; 1415 } 1416 1417 /** 1418 * Returns the system class loader for delegation. This is the default 1419 * delegation parent for new <tt>ClassLoader</tt> instances, and is 1420 * typically the class loader used to start the application. 1421 * 1422 * <p> This method is first invoked early in the runtime's startup 1423 * sequence, at which point it creates the system class loader and sets it 1424 * as the context class loader of the invoking <tt>Thread</tt>. 1425 * 1426 * <p> The default system class loader is an implementation-dependent 1427 * instance of this class. 1428 * 1429 * <p> If the system property "<tt>java.system.class.loader</tt>" is defined 1430 * when this method is first invoked then the value of that property is 1431 * taken to be the name of a class that will be returned as the system 1432 * class loader. The class is loaded using the default system class loader 1433 * and must define a public constructor that takes a single parameter of 1434 * type <tt>ClassLoader</tt> which is used as the delegation parent. An 1435 * instance is then created using this constructor with the default system 1436 * class loader as the parameter. The resulting class loader is defined 1437 * to be the system class loader. 1438 * 1439 * <p> If a security manager is present, and the invoker's class loader is 1440 * not <tt>null</tt> and the invoker's class loader is not the same as or 1441 * an ancestor of the system class loader, then this method invokes the 1442 * security manager's {@link 1443 * SecurityManager#checkPermission(java.security.Permission) 1444 * <tt>checkPermission</tt>} method with a {@link 1445 * RuntimePermission#RuntimePermission(String) 1446 * <tt>RuntimePermission("getClassLoader")</tt>} permission to verify 1447 * access to the system class loader. If not, a 1448 * <tt>SecurityException</tt> will be thrown. </p> 1449 * 1450 * @return The system <tt>ClassLoader</tt> for delegation, or 1451 * <tt>null</tt> if none 1452 * 1453 * @throws SecurityException 1454 * If a security manager exists and its <tt>checkPermission</tt> 1455 * method doesn't allow access to the system class loader. 1456 * 1457 * @throws IllegalStateException 1458 * If invoked recursively during the construction of the class 1459 * loader specified by the "<tt>java.system.class.loader</tt>" 1460 * property. 1461 * 1462 * @throws Error 1463 * If the system property "<tt>java.system.class.loader</tt>" 1464 * is defined but the named class could not be loaded, the 1465 * provider class does not define the required constructor, or an 1466 * exception is thrown by that constructor when it is invoked. The 1467 * underlying cause of the error can be retrieved via the 1468 * {@link Throwable#getCause()} method. 1469 * 1470 * @revised 1.4 1471 */ 1472 public static ClassLoader getSystemClassLoader() { 1473 initSystemClassLoader(); 1474 if (scl == null) { 1475 return null; 1476 } 1477 SecurityManager sm = System.getSecurityManager(); 1478 if (sm != null) { 1479 ClassLoader ccl = getCallerClassLoader(); 1480 if (ccl != null && ccl != scl && !scl.isAncestor(ccl)) { 1481 sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); 1482 } 1483 } 1484 return scl; 1485 } 1486 1487 private static synchronized void initSystemClassLoader() { 1488 if (!sclSet) { 1489 if (scl != null) 1490 throw new IllegalStateException("recursive invocation"); 1491 sun.misc.Launcher l = sun.misc.Launcher.getLauncher(); 1492 if (l != null) { 1493 Throwable oops = null; 1494 scl = l.getClassLoader(); 1495 try { 1496 scl = AccessController.doPrivileged( 1497 new SystemClassLoaderAction(scl)); 1498 } catch (PrivilegedActionException pae) { 1499 oops = pae.getCause(); 1500 if (oops instanceof InvocationTargetException) { 1501 oops = oops.getCause(); 1502 } 1503 } 1504 if (oops != null) { 1505 if (oops instanceof Error) { 1506 throw (Error) oops; 1507 } else { 1508 // wrap the exception 1509 throw new Error(oops); 1510 } 1511 } 1512 } 1513 sclSet = true; 1514 } 1515 } 1516 1517 // Returns true if the specified class loader can be found in this class 1518 // loader's delegation chain. 1519 boolean isAncestor(ClassLoader cl) { 1520 ClassLoader acl = this; 1521 do { 1522 acl = acl.parent; 1523 if (cl == acl) { 1524 return true; 1525 } 1526 } while (acl != null); 1527 return false; 1528 } 1529 1530 // Returns the invoker's class loader, or null if none. 1531 // NOTE: This must always be invoked when there is exactly one intervening 1532 // frame from the core libraries on the stack between this method's 1533 // invocation and the desired invoker. 1534 static ClassLoader getCallerClassLoader() { 1535 // NOTE use of more generic Reflection.getCallerClass() 1536 Class caller = Reflection.getCallerClass(3); 1537 // This can be null if the VM is requesting it 1538 if (caller == null) { 1539 return null; 1540 } 1541 // Circumvent security check since this is package-private 1542 return caller.getClassLoader0(); 1543 } 1544 1545 // The class loader for the system 1546 // @GuardedBy("ClassLoader.class") 1547 private static ClassLoader scl; 1548 1549 // Set to true once the system class loader has been set 1550 // @GuardedBy("ClassLoader.class") 1551 private static boolean sclSet; 1552 1553 1554 // -- Package -- 1555 1556 /** 1557 * Defines a package by name in this <tt>ClassLoader</tt>. This allows 1558 * class loaders to define the packages for their classes. Packages must 1559 * be created before the class is defined, and package names must be 1560 * unique within a class loader and cannot be redefined or changed once 1561 * created. </p> 1562 * 1563 * @param name 1564 * The package name 1565 * 1566 * @param specTitle 1567 * The specification title 1568 * 1569 * @param specVersion 1570 * The specification version 1571 * 1572 * @param specVendor 1573 * The specification vendor 1574 * 1575 * @param implTitle 1576 * The implementation title 1577 * 1578 * @param implVersion 1579 * The implementation version 1580 * 1581 * @param implVendor 1582 * The implementation vendor 1583 * 1584 * @param sealBase 1585 * If not <tt>null</tt>, then this package is sealed with 1586 * respect to the given code source {@link java.net.URL 1587 * <tt>URL</tt>} object. Otherwise, the package is not sealed. 1588 * 1589 * @return The newly defined <tt>Package</tt> object 1590 * 1591 * @throws IllegalArgumentException 1592 * If package name duplicates an existing package either in this 1593 * class loader or one of its ancestors 1594 * 1595 * @since 1.2 1596 */ 1597 protected Package definePackage(String name, String specTitle, 1598 String specVersion, String specVendor, 1599 String implTitle, String implVersion, 1600 String implVendor, URL sealBase) 1601 throws IllegalArgumentException 1602 { 1603 synchronized (packages) { 1604 Package pkg = getPackage(name); 1605 if (pkg != null) { 1606 throw new IllegalArgumentException(name); 1607 } 1608 pkg = new Package(name, specTitle, specVersion, specVendor, 1609 implTitle, implVersion, implVendor, 1610 sealBase, this); 1611 packages.put(name, pkg); 1612 return pkg; 1613 } 1614 } 1615 1616 /** 1617 * Returns a <tt>Package</tt> that has been defined by this class loader 1618 * or any of its ancestors. </p> 1619 * 1620 * @param name 1621 * The package name 1622 * 1623 * @return The <tt>Package</tt> corresponding to the given name, or 1624 * <tt>null</tt> if not found 1625 * 1626 * @since 1.2 1627 */ 1628 protected Package getPackage(String name) { 1629 synchronized (packages) { 1630 Package pkg = packages.get(name); 1631 if (pkg == null) { 1632 if (parent != null) { 1633 pkg = parent.getPackage(name); 1634 } else { 1635 pkg = Package.getSystemPackage(name); 1636 } 1637 if (pkg != null) { 1638 packages.put(name, pkg); 1639 } 1640 } 1641 return pkg; 1642 } 1643 } 1644 1645 /** 1646 * Returns all of the <tt>Packages</tt> defined by this class loader and 1647 * its ancestors. </p> 1648 * 1649 * @return The array of <tt>Package</tt> objects defined by this 1650 * <tt>ClassLoader</tt> 1651 * 1652 * @since 1.2 1653 */ 1654 protected Package[] getPackages() { 1655 Map<String, Package> map; 1656 synchronized (packages) { 1657 map = new HashMap<>(packages); 1658 } 1659 Package[] pkgs; 1660 if (parent != null) { 1661 pkgs = parent.getPackages(); 1662 } else { 1663 pkgs = Package.getSystemPackages(); 1664 } 1665 if (pkgs != null) { 1666 for (int i = 0; i < pkgs.length; i++) { 1667 String pkgName = pkgs[i].getName(); 1668 if (map.get(pkgName) == null) { 1669 map.put(pkgName, pkgs[i]); 1670 } 1671 } 1672 } 1673 return map.values().toArray(new Package[map.size()]); 1674 } 1675 1676 1677 // -- Native library access -- 1678 1679 /** 1680 * Returns the absolute path name of a native library. The VM invokes this 1681 * method to locate the native libraries that belong to classes loaded with 1682 * this class loader. If this method returns <tt>null</tt>, the VM 1683 * searches the library along the path specified as the 1684 * "<tt>java.library.path</tt>" property. </p> 1685 * 1686 * @param libname 1687 * The library name 1688 * 1689 * @return The absolute path of the native library 1690 * 1691 * @see System#loadLibrary(String) 1692 * @see System#mapLibraryName(String) 1693 * 1694 * @since 1.2 1695 */ 1696 protected String findLibrary(String libname) { 1697 return null; 1698 } 1699 1700 /** 1701 * The inner class NativeLibrary denotes a loaded native library instance. 1702 * Every classloader contains a vector of loaded native libraries in the 1703 * private field <tt>nativeLibraries</tt>. The native libraries loaded 1704 * into the system are entered into the <tt>systemNativeLibraries</tt> 1705 * vector. 1706 * 1707 * <p> Every native library requires a particular version of JNI. This is 1708 * denoted by the private <tt>jniVersion</tt> field. This field is set by 1709 * the VM when it loads the library, and used by the VM to pass the correct 1710 * version of JNI to the native methods. </p> 1711 * 1712 * @see ClassLoader 1713 * @since 1.2 1714 */ 1715 static class NativeLibrary { 1716 // opaque handle to native library, used in native code. 1717 long handle; 1718 // the version of JNI environment the native library requires. 1719 private int jniVersion; 1720 // the class from which the library is loaded, also indicates 1721 // the loader this native library belongs. 1722 private Class fromClass; 1723 // the canonicalized name of the native library. 1724 String name; 1725 1726 native void load(String name); 1727 native long find(String name); 1728 native void unload(); 1729 1730 public NativeLibrary(Class fromClass, String name) { 1731 this.name = name; 1732 this.fromClass = fromClass; 1733 } 1734 1735 protected void finalize() { 1736 synchronized (loadedLibraryNames) { 1737 if (fromClass.getClassLoader() != null && handle != 0) { 1738 /* remove the native library name */ 1739 int size = loadedLibraryNames.size(); 1740 for (int i = 0; i < size; i++) { 1741 if (name.equals(loadedLibraryNames.elementAt(i))) { 1742 loadedLibraryNames.removeElementAt(i); 1743 break; 1744 } 1745 } 1746 /* unload the library. */ 1747 ClassLoader.nativeLibraryContext.push(this); 1748 try { 1749 unload(); 1750 } finally { 1751 ClassLoader.nativeLibraryContext.pop(); 1752 } 1753 } 1754 } 1755 } 1756 // Invoked in the VM to determine the context class in 1757 // JNI_Load/JNI_Unload 1758 static Class getFromClass() { 1759 return ClassLoader.nativeLibraryContext.peek().fromClass; 1760 } 1761 } 1762 1763 // All native library names we've loaded. 1764 private static Vector<String> loadedLibraryNames = new Vector<>(); 1765 1766 // Native libraries belonging to system classes. 1767 private static Vector<NativeLibrary> systemNativeLibraries 1768 = new Vector<>(); 1769 1770 // Native libraries associated with the class loader. 1771 private Vector<NativeLibrary> nativeLibraries = new Vector<>(); 1772 1773 // native libraries being loaded/unloaded. 1774 private static Stack<NativeLibrary> nativeLibraryContext = new Stack<>(); 1775 1776 // The paths searched for libraries 1777 private static String usr_paths[]; 1778 private static String sys_paths[]; 1779 1780 private static String[] initializePath(String propname) { 1781 String ldpath = System.getProperty(propname, ""); 1782 String ps = File.pathSeparator; 1783 int ldlen = ldpath.length(); 1784 int i, j, n; 1785 // Count the separators in the path 1786 i = ldpath.indexOf(ps); 1787 n = 0; 1788 while (i >= 0) { 1789 n++; 1790 i = ldpath.indexOf(ps, i + 1); 1791 } 1792 1793 // allocate the array of paths - n :'s = n + 1 path elements 1794 String[] paths = new String[n + 1]; 1795 1796 // Fill the array with paths from the ldpath 1797 n = i = 0; 1798 j = ldpath.indexOf(ps); 1799 while (j >= 0) { 1800 if (j - i > 0) { 1801 paths[n++] = ldpath.substring(i, j); 1802 } else if (j - i == 0) { 1803 paths[n++] = "."; 1804 } 1805 i = j + 1; 1806 j = ldpath.indexOf(ps, i); 1807 } 1808 paths[n] = ldpath.substring(i, ldlen); 1809 return paths; 1810 } 1811 1812 // Invoked in the java.lang.Runtime class to implement load and loadLibrary. 1813 static void loadLibrary(Class fromClass, String name, 1814 boolean isAbsolute) { 1815 ClassLoader loader = 1816 (fromClass == null) ? null : fromClass.getClassLoader(); 1817 if (sys_paths == null) { 1818 usr_paths = initializePath("java.library.path"); 1819 sys_paths = initializePath("sun.boot.library.path"); 1820 } 1821 if (isAbsolute) { 1822 if (loadLibrary0(fromClass, new File(name))) { 1823 return; 1824 } 1825 throw new UnsatisfiedLinkError("Can't load library: " + name); 1826 } 1827 if (loader != null) { 1828 String libfilename = loader.findLibrary(name); 1829 if (libfilename != null) { 1830 File libfile = new File(libfilename); 1831 if (!libfile.isAbsolute()) { 1832 throw new UnsatisfiedLinkError( 1833 "ClassLoader.findLibrary failed to return an absolute path: " + libfilename); 1834 } 1835 if (loadLibrary0(fromClass, libfile)) { 1836 return; 1837 } 1838 throw new UnsatisfiedLinkError("Can't load " + libfilename); 1839 } 1840 } 1841 for (int i = 0 ; i < sys_paths.length ; i++) { 1842 File libfile = new File(sys_paths[i], System.mapLibraryName(name)); 1843 if (loadLibrary0(fromClass, libfile)) { 1844 return; 1845 } 1846 } 1847 if (loader != null) { 1848 for (int i = 0 ; i < usr_paths.length ; i++) { 1849 File libfile = new File(usr_paths[i], 1850 System.mapLibraryName(name)); 1851 if (loadLibrary0(fromClass, libfile)) { 1852 return; 1853 } 1854 } 1855 } 1856 // Oops, it failed 1857 throw new UnsatisfiedLinkError("no " + name + " in java.library.path"); 1858 } 1859 1860 private static boolean loadLibrary0(Class fromClass, final File file) { 1861 boolean exists = AccessController.doPrivileged( 1862 new PrivilegedAction<Object>() { 1863 public Object run() { 1864 return file.exists() ? Boolean.TRUE : null; 1865 }}) 1866 != null; 1867 if (!exists) { 1868 return false; 1869 } 1870 String name; 1871 try { 1872 name = file.getCanonicalPath(); 1873 } catch (IOException e) { 1874 return false; 1875 } 1876 ClassLoader loader = 1877 (fromClass == null) ? null : fromClass.getClassLoader(); 1878 Vector<NativeLibrary> libs = 1879 loader != null ? loader.nativeLibraries : systemNativeLibraries; 1880 synchronized (libs) { 1881 int size = libs.size(); 1882 for (int i = 0; i < size; i++) { 1883 NativeLibrary lib = libs.elementAt(i); 1884 if (name.equals(lib.name)) { 1885 return true; 1886 } 1887 } 1888 1889 synchronized (loadedLibraryNames) { 1890 if (loadedLibraryNames.contains(name)) { 1891 throw new UnsatisfiedLinkError 1892 ("Native Library " + 1893 name + 1894 " already loaded in another classloader"); 1895 } 1896 /* If the library is being loaded (must be by the same thread, 1897 * because Runtime.load and Runtime.loadLibrary are 1898 * synchronous). The reason is can occur is that the JNI_OnLoad 1899 * function can cause another loadLibrary invocation. 1900 * 1901 * Thus we can use a static stack to hold the list of libraries 1902 * we are loading. 1903 * 1904 * If there is a pending load operation for the library, we 1905 * immediately return success; otherwise, we raise 1906 * UnsatisfiedLinkError. 1907 */ 1908 int n = nativeLibraryContext.size(); 1909 for (int i = 0; i < n; i++) { 1910 NativeLibrary lib = nativeLibraryContext.elementAt(i); 1911 if (name.equals(lib.name)) { 1912 if (loader == lib.fromClass.getClassLoader()) { 1913 return true; 1914 } else { 1915 throw new UnsatisfiedLinkError 1916 ("Native Library " + 1917 name + 1918 " is being loaded in another classloader"); 1919 } 1920 } 1921 } 1922 NativeLibrary lib = new NativeLibrary(fromClass, name); 1923 nativeLibraryContext.push(lib); 1924 try { 1925 lib.load(name); 1926 } finally { 1927 nativeLibraryContext.pop(); 1928 } 1929 if (lib.handle != 0) { 1930 loadedLibraryNames.addElement(name); 1931 libs.addElement(lib); 1932 return true; 1933 } 1934 return false; 1935 } 1936 } 1937 } 1938 1939 // Invoked in the VM class linking code. 1940 static long findNative(ClassLoader loader, String name) { 1941 Vector<NativeLibrary> libs = 1942 loader != null ? loader.nativeLibraries : systemNativeLibraries; 1943 synchronized (libs) { 1944 int size = libs.size(); 1945 for (int i = 0; i < size; i++) { 1946 NativeLibrary lib = libs.elementAt(i); 1947 long entry = lib.find(name); 1948 if (entry != 0) 1949 return entry; 1950 } 1951 } 1952 return 0; 1953 } 1954 1955 1956 // -- Assertion management -- 1957 1958 final Object assertionLock; 1959 1960 // The default toggle for assertion checking. 1961 // @GuardedBy("assertionLock") 1962 private boolean defaultAssertionStatus = false; 1963 1964 // Maps String packageName to Boolean package default assertion status Note 1965 // that the default package is placed under a null map key. If this field 1966 // is null then we are delegating assertion status queries to the VM, i.e., 1967 // none of this ClassLoader's assertion status modification methods have 1968 // been invoked. 1969 // @GuardedBy("assertionLock") 1970 private Map<String, Boolean> packageAssertionStatus = null; 1971 1972 // Maps String fullyQualifiedClassName to Boolean assertionStatus If this 1973 // field is null then we are delegating assertion status queries to the VM, 1974 // i.e., none of this ClassLoader's assertion status modification methods 1975 // have been invoked. 1976 // @GuardedBy("assertionLock") 1977 Map<String, Boolean> classAssertionStatus = null; 1978 1979 /** 1980 * Sets the default assertion status for this class loader. This setting 1981 * determines whether classes loaded by this class loader and initialized 1982 * in the future will have assertions enabled or disabled by default. 1983 * This setting may be overridden on a per-package or per-class basis by 1984 * invoking {@link #setPackageAssertionStatus(String, boolean)} or {@link 1985 * #setClassAssertionStatus(String, boolean)}. </p> 1986 * 1987 * @param enabled 1988 * <tt>true</tt> if classes loaded by this class loader will 1989 * henceforth have assertions enabled by default, <tt>false</tt> 1990 * if they will have assertions disabled by default. 1991 * 1992 * @since 1.4 1993 */ 1994 public void setDefaultAssertionStatus(boolean enabled) { 1995 synchronized (assertionLock) { 1996 if (classAssertionStatus == null) 1997 initializeJavaAssertionMaps(); 1998 1999 defaultAssertionStatus = enabled; 2000 } 2001 } 2002 2003 /** 2004 * Sets the package default assertion status for the named package. The 2005 * package default assertion status determines the assertion status for 2006 * classes initialized in the future that belong to the named package or 2007 * any of its "subpackages". 2008 * 2009 * <p> A subpackage of a package named p is any package whose name begins 2010 * with "<tt>p.</tt>". For example, <tt>javax.swing.text</tt> is a 2011 * subpackage of <tt>javax.swing</tt>, and both <tt>java.util</tt> and 2012 * <tt>java.lang.reflect</tt> are subpackages of <tt>java</tt>. 2013 * 2014 * <p> In the event that multiple package defaults apply to a given class, 2015 * the package default pertaining to the most specific package takes 2016 * precedence over the others. For example, if <tt>javax.lang</tt> and 2017 * <tt>javax.lang.reflect</tt> both have package defaults associated with 2018 * them, the latter package default applies to classes in 2019 * <tt>javax.lang.reflect</tt>. 2020 * 2021 * <p> Package defaults take precedence over the class loader's default 2022 * assertion status, and may be overridden on a per-class basis by invoking 2023 * {@link #setClassAssertionStatus(String, boolean)}. </p> 2024 * 2025 * @param packageName 2026 * The name of the package whose package default assertion status 2027 * is to be set. A <tt>null</tt> value indicates the unnamed 2028 * package that is "current" 2029 * (<a href="http://java.sun.com/docs/books/jls/">Java Language 2030 * Specification</a>, section 7.4.2). 2031 * 2032 * @param enabled 2033 * <tt>true</tt> if classes loaded by this classloader and 2034 * belonging to the named package or any of its subpackages will 2035 * have assertions enabled by default, <tt>false</tt> if they will 2036 * have assertions disabled by default. 2037 * 2038 * @since 1.4 2039 */ 2040 public void setPackageAssertionStatus(String packageName, 2041 boolean enabled) { 2042 synchronized (assertionLock) { 2043 if (packageAssertionStatus == null) 2044 initializeJavaAssertionMaps(); 2045 2046 packageAssertionStatus.put(packageName, enabled); 2047 } 2048 } 2049 2050 /** 2051 * Sets the desired assertion status for the named top-level class in this 2052 * class loader and any nested classes contained therein. This setting 2053 * takes precedence over the class loader's default assertion status, and 2054 * over any applicable per-package default. This method has no effect if 2055 * the named class has already been initialized. (Once a class is 2056 * initialized, its assertion status cannot change.) 2057 * 2058 * <p> If the named class is not a top-level class, this invocation will 2059 * have no effect on the actual assertion status of any class. </p> 2060 * 2061 * @param className 2062 * The fully qualified class name of the top-level class whose 2063 * assertion status is to be set. 2064 * 2065 * @param enabled 2066 * <tt>true</tt> if the named class is to have assertions 2067 * enabled when (and if) it is initialized, <tt>false</tt> if the 2068 * class is to have assertions disabled. 2069 * 2070 * @since 1.4 2071 */ 2072 public void setClassAssertionStatus(String className, boolean enabled) { 2073 synchronized (assertionLock) { 2074 if (classAssertionStatus == null) 2075 initializeJavaAssertionMaps(); 2076 2077 classAssertionStatus.put(className, enabled); 2078 } 2079 } 2080 2081 /** 2082 * Sets the default assertion status for this class loader to 2083 * <tt>false</tt> and discards any package defaults or class assertion 2084 * status settings associated with the class loader. This method is 2085 * provided so that class loaders can be made to ignore any command line or 2086 * persistent assertion status settings and "start with a clean slate." 2087 * </p> 2088 * 2089 * @since 1.4 2090 */ 2091 public void clearAssertionStatus() { 2092 /* 2093 * Whether or not "Java assertion maps" are initialized, set 2094 * them to empty maps, effectively ignoring any present settings. 2095 */ 2096 synchronized (assertionLock) { 2097 classAssertionStatus = new HashMap<>(); 2098 packageAssertionStatus = new HashMap<>(); 2099 defaultAssertionStatus = false; 2100 } 2101 } 2102 2103 /** 2104 * Returns the assertion status that would be assigned to the specified 2105 * class if it were to be initialized at the time this method is invoked. 2106 * If the named class has had its assertion status set, the most recent 2107 * setting will be returned; otherwise, if any package default assertion 2108 * status pertains to this class, the most recent setting for the most 2109 * specific pertinent package default assertion status is returned; 2110 * otherwise, this class loader's default assertion status is returned. 2111 * </p> 2112 * 2113 * @param className 2114 * The fully qualified class name of the class whose desired 2115 * assertion status is being queried. 2116 * 2117 * @return The desired assertion status of the specified class. 2118 * 2119 * @see #setClassAssertionStatus(String, boolean) 2120 * @see #setPackageAssertionStatus(String, boolean) 2121 * @see #setDefaultAssertionStatus(boolean) 2122 * 2123 * @since 1.4 2124 */ 2125 boolean desiredAssertionStatus(String className) { 2126 synchronized (assertionLock) { 2127 // assert classAssertionStatus != null; 2128 // assert packageAssertionStatus != null; 2129 2130 // Check for a class entry 2131 Boolean result = classAssertionStatus.get(className); 2132 if (result != null) 2133 return result.booleanValue(); 2134 2135 // Check for most specific package entry 2136 int dotIndex = className.lastIndexOf("."); 2137 if (dotIndex < 0) { // default package 2138 result = packageAssertionStatus.get(null); 2139 if (result != null) 2140 return result.booleanValue(); 2141 } 2142 while(dotIndex > 0) { 2143 className = className.substring(0, dotIndex); 2144 result = packageAssertionStatus.get(className); 2145 if (result != null) 2146 return result.booleanValue(); 2147 dotIndex = className.lastIndexOf(".", dotIndex-1); 2148 } 2149 2150 // Return the classloader default 2151 return defaultAssertionStatus; 2152 } 2153 } 2154 2155 // Set up the assertions with information provided by the VM. 2156 // Note: Should only be called inside a synchronized block 2157 private void initializeJavaAssertionMaps() { 2158 // assert Thread.holdsLock(assertionLock); 2159 2160 classAssertionStatus = new HashMap<>(); 2161 packageAssertionStatus = new HashMap<>(); 2162 AssertionStatusDirectives directives = retrieveDirectives(); 2163 2164 for(int i = 0; i < directives.classes.length; i++) 2165 classAssertionStatus.put(directives.classes[i], 2166 directives.classEnabled[i]); 2167 2168 for(int i = 0; i < directives.packages.length; i++) 2169 packageAssertionStatus.put(directives.packages[i], 2170 directives.packageEnabled[i]); 2171 2172 defaultAssertionStatus = directives.deflt; 2173 } 2174 2175 // Retrieves the assertion directives from the VM. 2176 private static native AssertionStatusDirectives retrieveDirectives(); 2177 } 2178 2179 2180 class SystemClassLoaderAction 2181 implements PrivilegedExceptionAction<ClassLoader> { 2182 private ClassLoader parent; 2183 2184 SystemClassLoaderAction(ClassLoader parent) { 2185 this.parent = parent; 2186 } 2187 2188 public ClassLoader run() throws Exception { 2189 String cls = System.getProperty("java.system.class.loader"); 2190 if (cls == null) { 2191 return parent; 2192 } 2193 2194 Constructor ctor = Class.forName(cls, true, parent) 2195 .getDeclaredConstructor(new Class[] { ClassLoader.class }); 2196 ClassLoader sys = (ClassLoader) ctor.newInstance( 2197 new Object[] { parent }); 2198 Thread.currentThread().setContextClassLoader(sys); 2199 return sys; 2200 } 2201 }