1 /* ClassLoader.java -- responsible for loading classes into the VM 2 Copyright (C) 1998, 1999, 2001, 2002, 2003 Free Software Foundation, Inc. 3 4 This file is part of GNU Classpath. 5 6 GNU Classpath is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2, or (at your option) 9 any later version. 10 11 GNU Classpath is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GNU Classpath; see the file COPYING. If not, write to the 18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 19 02111-1307 USA. 20 21 Linking this library statically or dynamically with other modules is 22 making a combined work based on this library. Thus, the terms and 23 conditions of the GNU General Public License cover the whole 24 combination. 25 26 As a special exception, the copyright holders of this library give you 27 permission to link this library with independent modules to produce an 28 executable, regardless of the license terms of these independent 29 modules, and to copy and distribute the resulting executable under 30 terms of your choice, provided that you also meet, for each linked 31 independent module, the terms and conditions of the license of that 32 module. An independent module is a module which is not derived from 33 or based on this library. If you modify this library, you may extend 34 this exception to your version of the library, but you are not 35 obligated to do so. If you do not wish to do so, delete this 36 exception statement from your version. */ 37 38 39 package java.lang; 40 41 import java.io.InputStream; 42 import java.io.IOException; 43 import java.lang.reflect.Constructor; 44 import java.net.URL; 45 import java.security.CodeSource; 46 import java.security.PermissionCollection; 47 import java.security.Policy; 48 import java.security.ProtectionDomain; 49 import java.util.Enumeration; 50 import java.util.HashMap; 51 import java.util.Map; 52 import gnu.java.util.DoubleEnumeration; 53 import gnu.java.util.EmptyEnumeration; 54 55 /** 56 * The ClassLoader is a way of customizing the way Java gets its classes 57 * and loads them into memory. The verifier and other standard Java things 58 * still run, but the ClassLoader is allowed great flexibility in determining 59 * where to get the classfiles and when to load and resolve them. For that 60 * matter, a custom ClassLoader can perform on-the-fly code generation or 61 * modification! 62 * 63 * <p>Every classloader has a parent classloader that is consulted before 64 * the 'child' classloader when classes or resources should be loaded. 65 * This is done to make sure that classes can be loaded from an hierarchy of 66 * multiple classloaders and classloaders do not accidentially redefine 67 * already loaded classes by classloaders higher in the hierarchy. 68 * 69 * <p>The grandparent of all classloaders is the bootstrap classloader, which 70 * loads all the standard system classes as implemented by GNU Classpath. The 71 * other special classloader is the system classloader (also called 72 * application classloader) that loads all classes from the CLASSPATH 73 * (<code>java.class.path</code> system property). The system classloader 74 * is responsible for finding the application classes from the classpath, 75 * and delegates all requests for the standard library classes to its parent 76 * the bootstrap classloader. Most programs will load all their classes 77 * through the system classloaders. 78 * 79 * <p>The bootstrap classloader in GNU Classpath is implemented as a couple of 80 * static (native) methods on the package private class 81 * <code>java.lang.VMClassLoader</code>, the system classloader is an 82 * instance of <code>gnu.java.lang.SystemClassLoader</code> 83 * (which is a subclass of <code>java.net.URLClassLoader</code>). 84 * 85 * <p>Users of a <code>ClassLoader</code> will normally just use the methods 86 * <ul> 87 * <li> <code>loadClass()</code> to load a class.</li> 88 * <li> <code>getResource()</code> or <code>getResourceAsStream()</code> 89 * to access a resource.</li> 90 * <li> <code>getResources()</code> to get an Enumeration of URLs to all 91 * the resources provided by the classloader and its parents with the 92 * same name.</li> 93 * </ul> 94 * 95 * <p>Subclasses should implement the methods 96 * <ul> 97 * <li> <code>findClass()</code> which is called by <code>loadClass()</code> 98 * when the parent classloader cannot provide a named class.</li> 99 * <li> <code>findResource()</code> which is called by 100 * <code>getResource()</code> when the parent classloader cannot provide 101 * a named resource.</li> 102 * <li> <code>findResources()</code> which is called by 103 * <code>getResource()</code> to combine all the resources with the 104 * same name from the classloader and its parents.</li> 105 * <li> <code>findLibrary()</code> which is called by 106 * <code>Runtime.loadLibrary()</code> when a class defined by the 107 * classloader wants to load a native library.</li> 108 * </ul> 109 * 110 * @author John Keiser 111 * @author Mark Wielaard 112 * @author Eric Blake <ebb9@email.byu.edu> 113 * @see Class 114 * @since 1.0 115 * @status still missing 1.4 functionality 116 */ 117 public abstract class ClassLoader 118 { 119 /** 120 * All classes loaded by this classloader. VM's may choose to implement 121 * this cache natively; but it is here available for use if necessary. It 122 * is not private in order to allow native code (and trusted subclasses) 123 * access to this field. 124 */ 125 final Map loadedClasses = new HashMap(); 126 127 /** 128 * All packages defined by this classloader. It is not private in order to 129 * allow native code (and trusted subclasses) access to this field. 130 */ 131 final Map definedPackages = new HashMap(); 132 133 /** 134 * The classloader that is consulted before this classloader. 135 * If null then the parent is the bootstrap classloader. 136 */ 137 private final ClassLoader parent; 138 139 /** 140 * This is true if this classloader was successfully initialized. 141 * This flag is needed to avoid a class loader attack: even if the 142 * security manager rejects an attempt to create a class loader, the 143 * malicious class could have a finalize method which proceeds to 144 * define classes. 145 */ 146 private final boolean initialized; 147 148 /** 149 * System/Application classloader: defaults to an instance of 150 * gnu.java.lang.SystemClassLoader, unless the first invocation of 151 * getSystemClassLoader loads another class loader because of the 152 * java.system.class.loader property. The initialization of this field 153 * is somewhat circular - getSystemClassLoader() checks whether this 154 * field is null in order to bypass a security check. 155 */ 156 static final ClassLoader systemClassLoader = 157 VMClassLoader.getSystemClassLoader(); 158 159 /** 160 * The default protection domain, used when defining a class with a null 161 * paramter for the domain. 162 */ 163 static final ProtectionDomain defaultProtectionDomain; 164 static 165 { 166 CodeSource cs = new CodeSource(null, null); 167 PermissionCollection perm = Policy.getPolicy().getPermissions(cs); 168 defaultProtectionDomain = new ProtectionDomain(cs, perm); 169 } 170 171 /** 172 * The desired assertion status of classes loaded by this loader, if not 173 * overridden by package or class instructions. 174 */ 175 // Package visible for use by Class. 176 boolean defaultAssertionStatus = VMClassLoader.defaultAssertionStatus(); 177 178 /** 179 * The command-line state of the package assertion status overrides. This 180 * map is never modified, so it does not need to be synchronized. 181 */ 182 // Package visible for use by Class. 183 static final Map systemPackageAssertionStatus 184 = VMClassLoader.packageAssertionStatus(); 185 186 /** 187 * The map of package assertion status overrides, or null if no package 188 * overrides have been specified yet. The values of the map should be 189 * Boolean.TRUE or Boolean.FALSE, and the unnamed package is represented 190 * by the null key. This map must be synchronized on this instance. 191 */ 192 // Package visible for use by Class. 193 Map packageAssertionStatus; 194 195 /** 196 * The command-line state of the class assertion status overrides. This 197 * map is never modified, so it does not need to be synchronized. 198 */ 199 // Package visible for use by Class. 200 static final Map systemClassAssertionStatus 201 = VMClassLoader.classAssertionStatus(); 202 203 /** 204 * The map of class assertion status overrides, or null if no class 205 * overrides have been specified yet. The values of the map should be 206 * Boolean.TRUE or Boolean.FALSE. This map must be synchronized on this 207 * instance. 208 */ 209 // Package visible for use by Class. 210 Map classAssertionStatus; 211 212 /** 213 * Create a new ClassLoader with as parent the system classloader. There 214 * may be a security check for <code>checkCreateClassLoader</code>. 215 * 216 * @throws SecurityException if the security check fails 217 */ ClassLoader()218 protected ClassLoader() throws SecurityException 219 { 220 this(systemClassLoader); 221 } 222 223 /** 224 * Create a new ClassLoader with the specified parent. The parent will 225 * be consulted when a class or resource is requested through 226 * <code>loadClass()</code> or <code>getResource()</code>. Only when the 227 * parent classloader cannot provide the requested class or resource the 228 * <code>findClass()</code> or <code>findResource()</code> method 229 * of this classloader will be called. There may be a security check for 230 * <code>checkCreateClassLoader</code>. 231 * 232 * @param parent the classloader's parent, or null for the bootstrap 233 * classloader 234 * @throws SecurityException if the security check fails 235 * @since 1.2 236 */ ClassLoader(ClassLoader parent)237 protected ClassLoader(ClassLoader parent) 238 { 239 // May we create a new classloader? 240 SecurityManager sm = System.getSecurityManager(); 241 if (sm != null) 242 sm.checkCreateClassLoader(); 243 this.parent = parent; 244 this.initialized = true; 245 } 246 247 /** 248 * Load a class using this ClassLoader or its parent, without resolving 249 * it. Calls <code>loadClass(name, false)</code>. 250 * 251 * <p>Subclasses should not override this method but should override 252 * <code>findClass()</code> which is called by this method. 253 * 254 * @param name the name of the class relative to this ClassLoader 255 * @return the loaded class 256 * @throws ClassNotFoundException if the class cannot be found 257 */ loadClass(String name)258 public Class loadClass(String name) throws ClassNotFoundException 259 { 260 return loadClass(name, false); 261 } 262 263 /** 264 * Load a class using this ClassLoader or its parent, possibly resolving 265 * it as well using <code>resolveClass()</code>. It first tries to find 266 * out if the class has already been loaded through this classloader by 267 * calling <code>findLoadedClass()</code>. Then it calls 268 * <code>loadClass()</code> on the parent classloader (or when there is 269 * no parent it uses the VM bootclassloader)</code>). If the class is still 270 * not loaded it tries to create a new class by calling 271 * <code>findClass()</code>. Finally when <code>resolve</code> is 272 * <code>true</code> it also calls <code>resolveClass()</code> on the 273 * newly loaded class. 274 * 275 * <p>Subclasses should not override this method but should override 276 * <code>findClass()</code> which is called by this method. 277 * 278 * @param name the fully qualified name of the class to load 279 * @param resolve whether or not to resolve the class 280 * @return the loaded class 281 * @throws ClassNotFoundException if the class cannot be found 282 */ loadClass(String name, boolean resolve)283 protected synchronized Class loadClass(String name, boolean resolve) 284 throws ClassNotFoundException 285 { 286 // Have we already loaded this class? 287 Class c = findLoadedClass(name); 288 if (c != null) 289 return c; 290 291 // Can the class be loaded by a parent? 292 try 293 { 294 if (parent == null) 295 { 296 c = VMClassLoader.loadClass(name, resolve); 297 if (c != null) 298 return c; 299 } 300 else 301 { 302 return parent.loadClass(name, resolve); 303 } 304 } 305 catch (ClassNotFoundException e) 306 { 307 } 308 // Still not found, we have to do it ourself. 309 c = findClass(name); 310 if (resolve) 311 resolveClass(c); 312 return c; 313 } 314 315 /** 316 * Called for every class name that is needed but has not yet been 317 * defined by this classloader or one of its parents. It is called by 318 * <code>loadClass()</code> after both <code>findLoadedClass()</code> and 319 * <code>parent.loadClass()</code> couldn't provide the requested class. 320 * 321 * <p>The default implementation throws a 322 * <code>ClassNotFoundException</code>. Subclasses should override this 323 * method. An implementation of this method in a subclass should get the 324 * class bytes of the class (if it can find them), if the package of the 325 * requested class doesn't exist it should define the package and finally 326 * it should call define the actual class. It does not have to resolve the 327 * class. It should look something like the following:<br> 328 * 329 * <pre> 330 * // Get the bytes that describe the requested class 331 * byte[] classBytes = classLoaderSpecificWayToFindClassBytes(name); 332 * // Get the package name 333 * int lastDot = name.lastIndexOf('.'); 334 * if (lastDot != -1) 335 * { 336 * String packageName = name.substring(0, lastDot); 337 * // Look if the package already exists 338 * if (getPackage(pkg) == null) 339 * { 340 * // define the package 341 * definePackage(packageName, ...); 342 * } 343 * } 344 * // Define and return the class 345 * return defineClass(name, classBytes, 0, classBytes.length); 346 * </pre> 347 * 348 * <p><code>loadClass()</code> makes sure that the <code>Class</code> 349 * returned by <code>findClass()</code> will later be returned by 350 * <code>findLoadedClass()</code> when the same class name is requested. 351 * 352 * @param name class name to find (including the package name) 353 * @return the requested Class 354 * @throws ClassNotFoundException when the class can not be found 355 * @since 1.2 356 */ findClass(String name)357 protected Class findClass(String name) throws ClassNotFoundException 358 { 359 throw new ClassNotFoundException(name); 360 } 361 362 /** 363 * Helper to define a class using a string of bytes. This version is not 364 * secure. 365 * 366 * @param data the data representing the classfile, in classfile format 367 * @param offset the offset into the data where the classfile starts 368 * @param len the length of the classfile data in the array 369 * @return the class that was defined 370 * @throws ClassFormatError if data is not in proper classfile format 371 * @throws IndexOutOfBoundsException if offset or len is negative, or 372 * offset + len exceeds data 373 * @deprecated use {@link #defineClass(String, byte[], int, int)} instead 374 */ defineClass(byte[] data, int offset, int len)375 protected final Class defineClass(byte[] data, int offset, int len) 376 throws ClassFormatError 377 { 378 return defineClass(null, data, offset, len); 379 } 380 381 /** 382 * Helper to define a class using a string of bytes without a 383 * ProtectionDomain. Subclasses should call this method from their 384 * <code>findClass()</code> implementation. The name should use '.' 385 * separators, and discard the trailing ".class". The default protection 386 * domain has the permissions of 387 * <code>Policy.getPolicy().getPermissions(new CodeSource(null, null))<code>. 388 * 389 * @param name the name to give the class, or null if unknown 390 * @param data the data representing the classfile, in classfile format 391 * @param offset the offset into the data where the classfile starts 392 * @param len the length of the classfile data in the array 393 * @return the class that was defined 394 * @throws ClassFormatError if data is not in proper classfile format 395 * @throws IndexOutOfBoundsException if offset or len is negative, or 396 * offset + len exceeds data 397 * @throws SecurityException if name starts with "java." 398 * @since 1.1 399 */ defineClass(String name, byte[] data, int offset, int len)400 protected final Class defineClass(String name, byte[] data, int offset, 401 int len) throws ClassFormatError 402 { 403 return defineClass(name, data, offset, len, null); 404 } 405 406 /** 407 * Helper to define a class using a string of bytes. Subclasses should call 408 * this method from their <code>findClass()</code> implementation. If the 409 * domain is null, the default of 410 * <code>Policy.getPolicy().getPermissions(new CodeSource(null, null))<code> 411 * is used. Once a class has been defined in a package, all further classes 412 * in that package must have the same set of certificates or a 413 * SecurityException is thrown. 414 * 415 * @param name the name to give the class. null if unknown 416 * @param data the data representing the classfile, in classfile format 417 * @param offset the offset into the data where the classfile starts 418 * @param len the length of the classfile data in the array 419 * @param domain the ProtectionDomain to give to the class, null for the 420 * default protection domain 421 * @return the class that was defined 422 * @throws ClassFormatError if data is not in proper classfile format 423 * @throws IndexOutOfBoundsException if offset or len is negative, or 424 * offset + len exceeds data 425 * @throws SecurityException if name starts with "java.", or if certificates 426 * do not match up 427 * @since 1.2 428 */ defineClass(String name, byte[] data, int offset, int len, ProtectionDomain domain)429 protected final synchronized Class defineClass(String name, byte[] data, 430 int offset, int len, 431 ProtectionDomain domain) 432 throws ClassFormatError 433 { 434 if (domain == null) 435 domain = defaultProtectionDomain; 436 if (! initialized) 437 throw new SecurityException("attempt to define class from uninitialized class loader"); 438 Class retval = VMClassLoader.defineClass(this, name, data, 439 offset, len, domain); 440 loadedClasses.put(retval.getName(), retval); 441 return retval; 442 } 443 444 /** 445 * Links the class, if that has not already been done. Linking basically 446 * resolves all references to other classes made by this class. 447 * 448 * @param c the class to resolve 449 * @throws NullPointerException if c is null 450 * @throws LinkageError if linking fails 451 */ resolveClass(Class c)452 protected final void resolveClass(Class c) 453 { 454 VMClassLoader.resolveClass(c); 455 } 456 457 /** 458 * Helper to find a Class using the system classloader, possibly loading it. 459 * A subclass usually does not need to call this, if it correctly 460 * overrides <code>findClass(String)</code>. 461 * 462 * @param name the name of the class to find 463 * @return the found class 464 * @throws ClassNotFoundException if the class cannot be found 465 */ findSystemClass(String name)466 protected final Class findSystemClass(String name) 467 throws ClassNotFoundException 468 { 469 return Class.forName(name, false, systemClassLoader); 470 } 471 472 /** 473 * Returns the parent of this classloader. If the parent of this 474 * classloader is the bootstrap classloader then this method returns 475 * <code>null</code>. A security check may be performed on 476 * <code>RuntimePermission("getClassLoader")</code>. 477 * 478 * @throws SecurityException if the security check fails 479 * @since 1.2 480 */ getParent()481 public final ClassLoader getParent() 482 { 483 // Check if we may return the parent classloader. 484 SecurityManager sm = System.getSecurityManager(); 485 if (sm != null) 486 { 487 Class c = VMSecurityManager.getClassContext()[1]; 488 ClassLoader cl = c.getClassLoader(); 489 if (cl != null && ! cl.isAncestorOf(this)) 490 sm.checkPermission(new RuntimePermission("getClassLoader")); 491 } 492 return parent; 493 } 494 495 /** 496 * Helper to set the signers of a class. This should be called after 497 * defining the class. 498 * 499 * @param c the Class to set signers of 500 * @param signers the signers to set 501 * @since 1.1 502 */ setSigners(Class c, Object[] signers)503 protected final void setSigners(Class c, Object[] signers) 504 { 505 c.setSigners(signers); 506 } 507 508 /** 509 * Helper to find an already-loaded class in this ClassLoader. 510 * 511 * @param name the name of the class to find 512 * @return the found Class, or null if it is not found 513 * @since 1.1 514 */ findLoadedClass(String name)515 protected final synchronized Class findLoadedClass(String name) 516 { 517 // NOTE: If the VM is keeping its own cache, it may make sense to have 518 // this method be native. 519 return (Class) loadedClasses.get(name); 520 } 521 522 /** 523 * Get the URL to a resource using this classloader or one of its parents. 524 * First tries to get the resource by calling <code>getResource()</code> 525 * on the parent classloader. If the parent classloader returns null then 526 * it tries finding the resource by calling <code>findResource()</code> on 527 * this classloader. The resource name should be separated by '/' for path 528 * elements. 529 * 530 * <p>Subclasses should not override this method but should override 531 * <code>findResource()</code> which is called by this method. 532 * 533 * @param name the name of the resource relative to this classloader 534 * @return the URL to the resource or null when not found 535 */ getResource(String name)536 public URL getResource(String name) 537 { 538 URL result; 539 540 if (parent == null) 541 result = VMClassLoader.getResource(name); 542 else 543 result = parent.getResource(name); 544 545 if (result == null) 546 result = findResource(name); 547 return result; 548 } 549 550 /** 551 * Returns an Enumeration of all resources with a given name that can 552 * be found by this classloader and its parents. Certain classloaders 553 * (such as the URLClassLoader when given multiple jar files) can have 554 * multiple resources with the same name that come from multiple locations. 555 * It can also occur that a parent classloader offers a resource with a 556 * certain name and the child classloader also offers a resource with that 557 * same name. <code>getResource() only offers the first resource (of the 558 * parent) with a given name. This method lists all resources with the 559 * same name. The name should use '/' as path separators. 560 * 561 * <p>The Enumeration is created by first calling <code>getResources()</code> 562 * on the parent classloader and then calling <code>findResources()</code> 563 * on this classloader. 564 * 565 * @param name the resource name 566 * @return an enumaration of all resources found 567 * @throws IOException if I/O errors occur in the process 568 * @since 1.2 569 */ getResources(String name)570 public final Enumeration getResources(String name) throws IOException 571 { 572 Enumeration parentResources; 573 if (parent == null) 574 parentResources = VMClassLoader.getResources(name); 575 else 576 parentResources = parent.getResources(name); 577 return new DoubleEnumeration(parentResources, findResources(name)); 578 } 579 580 /** 581 * Called whenever all locations of a named resource are needed. 582 * It is called by <code>getResources()</code> after it has called 583 * <code>parent.getResources()</code>. The results are combined by 584 * the <code>getResources()</code> method. 585 * 586 * <p>The default implementation always returns an empty Enumeration. 587 * Subclasses should override it when they can provide an Enumeration of 588 * URLs (possibly just one element) to the named resource. 589 * The first URL of the Enumeration should be the same as the one 590 * returned by <code>findResource</code>. 591 * 592 * @param name the name of the resource to be found 593 * @return a possibly empty Enumeration of URLs to the named resource 594 * @throws IOException if I/O errors occur in the process 595 * @since 1.2 596 */ findResources(String name)597 protected Enumeration findResources(String name) throws IOException 598 { 599 return EmptyEnumeration.getInstance(); 600 } 601 602 /** 603 * Called whenever a resource is needed that could not be provided by 604 * one of the parents of this classloader. It is called by 605 * <code>getResource()</code> after <code>parent.getResource()</code> 606 * couldn't provide the requested resource. 607 * 608 * <p>The default implementation always returns null. Subclasses should 609 * override this method when they can provide a way to return a URL 610 * to a named resource. 611 * 612 * @param name the name of the resource to be found 613 * @return a URL to the named resource or null when not found 614 * @since 1.2 615 */ findResource(String name)616 protected URL findResource(String name) 617 { 618 return null; 619 } 620 621 /** 622 * Get the URL to a resource using the system classloader. 623 * 624 * @param name the name of the resource relative to the system classloader 625 * @return the URL to the resource 626 * @since 1.1 627 */ getSystemResource(String name)628 public static final URL getSystemResource(String name) 629 { 630 return systemClassLoader.getResource(name); 631 } 632 633 /** 634 * Get an Enumeration of URLs to resources with a given name using the 635 * the system classloader. The enumeration firsts lists the resources with 636 * the given name that can be found by the bootstrap classloader followed 637 * by the resources with the given name that can be found on the classpath. 638 * 639 * @param name the name of the resource relative to the system classloader 640 * @return an Enumeration of URLs to the resources 641 * @throws IOException if I/O errors occur in the process 642 * @since 1.2 643 */ getSystemResources(String name)644 public static Enumeration getSystemResources(String name) throws IOException 645 { 646 return systemClassLoader.getResources(name); 647 } 648 649 /** 650 * Get a resource as stream using this classloader or one of its parents. 651 * First calls <code>getResource()</code> and if that returns a URL to 652 * the resource then it calls and returns the InputStream given by 653 * <code>URL.openStream()</code>. 654 * 655 * <p>Subclasses should not override this method but should override 656 * <code>findResource()</code> which is called by this method. 657 * 658 * @param name the name of the resource relative to this classloader 659 * @return an InputStream to the resource, or null 660 * @since 1.1 661 */ getResourceAsStream(String name)662 public InputStream getResourceAsStream(String name) 663 { 664 try 665 { 666 URL url = getResource(name); 667 if (url == null) 668 return null; 669 return url.openStream(); 670 } 671 catch (IOException e) 672 { 673 return null; 674 } 675 } 676 677 /** 678 * Get a resource using the system classloader. 679 * 680 * @param name the name of the resource relative to the system classloader 681 * @return an input stream for the resource, or null 682 * @since 1.1 683 */ getSystemResourceAsStream(String name)684 public static final InputStream getSystemResourceAsStream(String name) 685 { 686 try 687 { 688 URL url = getSystemResource(name); 689 if (url == null) 690 return null; 691 return url.openStream(); 692 } 693 catch (IOException e) 694 { 695 return null; 696 } 697 } 698 699 /** 700 * Returns the system classloader. The system classloader (also called 701 * the application classloader) is the classloader that was used to 702 * load the application classes on the classpath (given by the system 703 * property <code>java.class.path</code>. This is set as the context 704 * class loader for a thread. The system property 705 * <code>java.system.class.loader</code>, if defined, is taken to be the 706 * name of the class to use as the system class loader, which must have 707 * a public constructor which takes a ClassLoader as a parent; otherwise this 708 * uses gnu.java.lang.SystemClassLoader. 709 * 710 * <p>Note that this is different from the bootstrap classloader that 711 * actually loads all the real "system" classes (the bootstrap classloader 712 * is the parent of the returned system classloader). 713 * 714 * <p>A security check will be performed for 715 * <code>RuntimePermission("getClassLoader")</code> if the calling class 716 * is not a parent of the system class loader. 717 * 718 * @return the system class loader 719 * @throws SecurityException if the security check fails 720 * @throws IllegalStateException if this is called recursively 721 * @throws Error if <code>java.system.class.loader</code> fails to load 722 * @since 1.2 723 */ getSystemClassLoader()724 public static ClassLoader getSystemClassLoader() 725 { 726 // Check if we may return the system classloader 727 SecurityManager sm = System.getSecurityManager(); 728 if (sm != null) 729 { 730 Class c = VMSecurityManager.getClassContext()[1]; 731 ClassLoader cl = c.getClassLoader(); 732 if (cl != null && cl != systemClassLoader) 733 sm.checkPermission(new RuntimePermission("getClassLoader")); 734 } 735 736 return systemClassLoader; 737 } 738 739 /** 740 * Defines a new package and creates a Package object. The package should 741 * be defined before any class in the package is defined with 742 * <code>defineClass()</code>. The package should not yet be defined 743 * before in this classloader or in one of its parents (which means that 744 * <code>getPackage()</code> should return <code>null</code>). All 745 * parameters except the <code>name</code> of the package may be 746 * <code>null</code>. 747 * 748 * <p>Subclasses should call this method from their <code>findClass()</code> 749 * implementation before calling <code>defineClass()</code> on a Class 750 * in a not yet defined Package (which can be checked by calling 751 * <code>getPackage()</code>). 752 * 753 * @param name the name of the Package 754 * @param specTitle the name of the specification 755 * @param specVendor the name of the specification designer 756 * @param specVersion the version of this specification 757 * @param implTitle the name of the implementation 758 * @param implVendor the vendor that wrote this implementation 759 * @param implVersion the version of this implementation 760 * @param sealed if sealed the origin of the package classes 761 * @return the Package object for the specified package 762 * @throws IllegalArgumentException if the package name is null or it 763 * was already defined by this classloader or one of its parents 764 * @see Package 765 * @since 1.2 766 */ definePackage(String name, String specTitle, String specVendor, String specVersion, String implTitle, String implVendor, String implVersion, URL sealed)767 protected Package definePackage(String name, String specTitle, 768 String specVendor, String specVersion, 769 String implTitle, String implVendor, 770 String implVersion, URL sealed) 771 { 772 if (getPackage(name) != null) 773 throw new IllegalArgumentException("Package " + name 774 + " already defined"); 775 Package p = new Package(name, specTitle, specVendor, specVersion, 776 implTitle, implVendor, implVersion, sealed); 777 synchronized (definedPackages) 778 { 779 definedPackages.put(name, p); 780 } 781 return p; 782 } 783 784 /** 785 * Returns the Package object for the requested package name. It returns 786 * null when the package is not defined by this classloader or one of its 787 * parents. 788 * 789 * @param name the package name to find 790 * @return the package, if defined 791 * @since 1.2 792 */ getPackage(String name)793 protected Package getPackage(String name) 794 { 795 Package p; 796 if (parent == null) 797 p = VMClassLoader.getPackage(name); 798 else 799 p = parent.getPackage(name); 800 801 if (p == null) 802 { 803 synchronized (definedPackages) 804 { 805 p = (Package) definedPackages.get(name); 806 } 807 } 808 return p; 809 } 810 811 /** 812 * Returns all Package objects defined by this classloader and its parents. 813 * 814 * @return an array of all defined packages 815 * @since 1.2 816 */ getPackages()817 protected Package[] getPackages() 818 { 819 // Get all our packages. 820 Package[] packages; 821 synchronized(definedPackages) 822 { 823 packages = new Package[definedPackages.size()]; 824 definedPackages.values().toArray(packages); 825 } 826 827 // If we have a parent get all packages defined by our parents. 828 Package[] parentPackages; 829 if (parent == null) 830 parentPackages = VMClassLoader.getPackages(); 831 else 832 parentPackages = parent.getPackages(); 833 834 Package[] allPackages = new Package[parentPackages.length 835 + packages.length]; 836 System.arraycopy(parentPackages, 0, allPackages, 0, 837 parentPackages.length); 838 System.arraycopy(packages, 0, allPackages, parentPackages.length, 839 packages.length); 840 return allPackages; 841 } 842 843 /** 844 * Called by <code>Runtime.loadLibrary()</code> to get an absolute path 845 * to a (system specific) library that was requested by a class loaded 846 * by this classloader. The default implementation returns 847 * <code>null</code>. It should be implemented by subclasses when they 848 * have a way to find the absolute path to a library. If this method 849 * returns null the library is searched for in the default locations 850 * (the directories listed in the <code>java.library.path</code> system 851 * property). 852 * 853 * @param name the (system specific) name of the requested library 854 * @return the full pathname to the requested library, or null 855 * @see Runtime#loadLibrary() 856 * @since 1.2 857 */ findLibrary(String name)858 protected String findLibrary(String name) 859 { 860 return null; 861 } 862 863 /** 864 * Set the default assertion status for classes loaded by this classloader, 865 * used unless overridden by a package or class request. 866 * 867 * @param enabled true to set the default to enabled 868 * @see #setClassAssertionStatus(String, boolean) 869 * @see #setPackageAssertionStatus(String, boolean) 870 * @see #clearAssertionStatus() 871 * @since 1.4 872 */ setDefaultAssertionStatus(boolean enabled)873 public void setDefaultAssertionStatus(boolean enabled) 874 { 875 defaultAssertionStatus = enabled; 876 } 877 878 /** 879 * Set the default assertion status for packages, used unless overridden 880 * by a class request. This default also covers subpackages, unless they 881 * are also specified. The unnamed package should use null for the name. 882 * 883 * @param name the package (and subpackages) to affect 884 * @param enabled true to set the default to enabled 885 * @see #setDefaultAssertionStatus(String, boolean) 886 * @see #setClassAssertionStatus(String, boolean) 887 * @see #clearAssertionStatus() 888 * @since 1.4 889 */ setPackageAssertionStatus(String name, boolean enabled)890 public synchronized void setPackageAssertionStatus(String name, 891 boolean enabled) 892 { 893 if (packageAssertionStatus == null) 894 packageAssertionStatus 895 = new HashMap(systemPackageAssertionStatus); 896 packageAssertionStatus.put(name, Boolean.valueOf(enabled)); 897 } 898 899 /** 900 * Set the default assertion status for a class. This only affects the 901 * status of top-level classes, any other string is harmless. 902 * 903 * @param name the class to affect 904 * @param enabled true to set the default to enabled 905 * @throws NullPointerException if name is null 906 * @see #setDefaultAssertionStatus(String, boolean) 907 * @see #setPackageAssertionStatus(String, boolean) 908 * @see #clearAssertionStatus() 909 * @since 1.4 910 */ setClassAssertionStatus(String name, boolean enabled)911 public synchronized void setClassAssertionStatus(String name, 912 boolean enabled) 913 { 914 if (classAssertionStatus == null) 915 classAssertionStatus = new HashMap(systemClassAssertionStatus); 916 // The toString() hack catches null, as required. 917 classAssertionStatus.put(name.toString(), Boolean.valueOf(enabled)); 918 } 919 920 /** 921 * Resets the default assertion status of this classloader, its packages 922 * and classes, all to false. This allows overriding defaults inherited 923 * from the command line. 924 * 925 * @see #setDefaultAssertionStatus(boolean) 926 * @see #setClassAssertionStatus(String, boolean) 927 * @see #setPackageAssertionStatus(String, boolean) 928 * @since 1.4 929 */ clearAssertionStatus()930 public synchronized void clearAssertionStatus() 931 { 932 defaultAssertionStatus = false; 933 packageAssertionStatus = new HashMap(); 934 classAssertionStatus = new HashMap(); 935 } 936 937 /** 938 * Return true if this loader is either the specified class loader 939 * or an ancestor thereof. 940 * @param loader the class loader to check 941 */ isAncestorOf(ClassLoader loader)942 final boolean isAncestorOf(ClassLoader loader) 943 { 944 while (loader != null) 945 { 946 if (this == loader) 947 return true; 948 loader = loader.parent; 949 } 950 return false; 951 } 952 } 953