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

Print this page




  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package java.lang;
  26 
  27 import java.io.InputStream;
  28 import java.io.IOException;
  29 import java.io.File;
  30 import java.lang.reflect.Constructor;
  31 import java.lang.reflect.InvocationTargetException;
  32 import java.net.MalformedURLException;
  33 import java.net.URL;
  34 import java.security.AccessController;
  35 import java.security.AccessControlContext;
  36 import java.security.CodeSource;
  37 import java.security.Policy;
  38 import java.security.PrivilegedAction;
  39 import java.security.PrivilegedActionException;
  40 import java.security.PrivilegedExceptionAction;
  41 import java.security.ProtectionDomain;
  42 import java.security.cert.Certificate;
  43 import java.util.Collections;
  44 import java.util.Enumeration;
  45 import java.util.HashMap;
  46 import java.util.HashSet;
  47 import java.util.Set;
  48 import java.util.Stack;
  49 import java.util.Map;
  50 import java.util.Vector;
  51 import java.util.Hashtable;
  52 import java.util.WeakHashMap;
  53 import java.util.concurrent.ConcurrentHashMap;
  54 import sun.misc.CompoundEnumeration;
  55 import sun.misc.Resource;
  56 import sun.misc.URLClassPath;
  57 import sun.misc.VM;
  58 import sun.reflect.CallerSensitive;
  59 import sun.reflect.Reflection;
  60 import sun.reflect.misc.ReflectUtil;
  61 import sun.security.util.SecurityConstants;
  62 
  63 /**
  64  * A class loader is an object that is responsible for loading classes. The
  65  * class <tt>ClassLoader</tt> is an abstract class.  Given the <a
  66  * href="#name">binary name</a> of a class, a class loader should attempt to
  67  * locate or generate data that constitutes a definition for the class.  A
  68  * typical strategy is to transform the name into a file name and then read a
  69  * "class file" of that name from a file system.
  70  *
  71  * <p> Every {@link Class <tt>Class</tt>} object contains a {@link
  72  * Class#getClassLoader() reference} to the <tt>ClassLoader</tt> that defined
  73  * it.
  74  *
  75  * <p> <tt>Class</tt> objects for array classes are not created by class
  76  * loaders, but are created automatically as required by the Java runtime.
  77  * The class loader for an array class, as returned by {@link


 219                     // all the super classes higher up must be too.
 220                     loaderTypes.add(c);
 221                     return true;
 222                 } else {
 223                     return false;
 224                 }
 225             }
 226         }
 227 
 228         /**
 229          * Returns {@code true} if the given class loader type is
 230          * registered as parallel capable.
 231          */
 232         static boolean isRegistered(Class<? extends ClassLoader> c) {
 233             synchronized (loaderTypes) {
 234                 return loaderTypes.contains(c);
 235             }
 236         }
 237     }
 238 









 239     // Maps class name to the corresponding lock object when the current
 240     // class loader is parallel capable.
 241     // Note: VM also uses this field to decide if the current class loader
 242     // is parallel capable and the appropriate lock object for class loading.
 243     private final ConcurrentHashMap<String, Object> parallelLockMap;
 244 
 245     // Hashtable that maps packages to certs
 246     private final Map <String, Certificate[]> package2certs;
 247 
 248     // Shared among all packages with unsigned classes
 249     private static final Certificate[] nocerts = new Certificate[0];
 250 
 251     // The classes loaded by this class loader. The only purpose of this table
 252     // is to keep the classes from being GC'ed until the loader is GC'ed.
 253     private final Vector<Class<?>> classes = new Vector<>();
 254 
 255     // The "default" domain. Set as the default ProtectionDomain on newly
 256     // created classes.
 257     private final ProtectionDomain defaultDomain =
 258         new ProtectionDomain(new CodeSource(null, (Certificate[]) null),
 259                              null, this, null);
 260 
 261     // The initiating protection domains for all classes loaded by this loader
 262     private final Set<ProtectionDomain> domains;
 263 


 339 
 340     // -- Class --
 341 
 342     /**
 343      * Loads the class with the specified <a href="#name">binary name</a>.
 344      * This method searches for classes in the same manner as the {@link
 345      * #loadClass(String, boolean)} method.  It is invoked by the Java virtual
 346      * machine to resolve class references.  Invoking this method is equivalent
 347      * to invoking {@link #loadClass(String, boolean) <tt>loadClass(name,
 348      * false)</tt>}.
 349      *
 350      * @param  name
 351      *         The <a href="#name">binary name</a> of the class
 352      *
 353      * @return  The resulting <tt>Class</tt> object
 354      *
 355      * @throws  ClassNotFoundException
 356      *          If the class was not found
 357      */
 358     public Class<?> loadClass(String name) throws ClassNotFoundException {




 359         return loadClass(name, false);

















 360     }
 361 
 362     /**
 363      * Loads the class with the specified <a href="#name">binary name</a>.  The
 364      * default implementation of this method searches for classes in the
 365      * following order:
 366      *
 367      * <ol>
 368      *
 369      *   <li><p> Invoke {@link #findLoadedClass(String)} to check if the class
 370      *   has already been loaded.  </p></li>
 371      *
 372      *   <li><p> Invoke the {@link #loadClass(String) <tt>loadClass</tt>} method
 373      *   on the parent class loader.  If the parent is <tt>null</tt> the class
 374      *   loader built-in to the virtual machine is used, instead.  </p></li>
 375      *
 376      *   <li><p> Invoke the {@link #findClass(String)} method to find the
 377      *   class.  </p></li>
 378      *
 379      * </ol>


 386      * #findClass(String)}, rather than this method.  </p>
 387      *
 388      * <p> Unless overridden, this method synchronizes on the result of
 389      * {@link #getClassLoadingLock <tt>getClassLoadingLock</tt>} method
 390      * during the entire class loading process.
 391      *
 392      * @param  name
 393      *         The <a href="#name">binary name</a> of the class
 394      *
 395      * @param  resolve
 396      *         If <tt>true</tt> then resolve the class
 397      *
 398      * @return  The resulting <tt>Class</tt> object
 399      *
 400      * @throws  ClassNotFoundException
 401      *          If the class could not be found
 402      */
 403     protected Class<?> loadClass(String name, boolean resolve)
 404         throws ClassNotFoundException
 405     {
 406         synchronized (getClassLoadingLock(name)) {

 407             // First, check if the class has already been loaded
 408             Class<?> c = findLoadedClass(name);















 409             if (c == null) {
 410                 long t0 = System.nanoTime();
 411                 try {
 412                     if (parent != null) {
 413                         c = parent.loadClass(name, false);
 414                     } else {
 415                         c = findBootstrapClassOrNull(name);
 416                     }
 417                 } catch (ClassNotFoundException e) {
 418                     // ClassNotFoundException thrown if class not found
 419                     // from the non-null parent class loader
 420                 }
 421 
 422                 if (c == null) {
 423                     // If still not found, then invoke findClass in order
 424                     // to find the class.
 425                     long t1 = System.nanoTime();
 426                     c = findClass(name);
 427 
 428                     // this is the defining class loader; record the stats
 429                     sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
 430                     sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
 431                     sun.misc.PerfCounter.getFindClasses().increment();
 432                 }






 433             }
 434             if (resolve) {
 435                 resolveClass(c);
 436             }
 437             return c;
 438         }
 439     }
 440 
 441     /**
 442      * Returns the lock object for class loading operations.
 443      * For backward compatibility, the default implementation of this method
 444      * behaves as follows. If this ClassLoader object is registered as
 445      * parallel capable, the method returns a dedicated object associated
 446      * with the specified class name. Otherwise, the method returns this
 447      * ClassLoader object.
 448      *
 449      * @param  className
 450      *         The name of the to-be-loaded class
 451      *
 452      * @return the lock for class loading operations
 453      *
 454      * @throws NullPointerException
 455      *         If registered as parallel capable and <tt>className</tt> is null
 456      *
 457      * @see #loadClass(String, boolean)
 458      *
 459      * @since  1.7
 460      */
 461     protected Object getClassLoadingLock(String className) {
 462         Object lock = this;
 463         if (parallelLockMap != null) {
 464             Object newLock = new Object();
 465             lock = parallelLockMap.putIfAbsent(className, newLock);
 466             if (lock == null) {
 467                 lock = newLock;
 468             }
 469         }
 470         return lock;
 471     }
 472 
 473     // This method is invoked by the virtual machine to load a class.
 474     private Class<?> loadClassInternal(String name)
 475         throws ClassNotFoundException
 476     {
 477         // For backward compatibility, explicitly lock on 'this' when
 478         // the current class loader is not parallel capable.
 479         if (parallelLockMap == null) {
 480             synchronized (this) {
 481                  return loadClass(name);
 482             }
 483         } else {
 484             return loadClass(name);


 512 
 513     /**
 514      * Finds the class with the specified <a href="#name">binary name</a>.
 515      * This method should be overridden by class loader implementations that
 516      * follow the delegation model for loading classes, and will be invoked by
 517      * the {@link #loadClass <tt>loadClass</tt>} method after checking the
 518      * parent class loader for the requested class.  The default implementation
 519      * throws a <tt>ClassNotFoundException</tt>.
 520      *
 521      * @param  name
 522      *         The <a href="#name">binary name</a> of the class
 523      *
 524      * @return  The resulting <tt>Class</tt> object
 525      *
 526      * @throws  ClassNotFoundException
 527      *          If the class could not be found
 528      *
 529      * @since  1.2
 530      */
 531     protected Class<?> findClass(String name) throws ClassNotFoundException {
 532         throw new ClassNotFoundException(name);






 533     }
 534 
 535     /**
 536      * Converts an array of bytes into an instance of class <tt>Class</tt>.
 537      * Before the <tt>Class</tt> can be used it must be resolved.  This method
 538      * is deprecated in favor of the version that takes a <a
 539      * href="#name">binary name</a> as its first argument, and is more secure.
 540      *
 541      * @param  b
 542      *         The bytes that make up the class data.  The bytes in positions
 543      *         <tt>off</tt> through <tt>off+len-1</tt> should have the format
 544      *         of a valid class file as defined by
 545      *         <cite>The Java&trade; Virtual Machine Specification</cite>.
 546      *
 547      * @param  off
 548      *         The start offset in <tt>b</tt> of the class data
 549      *
 550      * @param  len
 551      *         The length of the class data
 552      *




  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package java.lang;
  26 
  27 import java.io.InputStream;
  28 import java.io.IOException;
  29 import java.io.File;
  30 import java.lang.reflect.Constructor;
  31 import java.lang.reflect.InvocationTargetException;

  32 import java.net.URL;
  33 import java.security.AccessController;
  34 import java.security.AccessControlContext;
  35 import java.security.CodeSource;

  36 import java.security.PrivilegedAction;
  37 import java.security.PrivilegedActionException;
  38 import java.security.PrivilegedExceptionAction;
  39 import java.security.ProtectionDomain;
  40 import java.security.cert.Certificate;
  41 import java.util.Collections;
  42 import java.util.Enumeration;
  43 import java.util.HashMap;
  44 import java.util.HashSet;
  45 import java.util.Set;
  46 import java.util.Stack;
  47 import java.util.Map;
  48 import java.util.Vector;
  49 import java.util.Hashtable;
  50 import java.util.WeakHashMap;
  51 import java.util.concurrent.ConcurrentHashMap;
  52 import sun.misc.CompoundEnumeration;
  53 import sun.misc.Resource;
  54 import sun.misc.URLClassPath;

  55 import sun.reflect.CallerSensitive;
  56 import sun.reflect.Reflection;
  57 import sun.reflect.misc.ReflectUtil;
  58 import sun.security.util.SecurityConstants;
  59 
  60 /**
  61  * A class loader is an object that is responsible for loading classes. The
  62  * class <tt>ClassLoader</tt> is an abstract class.  Given the <a
  63  * href="#name">binary name</a> of a class, a class loader should attempt to
  64  * locate or generate data that constitutes a definition for the class.  A
  65  * typical strategy is to transform the name into a file name and then read a
  66  * "class file" of that name from a file system.
  67  *
  68  * <p> Every {@link Class <tt>Class</tt>} object contains a {@link
  69  * Class#getClassLoader() reference} to the <tt>ClassLoader</tt> that defined
  70  * it.
  71  *
  72  * <p> <tt>Class</tt> objects for array classes are not created by class
  73  * loaders, but are created automatically as required by the Java runtime.
  74  * The class loader for an array class, as returned by {@link


 216                     // all the super classes higher up must be too.
 217                     loaderTypes.add(c);
 218                     return true;
 219                 } else {
 220                     return false;
 221                 }
 222             }
 223         }
 224 
 225         /**
 226          * Returns {@code true} if the given class loader type is
 227          * registered as parallel capable.
 228          */
 229         static boolean isRegistered(Class<? extends ClassLoader> c) {
 230             synchronized (loaderTypes) {
 231                 return loaderTypes.contains(c);
 232             }
 233         }
 234     }
 235 
 236     // A lock object with a boolean flag indicating that loading of
 237     // a class with particular name has been attempted and attempt
 238     // was successful.
 239     // Note: this is used to avoid findLoadedClass() calls when
 240     // 1st request for a particular class name arrives.
 241     private static class Lock {
 242         boolean attempted;
 243     }
 244 
 245     // Maps class name to the corresponding lock object when the current
 246     // class loader is parallel capable.
 247     // Note: VM also uses this field to decide if the current class loader
 248     // is parallel capable and the appropriate lock object for class loading.
 249     private final ConcurrentHashMap<String, Lock> parallelLockMap;
 250 
 251     // Hashtable that maps packages to certs
 252     private final Map <String, Certificate[]> package2certs;
 253 
 254     // Shared among all packages with unsigned classes
 255     private static final Certificate[] nocerts = new Certificate[0];
 256 
 257     // The classes loaded by this class loader. The only purpose of this table
 258     // is to keep the classes from being GC'ed until the loader is GC'ed.
 259     private final Vector<Class<?>> classes = new Vector<>();
 260 
 261     // The "default" domain. Set as the default ProtectionDomain on newly
 262     // created classes.
 263     private final ProtectionDomain defaultDomain =
 264         new ProtectionDomain(new CodeSource(null, (Certificate[]) null),
 265                              null, this, null);
 266 
 267     // The initiating protection domains for all classes loaded by this loader
 268     private final Set<ProtectionDomain> domains;
 269 


 345 
 346     // -- Class --
 347 
 348     /**
 349      * Loads the class with the specified <a href="#name">binary name</a>.
 350      * This method searches for classes in the same manner as the {@link
 351      * #loadClass(String, boolean)} method.  It is invoked by the Java virtual
 352      * machine to resolve class references.  Invoking this method is equivalent
 353      * to invoking {@link #loadClass(String, boolean) <tt>loadClass(name,
 354      * false)</tt>}.
 355      *
 356      * @param  name
 357      *         The <a href="#name">binary name</a> of the class
 358      *
 359      * @return  The resulting <tt>Class</tt> object
 360      *
 361      * @throws  ClassNotFoundException
 362      *          If the class was not found
 363      */
 364     public Class<?> loadClass(String name) throws ClassNotFoundException {
 365         Thread ct = Thread.currentThread();
 366         ClassLoader prevLoader = ct.initiatingClassLoader;
 367         ct.initiatingClassLoader = this;
 368         try {
 369             return loadClass(name, false);
 370         } catch (ClassNotFoundException e) {
 371             if (e.getStackTraceDepth() > 0) {
 372                 throw e;
 373             } else {
 374                 // This should not happen if class loaders follow standard
 375                 // delegation model where ClassNotFoundException(s) from parent
 376                 // loader are always swallowed and only exceptions from the
 377                 // initiating class loader are propagated, but for other
 378                 // non-standard class loaders it may happen that exceptions from
 379                 // non-initiating class-loader are propagated.
 380                 // In that case we replace such stack-less exceptions with
 381                 // normal exceptions at exit from class loading request.
 382                 throw new ClassNotFoundException(e.getMessage(), e.getException());
 383             }
 384         } finally {
 385             ct.initiatingClassLoader = prevLoader;
 386         }
 387     }
 388 
 389     /**
 390      * Loads the class with the specified <a href="#name">binary name</a>.  The
 391      * default implementation of this method searches for classes in the
 392      * following order:
 393      *
 394      * <ol>
 395      *
 396      *   <li><p> Invoke {@link #findLoadedClass(String)} to check if the class
 397      *   has already been loaded.  </p></li>
 398      *
 399      *   <li><p> Invoke the {@link #loadClass(String) <tt>loadClass</tt>} method
 400      *   on the parent class loader.  If the parent is <tt>null</tt> the class
 401      *   loader built-in to the virtual machine is used, instead.  </p></li>
 402      *
 403      *   <li><p> Invoke the {@link #findClass(String)} method to find the
 404      *   class.  </p></li>
 405      *
 406      * </ol>


 413      * #findClass(String)}, rather than this method.  </p>
 414      *
 415      * <p> Unless overridden, this method synchronizes on the result of
 416      * {@link #getClassLoadingLock <tt>getClassLoadingLock</tt>} method
 417      * during the entire class loading process.
 418      *
 419      * @param  name
 420      *         The <a href="#name">binary name</a> of the class
 421      *
 422      * @param  resolve
 423      *         If <tt>true</tt> then resolve the class
 424      *
 425      * @return  The resulting <tt>Class</tt> object
 426      *
 427      * @throws  ClassNotFoundException
 428      *          If the class could not be found
 429      */
 430     protected Class<?> loadClass(String name, boolean resolve)
 431         throws ClassNotFoundException
 432     {
 433         Object cll = getClassLoadingLock(name);
 434         synchronized (cll) {
 435             // First, check if the class has already been loaded
 436             Class<?> c;
 437             // Are we parallel capable and getClassLoadingLock() has
 438             // not been overridden to supply it's own type of locks?
 439             Lock lock = (cll instanceof Lock) ? (Lock) cll : null;
 440             if (lock != null) { // yes
 441                 c = lock.attempted
 442                     // only invoke findLoadedClass() if loading of class
 443                     // with such name has already been attempted
 444                     ? findLoadedClass(name)
 445                     // else we can be sure findLoadedClass() would
 446                     // return null and can skip invoking it
 447                     : null;
 448             } else {
 449                 // we are not parallel capable and must always invoke
 450                 c = findLoadedClass(name);
 451             }
 452             if (c == null) {
 453                 long t0 = System.nanoTime();
 454                 try {
 455                     if (parent != null) {
 456                         c = parent.loadClass(name, false);
 457                     } else {
 458                         c = findBootstrapClassOrNull(name);
 459                     }
 460                 } catch (ClassNotFoundException e) {
 461                     // ClassNotFoundException thrown if class not found
 462                     // from the non-null parent class loader
 463                 }
 464 
 465                 if (c == null) {
 466                     // If still not found, then invoke findClass in order
 467                     // to find the class.
 468                     long t1 = System.nanoTime();
 469                     c = findClass(name);
 470 
 471                     // this is the defining class loader; record the stats
 472                     sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
 473                     sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
 474                     sun.misc.PerfCounter.getFindClasses().increment();
 475                 }
 476 
 477                 // if we reach here, attempt was successful - we mark that
 478                 // in our Lock so next time findLoadedClass() will be invoked
 479                 if (lock != null) {
 480                     lock.attempted = true;
 481                 }
 482             }
 483             if (resolve) {
 484                 resolveClass(c);
 485             }
 486             return c;
 487         }
 488     }
 489 
 490     /**
 491      * Returns the lock object for class loading operations.
 492      * For backward compatibility, the default implementation of this method
 493      * behaves as follows. If this ClassLoader object is registered as
 494      * parallel capable, the method returns a dedicated object associated
 495      * with the specified class name. Otherwise, the method returns this
 496      * ClassLoader object.
 497      *
 498      * @param  className
 499      *         The name of the to-be-loaded class
 500      *
 501      * @return the lock for class loading operations
 502      *
 503      * @throws NullPointerException
 504      *         If registered as parallel capable and <tt>className</tt> is null
 505      *
 506      * @see #loadClass(String, boolean)
 507      *
 508      * @since  1.7
 509      */
 510     protected Object getClassLoadingLock(String className) {
 511         Object lock = this;
 512         if (parallelLockMap != null) {
 513             Lock newLock = new Lock();
 514             lock = parallelLockMap.putIfAbsent(className, newLock);
 515             if (lock == null) {
 516                 lock = newLock;
 517             }
 518         }
 519         return lock;
 520     }
 521 
 522     // This method is invoked by the virtual machine to load a class.
 523     private Class<?> loadClassInternal(String name)
 524         throws ClassNotFoundException
 525     {
 526         // For backward compatibility, explicitly lock on 'this' when
 527         // the current class loader is not parallel capable.
 528         if (parallelLockMap == null) {
 529             synchronized (this) {
 530                  return loadClass(name);
 531             }
 532         } else {
 533             return loadClass(name);


 561 
 562     /**
 563      * Finds the class with the specified <a href="#name">binary name</a>.
 564      * This method should be overridden by class loader implementations that
 565      * follow the delegation model for loading classes, and will be invoked by
 566      * the {@link #loadClass <tt>loadClass</tt>} method after checking the
 567      * parent class loader for the requested class.  The default implementation
 568      * throws a <tt>ClassNotFoundException</tt>.
 569      *
 570      * @param  name
 571      *         The <a href="#name">binary name</a> of the class
 572      *
 573      * @return  The resulting <tt>Class</tt> object
 574      *
 575      * @throws  ClassNotFoundException
 576      *          If the class could not be found
 577      *
 578      * @since  1.2
 579      */
 580     protected Class<?> findClass(String name) throws ClassNotFoundException {
 581         // we only need stack trace when we're the initiating class loader.
 582         boolean initiating = (Thread.currentThread().initiatingClassLoader == this);
 583         throw new ClassNotFoundException(
 584             name,
 585             null,
 586             initiating
 587         );
 588     }
 589 
 590     /**
 591      * Converts an array of bytes into an instance of class <tt>Class</tt>.
 592      * Before the <tt>Class</tt> can be used it must be resolved.  This method
 593      * is deprecated in favor of the version that takes a <a
 594      * href="#name">binary name</a> as its first argument, and is more secure.
 595      *
 596      * @param  b
 597      *         The bytes that make up the class data.  The bytes in positions
 598      *         <tt>off</tt> through <tt>off+len-1</tt> should have the format
 599      *         of a valid class file as defined by
 600      *         <cite>The Java&trade; Virtual Machine Specification</cite>.
 601      *
 602      * @param  off
 603      *         The start offset in <tt>b</tt> of the class data
 604      *
 605      * @param  len
 606      *         The length of the class data
 607      *