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