Frames | No Frames |
1: /* ClassLoader.java -- responsible for loading classes into the VM 2: Copyright (C) 1998, 1999, 2001, 2002, 2003, 2004, 2005, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 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 gnu.java.util.DoubleEnumeration; 42: import gnu.java.util.EmptyEnumeration; 43: 44: import java.io.IOException; 45: import java.io.InputStream; 46: import java.net.URL; 47: import java.security.CodeSource; 48: import java.security.PermissionCollection; 49: import java.security.Policy; 50: import java.security.ProtectionDomain; 51: import java.util.Enumeration; 52: import java.util.HashMap; 53: import java.util.Map; 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 HashMap 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 HashMap 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: */ 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: */ 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.</p> 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: */ 258: public Class loadClass(String name) throws ClassNotFoundException 259: { 260: return loadClass(name, false); 261: } 262: 263: private native Class loadClassFromSig(String name) 264: throws ClassNotFoundException; 265: 266: /** 267: * Load a class using this ClassLoader or its parent, possibly resolving 268: * it as well using <code>resolveClass()</code>. It first tries to find 269: * out if the class has already been loaded through this classloader by 270: * calling <code>findLoadedClass()</code>. Then it calls 271: * <code>loadClass()</code> on the parent classloader (or when there is 272: * no parent it uses the VM bootclassloader). If the class is still 273: * not loaded it tries to create a new class by calling 274: * <code>findClass()</code>. Finally when <code>resolve</code> is 275: * <code>true</code> it also calls <code>resolveClass()</code> on the 276: * newly loaded class. 277: * 278: * <p>Subclasses should not override this method but should override 279: * <code>findClass()</code> which is called by this method.</p> 280: * 281: * @param name the fully qualified name of the class to load 282: * @param resolve whether or not to resolve the class 283: * @return the loaded class 284: * @throws ClassNotFoundException if the class cannot be found 285: */ 286: protected synchronized Class loadClass(String name, boolean resolve) 287: throws ClassNotFoundException 288: { 289: // Arrays are handled specially. 290: Class c; 291: if (name.length() > 0 && name.charAt(0) == '[') 292: c = loadClassFromSig(name); 293: else 294: { 295: // Have we already loaded this class? 296: c = findLoadedClass(name); 297: if (c == null) 298: { 299: // Can the class be loaded by a parent? 300: try 301: { 302: if (parent == null) 303: { 304: c = VMClassLoader.loadClass(name, resolve); 305: if (c != null) 306: return c; 307: } 308: else 309: { 310: return parent.loadClass(name, resolve); 311: } 312: } 313: catch (ClassNotFoundException e) 314: { 315: } 316: // Still not found, we have to do it ourself. 317: c = findClass(name); 318: } 319: } 320: if (resolve) 321: resolveClass(c); 322: return c; 323: } 324: 325: /** 326: * Called for every class name that is needed but has not yet been 327: * defined by this classloader or one of its parents. It is called by 328: * <code>loadClass()</code> after both <code>findLoadedClass()</code> and 329: * <code>parent.loadClass()</code> couldn't provide the requested class. 330: * 331: * <p>The default implementation throws a 332: * <code>ClassNotFoundException</code>. Subclasses should override this 333: * method. An implementation of this method in a subclass should get the 334: * class bytes of the class (if it can find them), if the package of the 335: * requested class doesn't exist it should define the package and finally 336: * it should call define the actual class. It does not have to resolve the 337: * class. It should look something like the following:<br> 338: * 339: * <pre> 340: * // Get the bytes that describe the requested class 341: * byte[] classBytes = classLoaderSpecificWayToFindClassBytes(name); 342: * // Get the package name 343: * int lastDot = name.lastIndexOf('.'); 344: * if (lastDot != -1) 345: * { 346: * String packageName = name.substring(0, lastDot); 347: * // Look if the package already exists 348: * if (getPackage(packageName) == null) 349: * { 350: * // define the package 351: * definePackage(packageName, ...); 352: * } 353: * } 354: * // Define and return the class 355: * return defineClass(name, classBytes, 0, classBytes.length); 356: * </pre> 357: * 358: * <p><code>loadClass()</code> makes sure that the <code>Class</code> 359: * returned by <code>findClass()</code> will later be returned by 360: * <code>findLoadedClass()</code> when the same class name is requested. 361: * 362: * @param name class name to find (including the package name) 363: * @return the requested Class 364: * @throws ClassNotFoundException when the class can not be found 365: * @since 1.2 366: */ 367: protected Class findClass(String name) throws ClassNotFoundException 368: { 369: throw new ClassNotFoundException(name); 370: } 371: 372: /** 373: * Helper to define a class using a string of bytes. This version is not 374: * secure. 375: * 376: * @param data the data representing the classfile, in classfile format 377: * @param offset the offset into the data where the classfile starts 378: * @param len the length of the classfile data in the array 379: * @return the class that was defined 380: * @throws ClassFormatError if data is not in proper classfile format 381: * @throws IndexOutOfBoundsException if offset or len is negative, or 382: * offset + len exceeds data 383: * @deprecated use {@link #defineClass(String, byte[], int, int)} instead 384: */ 385: protected final Class defineClass(byte[] data, int offset, int len) 386: throws ClassFormatError 387: { 388: return defineClass(null, data, offset, len); 389: } 390: 391: /** 392: * Helper to define a class using a string of bytes without a 393: * ProtectionDomain. Subclasses should call this method from their 394: * <code>findClass()</code> implementation. The name should use '.' 395: * separators, and discard the trailing ".class". The default protection 396: * domain has the permissions of 397: * <code>Policy.getPolicy().getPermissions(new CodeSource(null, null))</code>. 398: * 399: * @param name the name to give the class, or null if unknown 400: * @param data the data representing the classfile, in classfile format 401: * @param offset the offset into the data where the classfile starts 402: * @param len the length of the classfile data in the array 403: * @return the class that was defined 404: * @throws ClassFormatError if data is not in proper classfile format 405: * @throws IndexOutOfBoundsException if offset or len is negative, or 406: * offset + len exceeds data 407: * @throws SecurityException if name starts with "java." 408: * @since 1.1 409: */ 410: protected final Class defineClass(String name, byte[] data, int offset, 411: int len) throws ClassFormatError 412: { 413: return defineClass(name, data, offset, len, null); 414: } 415: 416: /** 417: * Helper to define a class using a string of bytes. Subclasses should call 418: * this method from their <code>findClass()</code> implementation. If the 419: * domain is null, the default of 420: * <code>Policy.getPolicy().getPermissions(new CodeSource(null, null))</code> 421: * is used. Once a class has been defined in a package, all further classes 422: * in that package must have the same set of certificates or a 423: * SecurityException is thrown. 424: * 425: * @param name the name to give the class. null if unknown 426: * @param data the data representing the classfile, in classfile format 427: * @param offset the offset into the data where the classfile starts 428: * @param len the length of the classfile data in the array 429: * @param domain the ProtectionDomain to give to the class, null for the 430: * default protection domain 431: * @return the class that was defined 432: * @throws ClassFormatError if data is not in proper classfile format 433: * @throws IndexOutOfBoundsException if offset or len is negative, or 434: * offset + len exceeds data 435: * @throws SecurityException if name starts with "java.", or if certificates 436: * do not match up 437: * @since 1.2 438: */ 439: protected final synchronized Class defineClass(String name, byte[] data, 440: int offset, int len, 441: ProtectionDomain domain) 442: throws ClassFormatError 443: { 444: if (domain == null) 445: domain = defaultProtectionDomain; 446: if (! initialized) 447: throw new SecurityException("attempt to define class from uninitialized class loader"); 448: 449: Class retval = VMClassLoader.defineClass(this, name, data, 450: offset, len, domain); 451: loadedClasses.put(retval.getName(), retval); 452: return retval; 453: } 454: 455: /** 456: * Links the class, if that has not already been done. Linking basically 457: * resolves all references to other classes made by this class. 458: * 459: * @param c the class to resolve 460: * @throws NullPointerException if c is null 461: * @throws LinkageError if linking fails 462: */ 463: protected final void resolveClass(Class c) 464: { 465: VMClassLoader.resolveClass(c); 466: } 467: 468: /** 469: * Helper to find a Class using the system classloader, possibly loading it. 470: * A subclass usually does not need to call this, if it correctly 471: * overrides <code>findClass(String)</code>. 472: * 473: * @param name the name of the class to find 474: * @return the found class 475: * @throws ClassNotFoundException if the class cannot be found 476: */ 477: protected final Class findSystemClass(String name) 478: throws ClassNotFoundException 479: { 480: return Class.forName(name, false, systemClassLoader); 481: } 482: 483: /** 484: * Returns the parent of this classloader. If the parent of this 485: * classloader is the bootstrap classloader then this method returns 486: * <code>null</code>. A security check may be performed on 487: * <code>RuntimePermission("getClassLoader")</code>. 488: * 489: * @return the parent <code>ClassLoader</code> 490: * @throws SecurityException if the security check fails 491: * @since 1.2 492: */ 493: public final ClassLoader getParent() 494: { 495: // Check if we may return the parent classloader. 496: SecurityManager sm = System.getSecurityManager(); 497: if (sm != null) 498: { 499: Class c = VMSecurityManager.getClassContext(ClassLoader.class)[1]; 500: ClassLoader cl = c.getClassLoader(); 501: if (cl != null && ! cl.isAncestorOf(this)) 502: sm.checkPermission(new RuntimePermission("getClassLoader")); 503: } 504: return parent; 505: } 506: 507: /** 508: * Helper to set the signers of a class. This should be called after 509: * defining the class. 510: * 511: * @param c the Class to set signers of 512: * @param signers the signers to set 513: * @since 1.1 514: */ 515: protected final void setSigners(Class c, Object[] signers) 516: { 517: c.setSigners(signers); 518: } 519: 520: /** 521: * Helper to find an already-loaded class in this ClassLoader. 522: * 523: * @param name the name of the class to find 524: * @return the found Class, or null if it is not found 525: * @since 1.1 526: */ 527: protected final synchronized Class findLoadedClass(String name) 528: { 529: // NOTE: If the VM is keeping its own cache, it may make sense to have 530: // this method be native. 531: return (Class) loadedClasses.get(name); 532: } 533: 534: /** 535: * Get the URL to a resource using this classloader or one of its parents. 536: * First tries to get the resource by calling <code>getResource()</code> 537: * on the parent classloader. If the parent classloader returns null then 538: * it tries finding the resource by calling <code>findResource()</code> on 539: * this classloader. The resource name should be separated by '/' for path 540: * elements. 541: * 542: * <p>Subclasses should not override this method but should override 543: * <code>findResource()</code> which is called by this method. 544: * 545: * @param name the name of the resource relative to this classloader 546: * @return the URL to the resource or null when not found 547: */ 548: public URL getResource(String name) 549: { 550: URL result; 551: 552: if (parent == null) 553: result = VMClassLoader.getResource(name); 554: else 555: result = parent.getResource(name); 556: 557: if (result == null) 558: result = findResource(name); 559: return result; 560: } 561: 562: /** 563: * Returns an Enumeration of all resources with a given name that can 564: * be found by this classloader and its parents. Certain classloaders 565: * (such as the URLClassLoader when given multiple jar files) can have 566: * multiple resources with the same name that come from multiple locations. 567: * It can also occur that a parent classloader offers a resource with a 568: * certain name and the child classloader also offers a resource with that 569: * same name. <code>getResource()</code> only offers the first resource (of the 570: * parent) with a given name. This method lists all resources with the 571: * same name. The name should use '/' as path separators. 572: * 573: * <p>The Enumeration is created by first calling <code>getResources()</code> 574: * on the parent classloader and then calling <code>findResources()</code> 575: * on this classloader.</p> 576: * 577: * @param name the resource name 578: * @return an enumaration of all resources found 579: * @throws IOException if I/O errors occur in the process 580: * @since 1.2 581: */ 582: public final Enumeration getResources(String name) throws IOException 583: { 584: Enumeration parentResources; 585: if (parent == null) 586: parentResources = VMClassLoader.getResources(name); 587: else 588: parentResources = parent.getResources(name); 589: return new DoubleEnumeration(parentResources, findResources(name)); 590: } 591: 592: /** 593: * Called whenever all locations of a named resource are needed. 594: * It is called by <code>getResources()</code> after it has called 595: * <code>parent.getResources()</code>. The results are combined by 596: * the <code>getResources()</code> method. 597: * 598: * <p>The default implementation always returns an empty Enumeration. 599: * Subclasses should override it when they can provide an Enumeration of 600: * URLs (possibly just one element) to the named resource. 601: * The first URL of the Enumeration should be the same as the one 602: * returned by <code>findResource</code>. 603: * 604: * @param name the name of the resource to be found 605: * @return a possibly empty Enumeration of URLs to the named resource 606: * @throws IOException if I/O errors occur in the process 607: * @since 1.2 608: */ 609: protected Enumeration findResources(String name) throws IOException 610: { 611: return EmptyEnumeration.getInstance(); 612: } 613: 614: /** 615: * Called whenever a resource is needed that could not be provided by 616: * one of the parents of this classloader. It is called by 617: * <code>getResource()</code> after <code>parent.getResource()</code> 618: * couldn't provide the requested resource. 619: * 620: * <p>The default implementation always returns null. Subclasses should 621: * override this method when they can provide a way to return a URL 622: * to a named resource. 623: * 624: * @param name the name of the resource to be found 625: * @return a URL to the named resource or null when not found 626: * @since 1.2 627: */ 628: protected URL findResource(String name) 629: { 630: return null; 631: } 632: 633: /** 634: * Get the URL to a resource using the system classloader. 635: * 636: * @param name the name of the resource relative to the system classloader 637: * @return the URL to the resource 638: * @since 1.1 639: */ 640: public static final URL getSystemResource(String name) 641: { 642: return systemClassLoader.getResource(name); 643: } 644: 645: /** 646: * Get an Enumeration of URLs to resources with a given name using the 647: * the system classloader. The enumeration firsts lists the resources with 648: * the given name that can be found by the bootstrap classloader followed 649: * by the resources with the given name that can be found on the classpath. 650: * 651: * @param name the name of the resource relative to the system classloader 652: * @return an Enumeration of URLs to the resources 653: * @throws IOException if I/O errors occur in the process 654: * @since 1.2 655: */ 656: public static Enumeration getSystemResources(String name) throws IOException 657: { 658: return systemClassLoader.getResources(name); 659: } 660: 661: /** 662: * Get a resource as stream using this classloader or one of its parents. 663: * First calls <code>getResource()</code> and if that returns a URL to 664: * the resource then it calls and returns the InputStream given by 665: * <code>URL.openStream()</code>. 666: * 667: * <p>Subclasses should not override this method but should override 668: * <code>findResource()</code> which is called by this method. 669: * 670: * @param name the name of the resource relative to this classloader 671: * @return an InputStream to the resource, or null 672: * @since 1.1 673: */ 674: public InputStream getResourceAsStream(String name) 675: { 676: try 677: { 678: URL url = getResource(name); 679: if (url == null) 680: return null; 681: return url.openStream(); 682: } 683: catch (IOException e) 684: { 685: return null; 686: } 687: } 688: 689: /** 690: * Get a resource using the system classloader. 691: * 692: * @param name the name of the resource relative to the system classloader 693: * @return an input stream for the resource, or null 694: * @since 1.1 695: */ 696: public static final InputStream getSystemResourceAsStream(String name) 697: { 698: try 699: { 700: URL url = getSystemResource(name); 701: if (url == null) 702: return null; 703: return url.openStream(); 704: } 705: catch (IOException e) 706: { 707: return null; 708: } 709: } 710: 711: /** 712: * Returns the system classloader. The system classloader (also called 713: * the application classloader) is the classloader that was used to 714: * load the application classes on the classpath (given by the system 715: * property <code>java.class.path</code>. This is set as the context 716: * class loader for a thread. The system property 717: * <code>java.system.class.loader</code>, if defined, is taken to be the 718: * name of the class to use as the system class loader, which must have 719: * a public constructor which takes a ClassLoader as a parent; otherwise this 720: * uses gnu.java.lang.SystemClassLoader. 721: * 722: * <p>Note that this is different from the bootstrap classloader that 723: * actually loads all the real "system" classes (the bootstrap classloader 724: * is the parent of the returned system classloader). 725: * 726: * <p>A security check will be performed for 727: * <code>RuntimePermission("getClassLoader")</code> if the calling class 728: * is not a parent of the system class loader. 729: * 730: * @return the system class loader 731: * @throws SecurityException if the security check fails 732: * @throws IllegalStateException if this is called recursively 733: * @throws Error if <code>java.system.class.loader</code> fails to load 734: * @since 1.2 735: */ 736: public static ClassLoader getSystemClassLoader() 737: { 738: // Check if we may return the system classloader 739: SecurityManager sm = System.getSecurityManager(); 740: if (sm != null) 741: { 742: Class c = VMSecurityManager.getClassContext(ClassLoader.class)[1]; 743: ClassLoader cl = c.getClassLoader(); 744: if (cl != null && cl != systemClassLoader) 745: sm.checkPermission(new RuntimePermission("getClassLoader")); 746: } 747: 748: return systemClassLoader; 749: } 750: 751: /** 752: * Defines a new package and creates a Package object. The package should 753: * be defined before any class in the package is defined with 754: * <code>defineClass()</code>. The package should not yet be defined 755: * before in this classloader or in one of its parents (which means that 756: * <code>getPackage()</code> should return <code>null</code>). All 757: * parameters except the <code>name</code> of the package may be 758: * <code>null</code>. 759: * 760: * <p>Subclasses should call this method from their <code>findClass()</code> 761: * implementation before calling <code>defineClass()</code> on a Class 762: * in a not yet defined Package (which can be checked by calling 763: * <code>getPackage()</code>). 764: * 765: * @param name the name of the Package 766: * @param specTitle the name of the specification 767: * @param specVendor the name of the specification designer 768: * @param specVersion the version of this specification 769: * @param implTitle the name of the implementation 770: * @param implVendor the vendor that wrote this implementation 771: * @param implVersion the version of this implementation 772: * @param sealed if sealed the origin of the package classes 773: * @return the Package object for the specified package 774: * @throws IllegalArgumentException if the package name is null or it 775: * was already defined by this classloader or one of its parents 776: * @see Package 777: * @since 1.2 778: */ 779: protected Package definePackage(String name, String specTitle, 780: String specVendor, String specVersion, 781: String implTitle, String implVendor, 782: String implVersion, URL sealed) 783: { 784: if (getPackage(name) != null) 785: throw new IllegalArgumentException("Package " + name 786: + " already defined"); 787: Package p = new Package(name, specTitle, specVendor, specVersion, 788: implTitle, implVendor, implVersion, sealed); 789: synchronized (definedPackages) 790: { 791: definedPackages.put(name, p); 792: } 793: return p; 794: } 795: 796: /** 797: * Returns the Package object for the requested package name. It returns 798: * null when the package is not defined by this classloader or one of its 799: * parents. 800: * 801: * @param name the package name to find 802: * @return the package, if defined 803: * @since 1.2 804: */ 805: protected Package getPackage(String name) 806: { 807: Package p; 808: if (parent == null) 809: p = VMClassLoader.getPackage(name); 810: else 811: p = parent.getPackage(name); 812: 813: if (p == null) 814: { 815: synchronized (definedPackages) 816: { 817: p = (Package) definedPackages.get(name); 818: } 819: } 820: return p; 821: } 822: 823: /** 824: * Returns all Package objects defined by this classloader and its parents. 825: * 826: * @return an array of all defined packages 827: * @since 1.2 828: */ 829: protected Package[] getPackages() 830: { 831: // Get all our packages. 832: Package[] packages; 833: synchronized(definedPackages) 834: { 835: packages = new Package[definedPackages.size()]; 836: definedPackages.values().toArray(packages); 837: } 838: 839: // If we have a parent get all packages defined by our parents. 840: Package[] parentPackages; 841: if (parent == null) 842: parentPackages = VMClassLoader.getPackages(); 843: else 844: parentPackages = parent.getPackages(); 845: 846: Package[] allPackages = new Package[parentPackages.length 847: + packages.length]; 848: System.arraycopy(parentPackages, 0, allPackages, 0, 849: parentPackages.length); 850: System.arraycopy(packages, 0, allPackages, parentPackages.length, 851: packages.length); 852: return allPackages; 853: } 854: 855: /** 856: * Called by <code>Runtime.loadLibrary()</code> to get an absolute path 857: * to a (system specific) library that was requested by a class loaded 858: * by this classloader. The default implementation returns 859: * <code>null</code>. It should be implemented by subclasses when they 860: * have a way to find the absolute path to a library. If this method 861: * returns null the library is searched for in the default locations 862: * (the directories listed in the <code>java.library.path</code> system 863: * property). 864: * 865: * @param name the (system specific) name of the requested library 866: * @return the full pathname to the requested library, or null 867: * @see Runtime#loadLibrary() 868: * @since 1.2 869: */ 870: protected String findLibrary(String name) 871: { 872: return null; 873: } 874: 875: /** 876: * Set the default assertion status for classes loaded by this classloader, 877: * used unless overridden by a package or class request. 878: * 879: * @param enabled true to set the default to enabled 880: * @see #setClassAssertionStatus(String, boolean) 881: * @see #setPackageAssertionStatus(String, boolean) 882: * @see #clearAssertionStatus() 883: * @since 1.4 884: */ 885: public void setDefaultAssertionStatus(boolean enabled) 886: { 887: defaultAssertionStatus = enabled; 888: } 889: 890: /** 891: * Set the default assertion status for packages, used unless overridden 892: * by a class request. This default also covers subpackages, unless they 893: * are also specified. The unnamed package should use null for the name. 894: * 895: * @param name the package (and subpackages) to affect 896: * @param enabled true to set the default to enabled 897: * @see #setDefaultAssertionStatus(String, boolean) 898: * @see #setClassAssertionStatus(String, boolean) 899: * @see #clearAssertionStatus() 900: * @since 1.4 901: */ 902: public synchronized void setPackageAssertionStatus(String name, 903: boolean enabled) 904: { 905: if (packageAssertionStatus == null) 906: packageAssertionStatus 907: = new HashMap(systemPackageAssertionStatus); 908: packageAssertionStatus.put(name, Boolean.valueOf(enabled)); 909: } 910: 911: /** 912: * Set the default assertion status for a class. This only affects the 913: * status of top-level classes, any other string is harmless. 914: * 915: * @param name the class to affect 916: * @param enabled true to set the default to enabled 917: * @throws NullPointerException if name is null 918: * @see #setDefaultAssertionStatus(String, boolean) 919: * @see #setPackageAssertionStatus(String, boolean) 920: * @see #clearAssertionStatus() 921: * @since 1.4 922: */ 923: public synchronized void setClassAssertionStatus(String name, 924: boolean enabled) 925: { 926: if (classAssertionStatus == null) 927: classAssertionStatus = new HashMap(systemClassAssertionStatus); 928: // The toString() hack catches null, as required. 929: classAssertionStatus.put(name.toString(), Boolean.valueOf(enabled)); 930: } 931: 932: /** 933: * Resets the default assertion status of this classloader, its packages 934: * and classes, all to false. This allows overriding defaults inherited 935: * from the command line. 936: * 937: * @see #setDefaultAssertionStatus(boolean) 938: * @see #setClassAssertionStatus(String, boolean) 939: * @see #setPackageAssertionStatus(String, boolean) 940: * @since 1.4 941: */ 942: public synchronized void clearAssertionStatus() 943: { 944: defaultAssertionStatus = false; 945: packageAssertionStatus = new HashMap(); 946: classAssertionStatus = new HashMap(); 947: } 948: 949: /** 950: * Return true if this loader is either the specified class loader 951: * or an ancestor thereof. 952: * @param loader the class loader to check 953: */ 954: final boolean isAncestorOf(ClassLoader loader) 955: { 956: while (loader != null) 957: { 958: if (this == loader) 959: return true; 960: loader = loader.parent; 961: } 962: return false; 963: } 964: }