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