src/share/classes/java/lang/ClassLoader.java
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File jdk Sdiff src/share/classes/java/lang

src/share/classes/java/lang/ClassLoader.java

Print this page




  91  * resource, a <tt>ClassLoader</tt> instance will delegate the search for the
  92  * class or resource to its parent class loader before attempting to find the
  93  * class or resource itself.  The virtual machine's built-in class loader,
  94  * called the "bootstrap class loader", does not itself have a parent but may
  95  * serve as the parent of a <tt>ClassLoader</tt> instance.
  96  *
  97  * <p> Class loaders that support concurrent loading of classes are known as
  98  * <em>parallel capable</em> class loaders and are required to register
  99  * themselves at their class initialization time by invoking the
 100  * {@link
 101  * #registerAsParallelCapable <tt>ClassLoader.registerAsParallelCapable</tt>}
 102  * method. Note that the <tt>ClassLoader</tt> class is registered as parallel
 103  * capable by default. However, its subclasses still need to register themselves
 104  * if they are parallel capable. <br>
 105  * In environments in which the delegation model is not strictly
 106  * hierarchical, class loaders need to be parallel capable, otherwise class
 107  * loading can lead to deadlocks because the loader lock is held for the
 108  * duration of the class loading process (see {@link #loadClass
 109  * <tt>loadClass</tt>} methods).
 110  *













 111  * <p> Normally, the Java virtual machine loads classes from the local file
 112  * system in a platform-dependent manner.  For example, on UNIX systems, the
 113  * virtual machine loads classes from the directory defined by the
 114  * <tt>CLASSPATH</tt> environment variable.
 115  *
 116  * <p> However, some classes may not originate from a file; they may originate
 117  * from other sources, such as the network, or they could be constructed by an
 118  * application.  The method {@link #defineClass(String, byte[], int, int)
 119  * <tt>defineClass</tt>} converts an array of bytes into an instance of class
 120  * <tt>Class</tt>. Instances of this newly defined class can be created using
 121  * {@link Class#newInstance <tt>Class.newInstance</tt>}.
 122  *
 123  * <p> The methods and constructors of objects created by a class loader may
 124  * reference other classes.  To determine the class(es) referred to, the Java
 125  * virtual machine invokes the {@link #loadClass <tt>loadClass</tt>} method of
 126  * the class loader that originally created the class.
 127  *
 128  * <p> For example, an application could create a network class loader to
 129  * download class files from a server.  Sample code might look like:
 130  *


 176  */
 177 public abstract class ClassLoader {
 178 
 179     private static native void registerNatives();
 180     static {
 181         registerNatives();
 182     }
 183 
 184     // The parent class loader for delegation
 185     // Note: VM hardcoded the offset of this field, thus all new fields
 186     // must be added *after* it.
 187     private final ClassLoader parent;
 188 
 189     /**
 190      * Encapsulates the set of parallel capable loader types.
 191      */
 192     private static class ParallelLoaders {
 193         private ParallelLoaders() {}
 194 
 195         // the set of parallel capable loader types
 196         private static final Set<Class<? extends ClassLoader>> loaderTypes =
 197             Collections.newSetFromMap(
 198                 new WeakHashMap<Class<? extends ClassLoader>, Boolean>());



 199         static {
 200             synchronized (loaderTypes) { loaderTypes.add(ClassLoader.class); }
 201         }
 202 
 203         /**
 204          * Registers the given class loader type as parallel capabale.
 205          * Returns {@code true} is successfully registered; {@code false} if
 206          * loader's super class is not registered.
 207          */
 208         static boolean register(Class<? extends ClassLoader> c) {

 209             synchronized (loaderTypes) {
 210                 if (loaderTypes.contains(c.getSuperclass())) {
 211                     // register the class loader as parallel capable
 212                     // if and only if all of its super classes are.
 213                     // Note: given current classloading sequence, if
 214                     // the immediate super class is parallel capable,
 215                     // all the super classes higher up must be too.
 216                     loaderTypes.add(c);


 217                     return true;
 218                 } else {
 219                     return false;
 220                 }
 221             }
 222         }
 223 
 224         /**
 225          * Returns {@code true} if the given class loader type is
 226          * registered as parallel capable.
 227          */
 228         static boolean isRegistered(Class<? extends ClassLoader> c) {
 229             synchronized (loaderTypes) {
 230                 return loaderTypes.contains(c);
 231             }
 232         }
 233     }
 234 
 235     // Maps class name to the corresponding lock object when the current
 236     // class loader is parallel capable.
 237     // Note: VM also uses this field to decide if the current class loader
 238     // is parallel capable and the appropriate lock object for class loading.
 239     private final ConcurrentHashMap<String, Object> parallelLockMap;
 240 










 241     // Hashtable that maps packages to certs
 242     private final Map <String, Certificate[]> package2certs;
 243 
 244     // Shared among all packages with unsigned classes
 245     private static final Certificate[] nocerts = new Certificate[0];
 246 
 247     // The classes loaded by this class loader. The only purpose of this table
 248     // is to keep the classes from being GC'ed until the loader is GC'ed.
 249     private final Vector<Class<?>> classes = new Vector<>();
 250 
 251     // The "default" domain. Set as the default ProtectionDomain on newly
 252     // created classes.
 253     private final ProtectionDomain defaultDomain =
 254         new ProtectionDomain(new CodeSource(null, (Certificate[]) null),
 255                              null, this, null);
 256 
 257     // The initiating protection domains for all classes loaded by this loader
 258     private final Set<ProtectionDomain> domains;
 259 
 260     // Invoked by the VM to record every loaded class with this loader.
 261     void addClass(Class<?> c) {
 262         classes.addElement(c);
 263     }
 264 
 265     // The packages defined in this class loader.  Each package name is mapped
 266     // to its corresponding Package object.
 267     // @GuardedBy("itself")
 268     private final HashMap<String, Package> packages = new HashMap<>();
 269 
 270     private static Void checkCreateClassLoader() {
 271         SecurityManager security = System.getSecurityManager();
 272         if (security != null) {
 273             security.checkCreateClassLoader();
 274         }
 275         return null;
 276     }
 277 
 278     private ClassLoader(Void unused, ClassLoader parent) {
 279         this.parent = parent;
 280         if (ParallelLoaders.isRegistered(this.getClass())) {





 281             parallelLockMap = new ConcurrentHashMap<>();
 282             package2certs = new ConcurrentHashMap<>();
 283             domains =
 284                 Collections.synchronizedSet(new HashSet<ProtectionDomain>());
 285             assertionLock = new Object();
 286         } else {
 287             // no finer-grained lock; lock on the classloader instance

 288             parallelLockMap = null;
 289             package2certs = new Hashtable<>();
 290             domains = new HashSet<>();
 291             assertionLock = this;
 292         }
 293     }
 294 
 295     /**
 296      * Creates a new class loader using the specified parent class loader for
 297      * delegation.
 298      *
 299      * <p> If there is a security manager, its {@link
 300      * SecurityManager#checkCreateClassLoader()
 301      * <tt>checkCreateClassLoader</tt>} method is invoked.  This may result in
 302      * a security exception.  </p>
 303      *
 304      * @param  parent
 305      *         The parent class loader
 306      *
 307      * @throws  SecurityException


 365      *
 366      *   <li><p> Invoke {@link #findLoadedClass(String)} to check if the class
 367      *   has already been loaded.  </p></li>
 368      *
 369      *   <li><p> Invoke the {@link #loadClass(String) <tt>loadClass</tt>} method
 370      *   on the parent class loader.  If the parent is <tt>null</tt> the class
 371      *   loader built-in to the virtual machine is used, instead.  </p></li>
 372      *
 373      *   <li><p> Invoke the {@link #findClass(String)} method to find the
 374      *   class.  </p></li>
 375      *
 376      * </ol>
 377      *
 378      * <p> If the class was found using the above steps, and the
 379      * <tt>resolve</tt> flag is true, this method will then invoke the {@link
 380      * #resolveClass(Class)} method on the resulting <tt>Class</tt> object.
 381      *
 382      * <p> Subclasses of <tt>ClassLoader</tt> are encouraged to override {@link
 383      * #findClass(String)}, rather than this method.  </p>
 384      *
 385      * <p> Unless overridden, this method synchronizes on the result of
 386      * {@link #getClassLoadingLock <tt>getClassLoadingLock</tt>} method
 387      * during the entire class loading process.


 388      *
 389      * @param  name
 390      *         The <a href="#name">binary name</a> of the class
 391      *
 392      * @param  resolve
 393      *         If <tt>true</tt> then resolve the class
 394      *
 395      * @return  The resulting <tt>Class</tt> object
 396      *
 397      * @throws  ClassNotFoundException
 398      *          If the class could not be found
 399      */
 400     protected Class<?> loadClass(String name, boolean resolve)
 401         throws ClassNotFoundException
 402     {


 403         synchronized (getClassLoadingLock(name)) {



















 404             // First, check if the class has already been loaded
 405             Class<?> c = findLoadedClass(name);
 406             if (c == null) {
 407                 long t0 = System.nanoTime();
 408                 try {
 409                     if (parent != null) {
 410                         c = parent.loadClass(name, false);
 411                     } else {
 412                         c = findBootstrapClassOrNull(name);
 413                     }
 414                 } catch (ClassNotFoundException e) {
 415                     // ClassNotFoundException thrown if class not found
 416                     // from the non-null parent class loader
 417                 }
 418 
 419                 if (c == null) {
 420                     // If still not found, then invoke findClass in order
 421                     // to find the class.
 422                     long t1 = System.nanoTime();
 423                     c = findClass(name);
 424 
 425                     // this is the defining class loader; record the stats
 426                     sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
 427                     sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
 428                     sun.misc.PerfCounter.getFindClasses().increment();
 429                 }
 430             }
 431             if (resolve) {
 432                 resolveClass(c);
 433             }
 434             return c;
 435         }
 436     }
 437 
 438     /**
 439      * Returns the lock object for class loading operations.
 440      * For backward compatibility, the default implementation of this method
 441      * behaves as follows. If this ClassLoader object is registered as
 442      * parallel capable, the method returns a dedicated object associated
 443      * with the specified class name. Otherwise, the method returns this
 444      * ClassLoader object. </p>
 445      *
 446      * @param  className
 447      *         The name of the to-be-loaded class
 448      *
 449      * @return the lock for class loading operations
 450      *
 451      * @throws NullPointerException
 452      *         If registered as parallel capable and <tt>className</tt> is null
 453      *
 454      * @see #loadClass(String, boolean)
 455      *
 456      * @since  1.7
 457      */
 458     protected Object getClassLoadingLock(String className) {
 459         Object lock = this;
 460         if (parallelLockMap != null) {
 461             Object newLock = new Object();
 462             lock = parallelLockMap.putIfAbsent(className, newLock);
 463             if (lock == null) {
 464                 lock = newLock;
 465             }
 466         }



 467         return lock;
 468     }
 469 
 470     // This method is invoked by the virtual machine to load a class.
 471     private Class<?> loadClassInternal(String name)
 472         throws ClassNotFoundException
 473     {
 474         // For backward compatibility, explicitly lock on 'this' when
 475         // the current class loader is not parallel capable.
 476         if (parallelLockMap == null) {
 477             synchronized (this) {
 478                  return loadClass(name);
 479             }
 480         } else {
 481             return loadClass(name);
 482         }
 483     }
 484 
 485     // Invoked by the VM after loading class with this loader.
 486     private void checkPackageAccess(Class<?> cls, ProtectionDomain pd) {
 487         final SecurityManager sm = System.getSecurityManager();
 488         if (sm != null) {
 489             final String name = cls.getName();
 490             final int i = name.lastIndexOf('.');
 491             if (i != -1) {
 492                 AccessController.doPrivileged(new PrivilegedAction<Void>() {
 493                     public Void run() {
 494                         sm.checkPackageAccess(name.substring(0, i));
 495                         return null;
 496                     }


 911 
 912     // true if the name is null or has the potential to be a valid binary name
 913     private boolean checkName(String name) {
 914         if ((name == null) || (name.length() == 0))
 915             return true;
 916         if ((name.indexOf('/') != -1)
 917             || (!VM.allowArraySyntax() && (name.charAt(0) == '[')))
 918             return false;
 919         return true;
 920     }
 921 
 922     private void checkCerts(String name, CodeSource cs) {
 923         int i = name.lastIndexOf('.');
 924         String pname = (i == -1) ? "" : name.substring(0, i);
 925 
 926         Certificate[] certs = null;
 927         if (cs != null) {
 928             certs = cs.getCertificates();
 929         }
 930         Certificate[] pcerts = null;
 931         if (parallelLockMap == null) {
 932             synchronized (this) {
 933                 pcerts = package2certs.get(pname);
 934                 if (pcerts == null) {
 935                     package2certs.put(pname, (certs == null? nocerts:certs));
 936                 }
 937             }
 938         } else {
 939             pcerts = ((ConcurrentHashMap<String, Certificate[]>)package2certs).
 940                 putIfAbsent(pname, (certs == null? nocerts:certs));
 941         }
 942         if (pcerts != null && !compareCerts(pcerts, certs)) {
 943             throw new SecurityException("class \""+ name +
 944                  "\"'s signer information does not match signer information of other classes in the same package");
 945         }
 946     }
 947 
 948     /**
 949      * check to make sure the certs for the new class (certs) are the same as
 950      * the certs for the first class inserted in the package (pcerts)
 951      */


1213      * @since  1.2
1214      */
1215     protected Enumeration<URL> findResources(String name) throws IOException {
1216         return java.util.Collections.emptyEnumeration();
1217     }
1218 
1219     // index 0: java.lang.ClassLoader.class
1220     // index 1: the immediate caller of index 0.
1221     // index 2: the immediate caller of index 1.
1222     private static native Class<? extends ClassLoader> getCaller(int index);
1223 
1224     /**
1225      * Registers the caller as parallel capable.</p>
1226      * The registration succeeds if and only if all of the following
1227      * conditions are met: <br>
1228      * 1. no instance of the caller has been created</p>
1229      * 2. all of the super classes (except class Object) of the caller are
1230      * registered as parallel capable</p>
1231      * Note that once a class loader is registered as parallel capable, there
1232      * is no way to change it back. </p>



1233      *
1234      * @return  true if the caller is successfully registered as
1235      *          parallel capable and false if otherwise.
1236      *
1237      * @since   1.7
1238      */
1239     protected static boolean registerAsParallelCapable() {
1240         return ParallelLoaders.register(getCaller(1));




















1241     }
1242 
1243     /**
1244      * Find a resource of the specified name from the search path used to load
1245      * classes.  This method locates the resource through the system class
1246      * loader (see {@link #getSystemClassLoader()}).  </p>
1247      *
1248      * @param  name
1249      *         The resource name
1250      *
1251      * @return  A {@link java.net.URL <tt>URL</tt>} object for reading the
1252      *          resource, or <tt>null</tt> if the resource could not be found
1253      *
1254      * @since  1.1
1255      */
1256     public static URL getSystemResource(String name) {
1257         ClassLoader system = getSystemClassLoader();
1258         if (system == null) {
1259             return getBootstrapResource(name);
1260         }




  91  * resource, a <tt>ClassLoader</tt> instance will delegate the search for the
  92  * class or resource to its parent class loader before attempting to find the
  93  * class or resource itself.  The virtual machine's built-in class loader,
  94  * called the "bootstrap class loader", does not itself have a parent but may
  95  * serve as the parent of a <tt>ClassLoader</tt> instance.
  96  *
  97  * <p> Class loaders that support concurrent loading of classes are known as
  98  * <em>parallel capable</em> class loaders and are required to register
  99  * themselves at their class initialization time by invoking the
 100  * {@link
 101  * #registerAsParallelCapable <tt>ClassLoader.registerAsParallelCapable</tt>}
 102  * method. Note that the <tt>ClassLoader</tt> class is registered as parallel
 103  * capable by default. However, its subclasses still need to register themselves
 104  * if they are parallel capable. <br>
 105  * In environments in which the delegation model is not strictly
 106  * hierarchical, class loaders need to be parallel capable, otherwise class
 107  * loading can lead to deadlocks because the loader lock is held for the
 108  * duration of the class loading process (see {@link #loadClass
 109  * <tt>loadClass</tt>} methods).
 110  *
 111  * <p>Regular parallel capable class loaders may still need to use some form 
 112  * of synchronization to control concurrent load attempts of a given class.
 113  * The {@link #getClassLoadingLock getClassLoadingLock} method is used to
 114  * provide that object for use by {@link #loadClass loadClass}. A class loader
 115  * can support fully concurrent loading of any class, in which case no
 116  * synchronization need be used. Such parallel capable class loaders are 
 117  * required to register themselves at their class initialization time by 
 118  * invoking the
 119  * {@link #registerAsFullyConcurrent registerAsFullyConcurrent} method. 
 120  * Note that the <tt>ClassLoader</tt> class is registered as fully
 121  * concurrent by default. However, its subclasses still need to register 
 122  * themselves if they capable of fully concurrent class loading.
 123  *
 124  * <p> Normally, the Java virtual machine loads classes from the local file
 125  * system in a platform-dependent manner.  For example, on UNIX systems, the
 126  * virtual machine loads classes from the directory defined by the
 127  * <tt>CLASSPATH</tt> environment variable.
 128  *
 129  * <p> However, some classes may not originate from a file; they may originate
 130  * from other sources, such as the network, or they could be constructed by an
 131  * application.  The method {@link #defineClass(String, byte[], int, int)
 132  * <tt>defineClass</tt>} converts an array of bytes into an instance of class
 133  * <tt>Class</tt>. Instances of this newly defined class can be created using
 134  * {@link Class#newInstance <tt>Class.newInstance</tt>}.
 135  *
 136  * <p> The methods and constructors of objects created by a class loader may
 137  * reference other classes.  To determine the class(es) referred to, the Java
 138  * virtual machine invokes the {@link #loadClass <tt>loadClass</tt>} method of
 139  * the class loader that originally created the class.
 140  *
 141  * <p> For example, an application could create a network class loader to
 142  * download class files from a server.  Sample code might look like:
 143  *


 189  */
 190 public abstract class ClassLoader {
 191 
 192     private static native void registerNatives();
 193     static {
 194         registerNatives();
 195     }
 196 
 197     // The parent class loader for delegation
 198     // Note: VM hardcoded the offset of this field, thus all new fields
 199     // must be added *after* it.
 200     private final ClassLoader parent;
 201 
 202     /**
 203      * Encapsulates the set of parallel capable loader types.
 204      */
 205     private static class ParallelLoaders {
 206         private ParallelLoaders() {}
 207 
 208         // the set of parallel capable loader types
 209         // - loader in the map -> parallel capable
 210         // - loader maps to TRUE -> fully concurrent
 211         private static final WeakHashMap<Class<? extends ClassLoader>, 
 212                                                  Boolean> loaderTypes = 
 213                                                  new WeakHashMap<>();
 214 
 215          static {
 216             synchronized (loaderTypes) { loaderTypes.put(ClassLoader.class, Boolean.TRUE); }
 217         }
 218 
 219         /**
 220          * Registers the given class loader type as parallel capable.
 221          * Returns {@code true} is successfully registered; {@code false} if
 222          * loader's super class is not registered.
 223          */
 224       static boolean register(Class<? extends ClassLoader> c, 
 225                               boolean fullyConcurrent) {
 226             synchronized (loaderTypes) {
 227                 if (loaderTypes.containsKey(c.getSuperclass())) {
 228                     // register the class loader as parallel capable
 229                     // if and only if all of its super classes are.
 230                     // Note: given current classloading sequence, if
 231                     // the immediate super class is parallel capable,
 232                     // all the super classes higher up must be too.
 233                     loaderTypes.put(c, fullyConcurrent);
 234                     System.out.println("Registered: " + c.getName() + " as " +
 235                                        (fullyConcurrent ? "fully concurrent " : " parallel capable") + " classloader");
 236                     return true;
 237                 } else {
 238                     return false;
 239                 }
 240             }
 241         }
 242 
 243         /**
 244          * Returns the value of the given loader in the parallel
 245          * loader map, else null.
 246          */
 247         static Boolean getRegistration(Class<? extends ClassLoader> c) {
 248             synchronized(loaderTypes) {
 249                 return loaderTypes.get(c);
 250             }
 251         }
 252     }
 253 
 254     // Maps class name to the corresponding lock object when the current
 255     // class loader is parallel capable.
 256     // Note: VM also uses this field to decide if the current class loader
 257     // is parallel capable and the appropriate lock object for class loading.
 258     private final ConcurrentHashMap<String, Object> parallelLockMap;
 259 
 260     // Indicates this parallel capable loader supports fully concurrent loading
 261     // Note: the VM uses this field to decide if the current class loader
 262     // allows parallel class definition
 263     private final boolean isFullyConcurrent;
 264 
 265     // Indicate if this loader is parallel capable
 266     private boolean isParallelCapable() {
 267         return parallelLockMap != null || isFullyConcurrent;
 268     }
 269 
 270     // Hashtable that maps packages to certs
 271     private final Map <String, Certificate[]> package2certs;
 272 
 273     // Shared among all packages with unsigned classes
 274     private static final Certificate[] nocerts = new Certificate[0];
 275 
 276     // The classes loaded by this class loader. The only purpose of this table
 277     // is to keep the classes from being GC'ed until the loader is GC'ed.
 278     private final Vector<Class<?>> classes = new Vector<>();
 279 
 280     // The "default" domain. Set as the default ProtectionDomain on newly
 281     // created classes.
 282     private final ProtectionDomain defaultDomain =
 283         new ProtectionDomain(new CodeSource(null, (Certificate[]) null),
 284                              null, this, null);
 285 
 286     // The initiating protection domains for all classes loaded by this loader
 287     private final Set<ProtectionDomain> domains;
 288 
 289     // Invoked by the VM to record every loaded class with this loader.
 290     void addClass(Class<?> c) {
 291         classes.addElement(c);
 292     }
 293 
 294     // The packages defined in this class loader.  Each package name is mapped
 295     // to its corresponding Package object.
 296     // @GuardedBy("itself")
 297     private final HashMap<String, Package> packages = new HashMap<>();
 298 
 299     private static Void checkCreateClassLoader() {
 300         SecurityManager security = System.getSecurityManager();
 301         if (security != null) {
 302             security.checkCreateClassLoader();
 303         }
 304         return null;
 305     }
 306 
 307     private ClassLoader(Void unused, ClassLoader parent) {
 308         this.parent = parent;
 309         Boolean reg = ParallelLoaders.getRegistration(this.getClass());
 310         if (reg != null) {
 311             isFullyConcurrent = reg;
 312             if (isFullyConcurrent)
 313                 parallelLockMap = null;
 314             else
 315                 parallelLockMap = new ConcurrentHashMap<>();
 316             package2certs = new ConcurrentHashMap<>();
 317             domains =
 318                 Collections.synchronizedSet(new HashSet<ProtectionDomain>());
 319             assertionLock = new Object();
 320         } else {
 321             // no finer-grained lock; lock on the classloader instance
 322             isFullyConcurrent = false;
 323             parallelLockMap = null;
 324             package2certs = new Hashtable<>();
 325             domains = new HashSet<>();
 326             assertionLock = this;
 327         }
 328     }
 329 
 330     /**
 331      * Creates a new class loader using the specified parent class loader for
 332      * delegation.
 333      *
 334      * <p> If there is a security manager, its {@link
 335      * SecurityManager#checkCreateClassLoader()
 336      * <tt>checkCreateClassLoader</tt>} method is invoked.  This may result in
 337      * a security exception.  </p>
 338      *
 339      * @param  parent
 340      *         The parent class loader
 341      *
 342      * @throws  SecurityException


 400      *
 401      *   <li><p> Invoke {@link #findLoadedClass(String)} to check if the class
 402      *   has already been loaded.  </p></li>
 403      *
 404      *   <li><p> Invoke the {@link #loadClass(String) <tt>loadClass</tt>} method
 405      *   on the parent class loader.  If the parent is <tt>null</tt> the class
 406      *   loader built-in to the virtual machine is used, instead.  </p></li>
 407      *
 408      *   <li><p> Invoke the {@link #findClass(String)} method to find the
 409      *   class.  </p></li>
 410      *
 411      * </ol>
 412      *
 413      * <p> If the class was found using the above steps, and the
 414      * <tt>resolve</tt> flag is true, this method will then invoke the {@link
 415      * #resolveClass(Class)} method on the resulting <tt>Class</tt> object.
 416      *
 417      * <p> Subclasses of <tt>ClassLoader</tt> are encouraged to override {@link
 418      * #findClass(String)}, rather than this method.  </p>
 419      *
 420      * <p> Unless overridden, if this loader is not fully concurrent then 
 421      * this method synchronizes on the result
 422      * of the {@link #getClassLoadingLock <tt>getClassLoadingLock</tt>} method
 423      * during the entire class loading process. For a fully concurrent loader
 424      * no synchronization occurs.
 425      *
 426      * @param  name
 427      *         The <a href="#name">binary name</a> of the class
 428      *
 429      * @param  resolve
 430      *         If <tt>true</tt> then resolve the class
 431      *
 432      * @return  The resulting <tt>Class</tt> object
 433      *
 434      * @throws  ClassNotFoundException
 435      *          If the class could not be found
 436      */
 437     protected Class<?> loadClass(String name, boolean resolve)
 438         throws ClassNotFoundException
 439     {
 440         Class<?> c = null;
 441         if (!isFullyConcurrent) {
 442             synchronized (getClassLoadingLock(name)) {
 443                 c = do_loadClass(name);
 444                 if (resolve) {
 445                     resolveClass(c);
 446                 }
 447             }
 448         }
 449         else {
 450             c = do_loadClass(name);
 451             if (resolve) {
 452                 resolveClass(c);
 453             }
 454         }
 455         return c;
 456     }
 457 
 458 
 459     private Class<?> do_loadClass(String name) 
 460         throws ClassNotFoundException
 461     {
 462         // First, check if the class has already been loaded
 463         Class<?> c = findLoadedClass(name);
 464         if (c == null) {
 465             long t0 = System.nanoTime();
 466             try {
 467                 if (parent != null) {
 468                     c = parent.loadClass(name, false);
 469                 } else {
 470                     c = findBootstrapClassOrNull(name);
 471                 }
 472             } catch (ClassNotFoundException e) {
 473                 // ClassNotFoundException thrown if class not found
 474                 // from the non-null parent class loader
 475             }
 476 
 477             if (c == null) {
 478                 // If still not found, then invoke findClass in order
 479                 // to find the class.
 480                 long t1 = System.nanoTime();
 481                 c = findClass(name);
 482 
 483                 // this is the defining class loader; record the stats
 484                 sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
 485                 sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
 486                 sun.misc.PerfCounter.getFindClasses().increment();
 487             }
 488         }



 489         return c;
 490     }

 491 
 492     /**
 493      * Returns the lock object for class loading operations.
 494      * For backward compatibility, the default implementation of this method
 495      * behaves as follows. If this ClassLoader object is registered as
 496      * parallel capable, the method returns a dedicated object associated
 497      * with the specified class name. Otherwise, the method returns this
 498      * ClassLoader object. </p>
 499      *
 500      * @param  className
 501      *         The name of the to-be-loaded class
 502      *
 503      * @return the lock for class loading operations
 504      *
 505      * @throws NullPointerException
 506      *         If registered as parallel capable and <tt>className</tt> is null
 507      *
 508      * @see #loadClass(String, boolean)
 509      *
 510      * @since  1.7
 511      */
 512     protected Object getClassLoadingLock(String className) {
 513         Object lock = this;
 514         if (parallelLockMap != null) {
 515             Object newLock = new Object();
 516             lock = parallelLockMap.putIfAbsent(className, newLock);
 517             if (lock == null) {
 518                 lock = newLock;
 519             }
 520         }
 521         else if (isFullyConcurrent) {
 522             lock = null; // TBD: is this the best thing to return?
 523         }
 524         return lock;
 525     }
 526 
 527     // This method is invoked by the virtual machine to load a class.
 528     private Class<?> loadClassInternal(String name)
 529         throws ClassNotFoundException
 530     {
 531         // For backward compatibility, explicitly lock on 'this' when
 532         // the current class loader is not parallel capable.
 533         if (!isParallelCapable()) {
 534             synchronized (this) {
 535                  return loadClass(name);
 536             }
 537         } else {
 538             return loadClass(name);
 539         }
 540     }
 541 
 542     // Invoked by the VM after loading class with this loader.
 543     private void checkPackageAccess(Class<?> cls, ProtectionDomain pd) {
 544         final SecurityManager sm = System.getSecurityManager();
 545         if (sm != null) {
 546             final String name = cls.getName();
 547             final int i = name.lastIndexOf('.');
 548             if (i != -1) {
 549                 AccessController.doPrivileged(new PrivilegedAction<Void>() {
 550                     public Void run() {
 551                         sm.checkPackageAccess(name.substring(0, i));
 552                         return null;
 553                     }


 968 
 969     // true if the name is null or has the potential to be a valid binary name
 970     private boolean checkName(String name) {
 971         if ((name == null) || (name.length() == 0))
 972             return true;
 973         if ((name.indexOf('/') != -1)
 974             || (!VM.allowArraySyntax() && (name.charAt(0) == '[')))
 975             return false;
 976         return true;
 977     }
 978 
 979     private void checkCerts(String name, CodeSource cs) {
 980         int i = name.lastIndexOf('.');
 981         String pname = (i == -1) ? "" : name.substring(0, i);
 982 
 983         Certificate[] certs = null;
 984         if (cs != null) {
 985             certs = cs.getCertificates();
 986         }
 987         Certificate[] pcerts = null;
 988         if (!isParallelCapable()) {
 989             synchronized (this) {
 990                 pcerts = package2certs.get(pname);
 991                 if (pcerts == null) {
 992                     package2certs.put(pname, (certs == null? nocerts:certs));
 993                 }
 994             }
 995         } else {
 996             pcerts = ((ConcurrentHashMap<String, Certificate[]>)package2certs).
 997                 putIfAbsent(pname, (certs == null? nocerts:certs));
 998         }
 999         if (pcerts != null && !compareCerts(pcerts, certs)) {
1000             throw new SecurityException("class \""+ name +
1001                  "\"'s signer information does not match signer information of other classes in the same package");
1002         }
1003     }
1004 
1005     /**
1006      * check to make sure the certs for the new class (certs) are the same as
1007      * the certs for the first class inserted in the package (pcerts)
1008      */


1270      * @since  1.2
1271      */
1272     protected Enumeration<URL> findResources(String name) throws IOException {
1273         return java.util.Collections.emptyEnumeration();
1274     }
1275 
1276     // index 0: java.lang.ClassLoader.class
1277     // index 1: the immediate caller of index 0.
1278     // index 2: the immediate caller of index 1.
1279     private static native Class<? extends ClassLoader> getCaller(int index);
1280 
1281     /**
1282      * Registers the caller as parallel capable.</p>
1283      * The registration succeeds if and only if all of the following
1284      * conditions are met: <br>
1285      * 1. no instance of the caller has been created</p>
1286      * 2. all of the super classes (except class Object) of the caller are
1287      * registered as parallel capable</p>
1288      * Note that once a class loader is registered as parallel capable, there
1289      * is no way to change it back. </p>
1290      * <p>
1291      * Class loaders that are fully concurrent parallel capable should
1292      * use {@link #registerAsFullyConcurrent} to register. </p>
1293      *
1294      * @return  true if the caller is successfully registered as
1295      *          parallel capable and false if otherwise.
1296      *
1297      * @since   1.7
1298      */
1299     protected static boolean registerAsParallelCapable() {
1300       return ParallelLoaders.register(getCaller(1), false);
1301     }
1302 
1303     /**
1304      * Registers the caller as  a fully concurrent parallel capable
1305      * class loader.</p>
1306      * The registration succeeds if and only if all of the following
1307      * conditions are met: <br>
1308      * 1. no instance of the caller has been created</p>
1309      * 2. all of the super classes (except class Object) of the caller are
1310      * registered as parallel capable</p>
1311      * Note that once a class loader is registered as fully concurrent
1312      * parallel capable, there is no way to change it back. </p>
1313      *
1314      * @return  true if the caller is successfully registered as
1315      *          fully concurrent parallel capable and false if otherwise.
1316      *
1317      * @since   1.8
1318      */
1319     protected static boolean registerAsFullyConcurrent() {
1320       return ParallelLoaders.register(getCaller(1), true);
1321     }
1322 
1323     /**
1324      * Find a resource of the specified name from the search path used to load
1325      * classes.  This method locates the resource through the system class
1326      * loader (see {@link #getSystemClassLoader()}).  </p>
1327      *
1328      * @param  name
1329      *         The resource name
1330      *
1331      * @return  A {@link java.net.URL <tt>URL</tt>} object for reading the
1332      *          resource, or <tt>null</tt> if the resource could not be found
1333      *
1334      * @since  1.1
1335      */
1336     public static URL getSystemResource(String name) {
1337         ClassLoader system = getSystemClassLoader();
1338         if (system == null) {
1339             return getBootstrapResource(name);
1340         }


src/share/classes/java/lang/ClassLoader.java
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File