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