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