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