1 /* 2 * Copyright (c) 1994, 2011, 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 Enumeration[] tmp = new Enumeration[2]; 1171 if (parent != null) { 1172 tmp[0] = parent.getResources(name); 1173 } else { 1174 tmp[0] = getBootstrapResources(name); 1175 } 1176 tmp[1] = findResources(name); 1177 1178 return new CompoundEnumeration<>(tmp); 1179 } 1180 1181 /** 1182 * Finds the resource with the given name. Class loader implementations 1183 * should override this method to specify where to find resources. </p> 1184 * 1185 * @param name 1186 * The resource name 1187 * 1188 * @return A <tt>URL</tt> object for reading the resource, or 1189 * <tt>null</tt> if the resource could not be found 1190 * 1191 * @since 1.2 1192 */ 1193 protected URL findResource(String name) { 1194 return null; 1195 } 1196 1197 /** 1198 * Returns an enumeration of {@link java.net.URL <tt>URL</tt>} objects 1199 * representing all the resources with the given name. Class loader 1200 * implementations should override this method to specify where to load 1201 * resources from. </p> 1202 * 1203 * @param name 1204 * The resource name 1205 * 1206 * @return An enumeration of {@link java.net.URL <tt>URL</tt>} objects for 1207 * the resources 1208 * 1209 * @throws IOException 1210 * If I/O errors occur 1211 * 1212 * @since 1.2 1213 */ 1214 protected Enumeration<URL> findResources(String name) throws IOException { 1215 return java.util.Collections.emptyEnumeration(); 1216 } 1217 1218 // index 0: java.lang.ClassLoader.class 1219 // index 1: the immediate caller of index 0. 1220 // index 2: the immediate caller of index 1. 1221 private static native Class<? extends ClassLoader> getCaller(int index); 1222 1223 /** 1224 * Registers the caller as parallel capable.</p> 1225 * The registration succeeds if and only if all of the following 1226 * conditions are met: <br> 1227 * 1. no instance of the caller has been created</p> 1228 * 2. all of the super classes (except class Object) of the caller are 1229 * registered as parallel capable</p> 1230 * Note that once a class loader is registered as parallel capable, there 1231 * is no way to change it back. </p> 1232 * 1233 * @return true if the caller is successfully registered as 1234 * parallel capable and false if otherwise. 1235 * 1236 * @since 1.7 1237 */ 1238 protected static boolean registerAsParallelCapable() { 1239 return ParallelLoaders.register(getCaller(1)); 1240 } 1241 1242 /** 1243 * Find a resource of the specified name from the search path used to load 1244 * classes. This method locates the resource through the system class 1245 * loader (see {@link #getSystemClassLoader()}). </p> 1246 * 1247 * @param name 1248 * The resource name 1249 * 1250 * @return A {@link java.net.URL <tt>URL</tt>} object for reading the 1251 * resource, or <tt>null</tt> if the resource could not be found 1252 * 1253 * @since 1.1 1254 */ 1255 public static URL getSystemResource(String name) { 1256 ClassLoader system = getSystemClassLoader(); 1257 if (system == null) { 1258 return getBootstrapResource(name); 1259 } 1260 return system.getResource(name); 1261 } 1262 1263 /** 1264 * Finds all resources of the specified name from the search path used to 1265 * load classes. The resources thus found are returned as an 1266 * {@link java.util.Enumeration <tt>Enumeration</tt>} of {@link 1267 * java.net.URL <tt>URL</tt>} objects. 1268 * 1269 * <p> The search order is described in the documentation for {@link 1270 * #getSystemResource(String)}. </p> 1271 * 1272 * @param name 1273 * The resource name 1274 * 1275 * @return An enumeration of resource {@link java.net.URL <tt>URL</tt>} 1276 * objects 1277 * 1278 * @throws IOException 1279 * If I/O errors occur 1280 1281 * @since 1.2 1282 */ 1283 public static Enumeration<URL> getSystemResources(String name) 1284 throws IOException 1285 { 1286 ClassLoader system = getSystemClassLoader(); 1287 if (system == null) { 1288 return getBootstrapResources(name); 1289 } 1290 return system.getResources(name); 1291 } 1292 1293 /** 1294 * Find resources from the VM's built-in classloader. 1295 */ 1296 private static URL getBootstrapResource(String name) { 1297 URLClassPath ucp = getBootstrapClassPath(); 1298 Resource res = ucp.getResource(name); 1299 return res != null ? res.getURL() : null; 1300 } 1301 1302 /** 1303 * Find resources from the VM's built-in classloader. 1304 */ 1305 private static Enumeration<URL> getBootstrapResources(String name) 1306 throws IOException 1307 { 1308 final Enumeration<Resource> e = 1309 getBootstrapClassPath().getResources(name); 1310 return new Enumeration<URL> () { 1311 public URL nextElement() { 1312 return e.nextElement().getURL(); 1313 } 1314 public boolean hasMoreElements() { 1315 return e.hasMoreElements(); 1316 } 1317 }; 1318 } 1319 1320 // Returns the URLClassPath that is used for finding system resources. 1321 static URLClassPath getBootstrapClassPath() { 1322 return sun.misc.Launcher.getBootstrapClassPath(); 1323 } 1324 1325 1326 /** 1327 * Returns an input stream for reading the specified resource. 1328 * 1329 * <p> The search order is described in the documentation for {@link 1330 * #getResource(String)}. </p> 1331 * 1332 * @param name 1333 * The resource name 1334 * 1335 * @return An input stream for reading the resource, or <tt>null</tt> 1336 * if the resource could not be found 1337 * 1338 * @since 1.1 1339 */ 1340 public InputStream getResourceAsStream(String name) { 1341 URL url = getResource(name); 1342 try { 1343 return url != null ? url.openStream() : null; 1344 } catch (IOException e) { 1345 return null; 1346 } 1347 } 1348 1349 /** 1350 * Open for reading, a resource of the specified name from the search path 1351 * used to load classes. This method locates the resource through the 1352 * system class loader (see {@link #getSystemClassLoader()}). </p> 1353 * 1354 * @param name 1355 * The resource name 1356 * 1357 * @return An input stream for reading the resource, or <tt>null</tt> 1358 * if the resource could not be found 1359 * 1360 * @since 1.1 1361 */ 1362 public static InputStream getSystemResourceAsStream(String name) { 1363 URL url = getSystemResource(name); 1364 try { 1365 return url != null ? url.openStream() : null; 1366 } catch (IOException e) { 1367 return null; 1368 } 1369 } 1370 1371 1372 // -- Hierarchy -- 1373 1374 /** 1375 * Returns the parent class loader for delegation. Some implementations may 1376 * use <tt>null</tt> to represent the bootstrap class loader. This method 1377 * will return <tt>null</tt> in such implementations if this class loader's 1378 * parent is the bootstrap class loader. 1379 * 1380 * <p> If a security manager is present, and the invoker's class loader is 1381 * not <tt>null</tt> and is not an ancestor of this class loader, then this 1382 * method invokes the security manager's {@link 1383 * SecurityManager#checkPermission(java.security.Permission) 1384 * <tt>checkPermission</tt>} method with a {@link 1385 * RuntimePermission#RuntimePermission(String) 1386 * <tt>RuntimePermission("getClassLoader")</tt>} permission to verify 1387 * access to the parent class loader is permitted. If not, a 1388 * <tt>SecurityException</tt> will be thrown. </p> 1389 * 1390 * @return The parent <tt>ClassLoader</tt> 1391 * 1392 * @throws SecurityException 1393 * If a security manager exists and its <tt>checkPermission</tt> 1394 * method doesn't allow access to this class loader's parent class 1395 * loader. 1396 * 1397 * @since 1.2 1398 */ 1399 public final ClassLoader getParent() { 1400 if (parent == null) 1401 return null; 1402 SecurityManager sm = System.getSecurityManager(); 1403 if (sm != null) { 1404 ClassLoader ccl = getCallerClassLoader(); 1405 if (ccl != null && !isAncestor(ccl)) { 1406 sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); 1407 } 1408 } 1409 return parent; 1410 } 1411 1412 /** 1413 * Returns the system class loader for delegation. This is the default 1414 * delegation parent for new <tt>ClassLoader</tt> instances, and is 1415 * typically the class loader used to start the application. 1416 * 1417 * <p> This method is first invoked early in the runtime's startup 1418 * sequence, at which point it creates the system class loader and sets it 1419 * as the context class loader of the invoking <tt>Thread</tt>. 1420 * 1421 * <p> The default system class loader is an implementation-dependent 1422 * instance of this class. 1423 * 1424 * <p> If the system property "<tt>java.system.class.loader</tt>" is defined 1425 * when this method is first invoked then the value of that property is 1426 * taken to be the name of a class that will be returned as the system 1427 * class loader. The class is loaded using the default system class loader 1428 * and must define a public constructor that takes a single parameter of 1429 * type <tt>ClassLoader</tt> which is used as the delegation parent. An 1430 * instance is then created using this constructor with the default system 1431 * class loader as the parameter. The resulting class loader is defined 1432 * to be the system class loader. 1433 * 1434 * <p> If a security manager is present, and the invoker's class loader is 1435 * not <tt>null</tt> and the invoker's class loader is not the same as or 1436 * an ancestor of the system class loader, then this method invokes the 1437 * security manager's {@link 1438 * SecurityManager#checkPermission(java.security.Permission) 1439 * <tt>checkPermission</tt>} method with a {@link 1440 * RuntimePermission#RuntimePermission(String) 1441 * <tt>RuntimePermission("getClassLoader")</tt>} permission to verify 1442 * access to the system class loader. If not, a 1443 * <tt>SecurityException</tt> will be thrown. </p> 1444 * 1445 * @return The system <tt>ClassLoader</tt> for delegation, or 1446 * <tt>null</tt> if none 1447 * 1448 * @throws SecurityException 1449 * If a security manager exists and its <tt>checkPermission</tt> 1450 * method doesn't allow access to the system class loader. 1451 * 1452 * @throws IllegalStateException 1453 * If invoked recursively during the construction of the class 1454 * loader specified by the "<tt>java.system.class.loader</tt>" 1455 * property. 1456 * 1457 * @throws Error 1458 * If the system property "<tt>java.system.class.loader</tt>" 1459 * is defined but the named class could not be loaded, the 1460 * provider class does not define the required constructor, or an 1461 * exception is thrown by that constructor when it is invoked. The 1462 * underlying cause of the error can be retrieved via the 1463 * {@link Throwable#getCause()} method. 1464 * 1465 * @revised 1.4 1466 */ 1467 public static ClassLoader getSystemClassLoader() { 1468 initSystemClassLoader(); 1469 if (scl == null) { 1470 return null; 1471 } 1472 SecurityManager sm = System.getSecurityManager(); 1473 if (sm != null) { 1474 ClassLoader ccl = getCallerClassLoader(); 1475 if (ccl != null && ccl != scl && !scl.isAncestor(ccl)) { 1476 sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); 1477 } 1478 } 1479 return scl; 1480 } 1481 1482 private static synchronized void initSystemClassLoader() { 1483 if (!sclSet) { 1484 if (scl != null) 1485 throw new IllegalStateException("recursive invocation"); 1486 sun.misc.Launcher l = sun.misc.Launcher.getLauncher(); 1487 if (l != null) { 1488 Throwable oops = null; 1489 scl = l.getClassLoader(); 1490 try { 1491 scl = AccessController.doPrivileged( 1492 new SystemClassLoaderAction(scl)); 1493 } catch (PrivilegedActionException pae) { 1494 oops = pae.getCause(); 1495 if (oops instanceof InvocationTargetException) { 1496 oops = oops.getCause(); 1497 } 1498 } 1499 if (oops != null) { 1500 if (oops instanceof Error) { 1501 throw (Error) oops; 1502 } else { 1503 // wrap the exception 1504 throw new Error(oops); 1505 } 1506 } 1507 } 1508 sclSet = true; 1509 } 1510 } 1511 1512 // Returns true if the specified class loader can be found in this class 1513 // loader's delegation chain. 1514 boolean isAncestor(ClassLoader cl) { 1515 ClassLoader acl = this; 1516 do { 1517 acl = acl.parent; 1518 if (cl == acl) { 1519 return true; 1520 } 1521 } while (acl != null); 1522 return false; 1523 } 1524 1525 // Returns the invoker's class loader, or null if none. 1526 // NOTE: This must always be invoked when there is exactly one intervening 1527 // frame from the core libraries on the stack between this method's 1528 // invocation and the desired invoker. 1529 static ClassLoader getCallerClassLoader() { 1530 // NOTE use of more generic Reflection.getCallerClass() 1531 Class caller = Reflection.getCallerClass(3); 1532 // This can be null if the VM is requesting it 1533 if (caller == null) { 1534 return null; 1535 } 1536 // Circumvent security check since this is package-private 1537 return caller.getClassLoader0(); 1538 } 1539 1540 // The class loader for the system 1541 // @GuardedBy("ClassLoader.class") 1542 private static ClassLoader scl; 1543 1544 // Set to true once the system class loader has been set 1545 // @GuardedBy("ClassLoader.class") 1546 private static boolean sclSet; 1547 1548 1549 // -- Package -- 1550 1551 /** 1552 * Defines a package by name in this <tt>ClassLoader</tt>. This allows 1553 * class loaders to define the packages for their classes. Packages must 1554 * be created before the class is defined, and package names must be 1555 * unique within a class loader and cannot be redefined or changed once 1556 * created. </p> 1557 * 1558 * @param name 1559 * The package name 1560 * 1561 * @param specTitle 1562 * The specification title 1563 * 1564 * @param specVersion 1565 * The specification version 1566 * 1567 * @param specVendor 1568 * The specification vendor 1569 * 1570 * @param implTitle 1571 * The implementation title 1572 * 1573 * @param implVersion 1574 * The implementation version 1575 * 1576 * @param implVendor 1577 * The implementation vendor 1578 * 1579 * @param sealBase 1580 * If not <tt>null</tt>, then this package is sealed with 1581 * respect to the given code source {@link java.net.URL 1582 * <tt>URL</tt>} object. Otherwise, the package is not sealed. 1583 * 1584 * @return The newly defined <tt>Package</tt> object 1585 * 1586 * @throws IllegalArgumentException 1587 * If package name duplicates an existing package either in this 1588 * class loader or one of its ancestors 1589 * 1590 * @since 1.2 1591 */ 1592 protected Package definePackage(String name, String specTitle, 1593 String specVersion, String specVendor, 1594 String implTitle, String implVersion, 1595 String implVendor, URL sealBase) 1596 throws IllegalArgumentException 1597 { 1598 synchronized (packages) { 1599 Package pkg = getPackage(name); 1600 if (pkg != null) { 1601 throw new IllegalArgumentException(name); 1602 } 1603 pkg = new Package(name, specTitle, specVersion, specVendor, 1604 implTitle, implVersion, implVendor, 1605 sealBase, this); 1606 packages.put(name, pkg); 1607 return pkg; 1608 } 1609 } 1610 1611 /** 1612 * Returns a <tt>Package</tt> that has been defined by this class loader 1613 * or any of its ancestors. </p> 1614 * 1615 * @param name 1616 * The package name 1617 * 1618 * @return The <tt>Package</tt> corresponding to the given name, or 1619 * <tt>null</tt> if not found 1620 * 1621 * @since 1.2 1622 */ 1623 protected Package getPackage(String name) { 1624 Package pkg; 1625 synchronized (packages) { 1626 pkg = packages.get(name); 1627 } 1628 if (pkg == null) { 1629 if (parent != null) { 1630 pkg = parent.getPackage(name); 1631 } else { 1632 pkg = Package.getSystemPackage(name); 1633 } 1634 if (pkg != null) { 1635 synchronized (packages) { 1636 Package pkg2 = packages.get(name); 1637 if (pkg2 == null) { 1638 packages.put(name, pkg); 1639 } else { 1640 pkg = pkg2; 1641 } 1642 } 1643 } 1644 } 1645 return pkg; 1646 } 1647 1648 /** 1649 * Returns all of the <tt>Packages</tt> defined by this class loader and 1650 * its ancestors. </p> 1651 * 1652 * @return The array of <tt>Package</tt> objects defined by this 1653 * <tt>ClassLoader</tt> 1654 * 1655 * @since 1.2 1656 */ 1657 protected Package[] getPackages() { 1658 Map<String, Package> map; 1659 synchronized (packages) { 1660 map = new HashMap<>(packages); 1661 } 1662 Package[] pkgs; 1663 if (parent != null) { 1664 pkgs = parent.getPackages(); 1665 } else { 1666 pkgs = Package.getSystemPackages(); 1667 } 1668 if (pkgs != null) { 1669 for (int i = 0; i < pkgs.length; i++) { 1670 String pkgName = pkgs[i].getName(); 1671 if (map.get(pkgName) == null) { 1672 map.put(pkgName, pkgs[i]); 1673 } 1674 } 1675 } 1676 return map.values().toArray(new Package[map.size()]); 1677 } 1678 1679 1680 // -- Native library access -- 1681 1682 /** 1683 * Returns the absolute path name of a native library. The VM invokes this 1684 * method to locate the native libraries that belong to classes loaded with 1685 * this class loader. If this method returns <tt>null</tt>, the VM 1686 * searches the library along the path specified as the 1687 * "<tt>java.library.path</tt>" property. </p> 1688 * 1689 * @param libname 1690 * The library name 1691 * 1692 * @return The absolute path of the native library 1693 * 1694 * @see System#loadLibrary(String) 1695 * @see System#mapLibraryName(String) 1696 * 1697 * @since 1.2 1698 */ 1699 protected String findLibrary(String libname) { 1700 return null; 1701 } 1702 1703 /** 1704 * The inner class NativeLibrary denotes a loaded native library instance. 1705 * Every classloader contains a vector of loaded native libraries in the 1706 * private field <tt>nativeLibraries</tt>. The native libraries loaded 1707 * into the system are entered into the <tt>systemNativeLibraries</tt> 1708 * vector. 1709 * 1710 * <p> Every native library requires a particular version of JNI. This is 1711 * denoted by the private <tt>jniVersion</tt> field. This field is set by 1712 * the VM when it loads the library, and used by the VM to pass the correct 1713 * version of JNI to the native methods. </p> 1714 * 1715 * @see ClassLoader 1716 * @since 1.2 1717 */ 1718 static class NativeLibrary { 1719 // opaque handle to native library, used in native code. 1720 long handle; 1721 // the version of JNI environment the native library requires. 1722 private int jniVersion; 1723 // the class from which the library is loaded, also indicates 1724 // the loader this native library belongs. 1725 private Class fromClass; 1726 // the canonicalized name of the native library. 1727 String name; 1728 1729 native void load(String name); 1730 native long find(String name); 1731 native void unload(); 1732 1733 public NativeLibrary(Class fromClass, String name) { 1734 this.name = name; 1735 this.fromClass = fromClass; 1736 } 1737 1738 protected void finalize() { 1739 synchronized (loadedLibraryNames) { 1740 if (fromClass.getClassLoader() != null && handle != 0) { 1741 /* remove the native library name */ 1742 int size = loadedLibraryNames.size(); 1743 for (int i = 0; i < size; i++) { 1744 if (name.equals(loadedLibraryNames.elementAt(i))) { 1745 loadedLibraryNames.removeElementAt(i); 1746 break; 1747 } 1748 } 1749 /* unload the library. */ 1750 ClassLoader.nativeLibraryContext.push(this); 1751 try { 1752 unload(); 1753 } finally { 1754 ClassLoader.nativeLibraryContext.pop(); 1755 } 1756 } 1757 } 1758 } 1759 // Invoked in the VM to determine the context class in 1760 // JNI_Load/JNI_Unload 1761 static Class getFromClass() { 1762 return ClassLoader.nativeLibraryContext.peek().fromClass; 1763 } 1764 } 1765 1766 // All native library names we've loaded. 1767 private static Vector<String> loadedLibraryNames = new Vector<>(); 1768 1769 // Native libraries belonging to system classes. 1770 private static Vector<NativeLibrary> systemNativeLibraries 1771 = new Vector<>(); 1772 1773 // Native libraries associated with the class loader. 1774 private Vector<NativeLibrary> nativeLibraries = new Vector<>(); 1775 1776 // native libraries being loaded/unloaded. 1777 private static Stack<NativeLibrary> nativeLibraryContext = new Stack<>(); 1778 1779 // The paths searched for libraries 1780 private static String usr_paths[]; 1781 private static String sys_paths[]; 1782 1783 private static String[] initializePath(String propname) { 1784 String ldpath = System.getProperty(propname, ""); 1785 String ps = File.pathSeparator; 1786 int ldlen = ldpath.length(); 1787 int i, j, n; 1788 // Count the separators in the path 1789 i = ldpath.indexOf(ps); 1790 n = 0; 1791 while (i >= 0) { 1792 n++; 1793 i = ldpath.indexOf(ps, i + 1); 1794 } 1795 1796 // allocate the array of paths - n :'s = n + 1 path elements 1797 String[] paths = new String[n + 1]; 1798 1799 // Fill the array with paths from the ldpath 1800 n = i = 0; 1801 j = ldpath.indexOf(ps); 1802 while (j >= 0) { 1803 if (j - i > 0) { 1804 paths[n++] = ldpath.substring(i, j); 1805 } else if (j - i == 0) { 1806 paths[n++] = "."; 1807 } 1808 i = j + 1; 1809 j = ldpath.indexOf(ps, i); 1810 } 1811 paths[n] = ldpath.substring(i, ldlen); 1812 return paths; 1813 } 1814 1815 // Invoked in the java.lang.Runtime class to implement load and loadLibrary. 1816 static void loadLibrary(Class fromClass, String name, 1817 boolean isAbsolute) { 1818 ClassLoader loader = 1819 (fromClass == null) ? null : fromClass.getClassLoader(); 1820 if (sys_paths == null) { 1821 usr_paths = initializePath("java.library.path"); 1822 sys_paths = initializePath("sun.boot.library.path"); 1823 } 1824 if (isAbsolute) { 1825 if (loadLibrary0(fromClass, new File(name))) { 1826 return; 1827 } 1828 throw new UnsatisfiedLinkError("Can't load library: " + name); 1829 } 1830 if (loader != null) { 1831 String libfilename = loader.findLibrary(name); 1832 if (libfilename != null) { 1833 File libfile = new File(libfilename); 1834 if (!libfile.isAbsolute()) { 1835 throw new UnsatisfiedLinkError( 1836 "ClassLoader.findLibrary failed to return an absolute path: " + libfilename); 1837 } 1838 if (loadLibrary0(fromClass, libfile)) { 1839 return; 1840 } 1841 throw new UnsatisfiedLinkError("Can't load " + libfilename); 1842 } 1843 } 1844 for (int i = 0 ; i < sys_paths.length ; i++) { 1845 File libfile = new File(sys_paths[i], System.mapLibraryName(name)); 1846 if (loadLibrary0(fromClass, libfile)) { 1847 return; 1848 } 1849 } 1850 if (loader != null) { 1851 for (int i = 0 ; i < usr_paths.length ; i++) { 1852 File libfile = new File(usr_paths[i], 1853 System.mapLibraryName(name)); 1854 if (loadLibrary0(fromClass, libfile)) { 1855 return; 1856 } 1857 } 1858 } 1859 // Oops, it failed 1860 throw new UnsatisfiedLinkError("no " + name + " in java.library.path"); 1861 } 1862 1863 private static boolean loadLibrary0(Class fromClass, final File file) { 1864 boolean exists = AccessController.doPrivileged( 1865 new PrivilegedAction<Object>() { 1866 public Object run() { 1867 return file.exists() ? Boolean.TRUE : null; 1868 }}) 1869 != null; 1870 if (!exists) { 1871 return false; 1872 } 1873 String name; 1874 try { 1875 name = file.getCanonicalPath(); 1876 } catch (IOException e) { 1877 return false; 1878 } 1879 ClassLoader loader = 1880 (fromClass == null) ? null : fromClass.getClassLoader(); 1881 Vector<NativeLibrary> libs = 1882 loader != null ? loader.nativeLibraries : systemNativeLibraries; 1883 synchronized (libs) { 1884 int size = libs.size(); 1885 for (int i = 0; i < size; i++) { 1886 NativeLibrary lib = libs.elementAt(i); 1887 if (name.equals(lib.name)) { 1888 return true; 1889 } 1890 } 1891 1892 synchronized (loadedLibraryNames) { 1893 if (loadedLibraryNames.contains(name)) { 1894 throw new UnsatisfiedLinkError 1895 ("Native Library " + 1896 name + 1897 " already loaded in another classloader"); 1898 } 1899 /* If the library is being loaded (must be by the same thread, 1900 * because Runtime.load and Runtime.loadLibrary are 1901 * synchronous). The reason is can occur is that the JNI_OnLoad 1902 * function can cause another loadLibrary invocation. 1903 * 1904 * Thus we can use a static stack to hold the list of libraries 1905 * we are loading. 1906 * 1907 * If there is a pending load operation for the library, we 1908 * immediately return success; otherwise, we raise 1909 * UnsatisfiedLinkError. 1910 */ 1911 int n = nativeLibraryContext.size(); 1912 for (int i = 0; i < n; i++) { 1913 NativeLibrary lib = nativeLibraryContext.elementAt(i); 1914 if (name.equals(lib.name)) { 1915 if (loader == lib.fromClass.getClassLoader()) { 1916 return true; 1917 } else { 1918 throw new UnsatisfiedLinkError 1919 ("Native Library " + 1920 name + 1921 " is being loaded in another classloader"); 1922 } 1923 } 1924 } 1925 NativeLibrary lib = new NativeLibrary(fromClass, name); 1926 nativeLibraryContext.push(lib); 1927 try { 1928 lib.load(name); 1929 } finally { 1930 nativeLibraryContext.pop(); 1931 } 1932 if (lib.handle != 0) { 1933 loadedLibraryNames.addElement(name); 1934 libs.addElement(lib); 1935 return true; 1936 } 1937 return false; 1938 } 1939 } 1940 } 1941 1942 // Invoked in the VM class linking code. 1943 static long findNative(ClassLoader loader, String name) { 1944 Vector<NativeLibrary> libs = 1945 loader != null ? loader.nativeLibraries : systemNativeLibraries; 1946 synchronized (libs) { 1947 int size = libs.size(); 1948 for (int i = 0; i < size; i++) { 1949 NativeLibrary lib = libs.elementAt(i); 1950 long entry = lib.find(name); 1951 if (entry != 0) 1952 return entry; 1953 } 1954 } 1955 return 0; 1956 } 1957 1958 1959 // -- Assertion management -- 1960 1961 final Object assertionLock; 1962 1963 // The default toggle for assertion checking. 1964 // @GuardedBy("assertionLock") 1965 private boolean defaultAssertionStatus = false; 1966 1967 // Maps String packageName to Boolean package default assertion status Note 1968 // that the default package is placed under a null map key. If this field 1969 // is null then we are delegating assertion status queries to the VM, i.e., 1970 // none of this ClassLoader's assertion status modification methods have 1971 // been invoked. 1972 // @GuardedBy("assertionLock") 1973 private Map<String, Boolean> packageAssertionStatus = null; 1974 1975 // Maps String fullyQualifiedClassName to Boolean assertionStatus If this 1976 // field is null then we are delegating assertion status queries to the VM, 1977 // i.e., none of this ClassLoader's assertion status modification methods 1978 // have been invoked. 1979 // @GuardedBy("assertionLock") 1980 Map<String, Boolean> classAssertionStatus = null; 1981 1982 /** 1983 * Sets the default assertion status for this class loader. This setting 1984 * determines whether classes loaded by this class loader and initialized 1985 * in the future will have assertions enabled or disabled by default. 1986 * This setting may be overridden on a per-package or per-class basis by 1987 * invoking {@link #setPackageAssertionStatus(String, boolean)} or {@link 1988 * #setClassAssertionStatus(String, boolean)}. </p> 1989 * 1990 * @param enabled 1991 * <tt>true</tt> if classes loaded by this class loader will 1992 * henceforth have assertions enabled by default, <tt>false</tt> 1993 * if they will have assertions disabled by default. 1994 * 1995 * @since 1.4 1996 */ 1997 public void setDefaultAssertionStatus(boolean enabled) { 1998 synchronized (assertionLock) { 1999 if (classAssertionStatus == null) 2000 initializeJavaAssertionMaps(); 2001 2002 defaultAssertionStatus = enabled; 2003 } 2004 } 2005 2006 /** 2007 * Sets the package default assertion status for the named package. The 2008 * package default assertion status determines the assertion status for 2009 * classes initialized in the future that belong to the named package or 2010 * any of its "subpackages". 2011 * 2012 * <p> A subpackage of a package named p is any package whose name begins 2013 * with "<tt>p.</tt>". For example, <tt>javax.swing.text</tt> is a 2014 * subpackage of <tt>javax.swing</tt>, and both <tt>java.util</tt> and 2015 * <tt>java.lang.reflect</tt> are subpackages of <tt>java</tt>. 2016 * 2017 * <p> In the event that multiple package defaults apply to a given class, 2018 * the package default pertaining to the most specific package takes 2019 * precedence over the others. For example, if <tt>javax.lang</tt> and 2020 * <tt>javax.lang.reflect</tt> both have package defaults associated with 2021 * them, the latter package default applies to classes in 2022 * <tt>javax.lang.reflect</tt>. 2023 * 2024 * <p> Package defaults take precedence over the class loader's default 2025 * assertion status, and may be overridden on a per-class basis by invoking 2026 * {@link #setClassAssertionStatus(String, boolean)}. </p> 2027 * 2028 * @param packageName 2029 * The name of the package whose package default assertion status 2030 * is to be set. A <tt>null</tt> value indicates the unnamed 2031 * package that is "current" 2032 * (see section 7.4.2 of 2033 * <cite>The Java™ Language Specification</cite>.) 2034 * 2035 * @param enabled 2036 * <tt>true</tt> if classes loaded by this classloader and 2037 * belonging to the named package or any of its subpackages will 2038 * have assertions enabled by default, <tt>false</tt> if they will 2039 * have assertions disabled by default. 2040 * 2041 * @since 1.4 2042 */ 2043 public void setPackageAssertionStatus(String packageName, 2044 boolean enabled) { 2045 synchronized (assertionLock) { 2046 if (packageAssertionStatus == null) 2047 initializeJavaAssertionMaps(); 2048 2049 packageAssertionStatus.put(packageName, enabled); 2050 } 2051 } 2052 2053 /** 2054 * Sets the desired assertion status for the named top-level class in this 2055 * class loader and any nested classes contained therein. This setting 2056 * takes precedence over the class loader's default assertion status, and 2057 * over any applicable per-package default. This method has no effect if 2058 * the named class has already been initialized. (Once a class is 2059 * initialized, its assertion status cannot change.) 2060 * 2061 * <p> If the named class is not a top-level class, this invocation will 2062 * have no effect on the actual assertion status of any class. </p> 2063 * 2064 * @param className 2065 * The fully qualified class name of the top-level class whose 2066 * assertion status is to be set. 2067 * 2068 * @param enabled 2069 * <tt>true</tt> if the named class is to have assertions 2070 * enabled when (and if) it is initialized, <tt>false</tt> if the 2071 * class is to have assertions disabled. 2072 * 2073 * @since 1.4 2074 */ 2075 public void setClassAssertionStatus(String className, boolean enabled) { 2076 synchronized (assertionLock) { 2077 if (classAssertionStatus == null) 2078 initializeJavaAssertionMaps(); 2079 2080 classAssertionStatus.put(className, enabled); 2081 } 2082 } 2083 2084 /** 2085 * Sets the default assertion status for this class loader to 2086 * <tt>false</tt> and discards any package defaults or class assertion 2087 * status settings associated with the class loader. This method is 2088 * provided so that class loaders can be made to ignore any command line or 2089 * persistent assertion status settings and "start with a clean slate." 2090 * </p> 2091 * 2092 * @since 1.4 2093 */ 2094 public void clearAssertionStatus() { 2095 /* 2096 * Whether or not "Java assertion maps" are initialized, set 2097 * them to empty maps, effectively ignoring any present settings. 2098 */ 2099 synchronized (assertionLock) { 2100 classAssertionStatus = new HashMap<>(); 2101 packageAssertionStatus = new HashMap<>(); 2102 defaultAssertionStatus = false; 2103 } 2104 } 2105 2106 /** 2107 * Returns the assertion status that would be assigned to the specified 2108 * class if it were to be initialized at the time this method is invoked. 2109 * If the named class has had its assertion status set, the most recent 2110 * setting will be returned; otherwise, if any package default assertion 2111 * status pertains to this class, the most recent setting for the most 2112 * specific pertinent package default assertion status is returned; 2113 * otherwise, this class loader's default assertion status is returned. 2114 * </p> 2115 * 2116 * @param className 2117 * The fully qualified class name of the class whose desired 2118 * assertion status is being queried. 2119 * 2120 * @return The desired assertion status of the specified class. 2121 * 2122 * @see #setClassAssertionStatus(String, boolean) 2123 * @see #setPackageAssertionStatus(String, boolean) 2124 * @see #setDefaultAssertionStatus(boolean) 2125 * 2126 * @since 1.4 2127 */ 2128 boolean desiredAssertionStatus(String className) { 2129 synchronized (assertionLock) { 2130 // assert classAssertionStatus != null; 2131 // assert packageAssertionStatus != null; 2132 2133 // Check for a class entry 2134 Boolean result = classAssertionStatus.get(className); 2135 if (result != null) 2136 return result.booleanValue(); 2137 2138 // Check for most specific package entry 2139 int dotIndex = className.lastIndexOf("."); 2140 if (dotIndex < 0) { // default package 2141 result = packageAssertionStatus.get(null); 2142 if (result != null) 2143 return result.booleanValue(); 2144 } 2145 while(dotIndex > 0) { 2146 className = className.substring(0, dotIndex); 2147 result = packageAssertionStatus.get(className); 2148 if (result != null) 2149 return result.booleanValue(); 2150 dotIndex = className.lastIndexOf(".", dotIndex-1); 2151 } 2152 2153 // Return the classloader default 2154 return defaultAssertionStatus; 2155 } 2156 } 2157 2158 // Set up the assertions with information provided by the VM. 2159 // Note: Should only be called inside a synchronized block 2160 private void initializeJavaAssertionMaps() { 2161 // assert Thread.holdsLock(assertionLock); 2162 2163 classAssertionStatus = new HashMap<>(); 2164 packageAssertionStatus = new HashMap<>(); 2165 AssertionStatusDirectives directives = retrieveDirectives(); 2166 2167 for(int i = 0; i < directives.classes.length; i++) 2168 classAssertionStatus.put(directives.classes[i], 2169 directives.classEnabled[i]); 2170 2171 for(int i = 0; i < directives.packages.length; i++) 2172 packageAssertionStatus.put(directives.packages[i], 2173 directives.packageEnabled[i]); 2174 2175 defaultAssertionStatus = directives.deflt; 2176 } 2177 2178 // Retrieves the assertion directives from the VM. 2179 private static native AssertionStatusDirectives retrieveDirectives(); 2180 } 2181 2182 2183 class SystemClassLoaderAction 2184 implements PrivilegedExceptionAction<ClassLoader> { 2185 private ClassLoader parent; 2186 2187 SystemClassLoaderAction(ClassLoader parent) { 2188 this.parent = parent; 2189 } 2190 2191 public ClassLoader run() throws Exception { 2192 String cls = System.getProperty("java.system.class.loader"); 2193 if (cls == null) { 2194 return parent; 2195 } 2196 2197 Constructor ctor = Class.forName(cls, true, parent) 2198 .getDeclaredConstructor(new Class[] { ClassLoader.class }); 2199 ClassLoader sys = (ClassLoader) ctor.newInstance( 2200 new Object[] { parent }); 2201 Thread.currentThread().setContextClassLoader(sys); 2202 return sys; 2203 } 2204 }