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