jdk/src/share/classes/java/lang/ClassLoader.java
changeset 16906 44dfee24cb71
parent 16479 d845c18d13f2
child 18156 edb590d448c5
equal deleted inserted replaced
16905:0419f45c7761 16906:44dfee24cb71
    53 import java.util.concurrent.ConcurrentHashMap;
    53 import java.util.concurrent.ConcurrentHashMap;
    54 import sun.misc.CompoundEnumeration;
    54 import sun.misc.CompoundEnumeration;
    55 import sun.misc.Resource;
    55 import sun.misc.Resource;
    56 import sun.misc.URLClassPath;
    56 import sun.misc.URLClassPath;
    57 import sun.misc.VM;
    57 import sun.misc.VM;
       
    58 import sun.reflect.CallerSensitive;
    58 import sun.reflect.Reflection;
    59 import sun.reflect.Reflection;
    59 import sun.security.util.SecurityConstants;
    60 import sun.security.util.SecurityConstants;
    60 
    61 
    61 /**
    62 /**
    62  * A class loader is an object that is responsible for loading classes. The
    63  * A class loader is an object that is responsible for loading classes. The
  1157      */
  1158      */
  1158     protected Enumeration<URL> findResources(String name) throws IOException {
  1159     protected Enumeration<URL> findResources(String name) throws IOException {
  1159         return java.util.Collections.emptyEnumeration();
  1160         return java.util.Collections.emptyEnumeration();
  1160     }
  1161     }
  1161 
  1162 
  1162     // index 0: java.lang.ClassLoader.class
       
  1163     // index 1: the immediate caller of index 0.
       
  1164     // index 2: the immediate caller of index 1.
       
  1165     private static native Class<? extends ClassLoader> getCaller(int index);
       
  1166 
       
  1167     /**
  1163     /**
  1168      * Registers the caller as parallel capable.</p>
  1164      * Registers the caller as parallel capable.</p>
  1169      * The registration succeeds if and only if all of the following
  1165      * The registration succeeds if and only if all of the following
  1170      * conditions are met: <br>
  1166      * conditions are met: <br>
  1171      * 1. no instance of the caller has been created</p>
  1167      * 1. no instance of the caller has been created</p>
  1177      * @return  true if the caller is successfully registered as
  1173      * @return  true if the caller is successfully registered as
  1178      *          parallel capable and false if otherwise.
  1174      *          parallel capable and false if otherwise.
  1179      *
  1175      *
  1180      * @since   1.7
  1176      * @since   1.7
  1181      */
  1177      */
       
  1178     @CallerSensitive
  1182     protected static boolean registerAsParallelCapable() {
  1179     protected static boolean registerAsParallelCapable() {
  1183         return ParallelLoaders.register(getCaller(1));
  1180         Class<? extends ClassLoader> callerClass =
       
  1181             Reflection.getCallerClass().asSubclass(ClassLoader.class);
       
  1182         return ParallelLoaders.register(callerClass);
  1184     }
  1183     }
  1185 
  1184 
  1186     /**
  1185     /**
  1187      * Find a resource of the specified name from the search path used to load
  1186      * Find a resource of the specified name from the search path used to load
  1188      * classes.  This method locates the resource through the system class
  1187      * classes.  This method locates the resource through the system class
  1338      *          method doesn't allow access to this class loader's parent class
  1337      *          method doesn't allow access to this class loader's parent class
  1339      *          loader.
  1338      *          loader.
  1340      *
  1339      *
  1341      * @since  1.2
  1340      * @since  1.2
  1342      */
  1341      */
       
  1342     @CallerSensitive
  1343     public final ClassLoader getParent() {
  1343     public final ClassLoader getParent() {
  1344         if (parent == null)
  1344         if (parent == null)
  1345             return null;
  1345             return null;
  1346         SecurityManager sm = System.getSecurityManager();
  1346         SecurityManager sm = System.getSecurityManager();
  1347         if (sm != null) {
  1347         if (sm != null) {
  1348             ClassLoader ccl = getCallerClassLoader();
  1348             checkClassLoaderPermission(this, Reflection.getCallerClass());
  1349             if (needsClassLoaderPermissionCheck(ccl, this)) {
       
  1350                 sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
       
  1351             }
       
  1352         }
  1349         }
  1353         return parent;
  1350         return parent;
  1354     }
  1351     }
  1355 
  1352 
  1356     /**
  1353     /**
  1406      *          underlying cause of the error can be retrieved via the
  1403      *          underlying cause of the error can be retrieved via the
  1407      *          {@link Throwable#getCause()} method.
  1404      *          {@link Throwable#getCause()} method.
  1408      *
  1405      *
  1409      * @revised  1.4
  1406      * @revised  1.4
  1410      */
  1407      */
       
  1408     @CallerSensitive
  1411     public static ClassLoader getSystemClassLoader() {
  1409     public static ClassLoader getSystemClassLoader() {
  1412         initSystemClassLoader();
  1410         initSystemClassLoader();
  1413         if (scl == null) {
  1411         if (scl == null) {
  1414             return null;
  1412             return null;
  1415         }
  1413         }
  1416         SecurityManager sm = System.getSecurityManager();
  1414         SecurityManager sm = System.getSecurityManager();
  1417         if (sm != null) {
  1415         if (sm != null) {
  1418             ClassLoader ccl = getCallerClassLoader();
  1416             checkClassLoaderPermission(scl, Reflection.getCallerClass());
  1419             if (needsClassLoaderPermissionCheck(ccl, scl)) {
       
  1420                 sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
       
  1421             }
       
  1422         }
  1417         }
  1423         return scl;
  1418         return scl;
  1424     }
  1419     }
  1425 
  1420 
  1426     private static synchronized void initSystemClassLoader() {
  1421     private static synchronized void initSystemClassLoader() {
  1469     // Tests if class loader access requires "getClassLoader" permission
  1464     // Tests if class loader access requires "getClassLoader" permission
  1470     // check.  A class loader 'from' can access class loader 'to' if
  1465     // check.  A class loader 'from' can access class loader 'to' if
  1471     // class loader 'from' is same as class loader 'to' or an ancestor
  1466     // class loader 'from' is same as class loader 'to' or an ancestor
  1472     // of 'to'.  The class loader in a system domain can access
  1467     // of 'to'.  The class loader in a system domain can access
  1473     // any class loader.
  1468     // any class loader.
  1474     static boolean needsClassLoaderPermissionCheck(ClassLoader from,
  1469     private static boolean needsClassLoaderPermissionCheck(ClassLoader from,
  1475                                                    ClassLoader to)
  1470                                                            ClassLoader to)
  1476     {
  1471     {
  1477         if (from == to)
  1472         if (from == to)
  1478             return false;
  1473             return false;
  1479 
  1474 
  1480         if (from == null)
  1475         if (from == null)
  1481             return false;
  1476             return false;
  1482 
  1477 
  1483         return !to.isAncestor(from);
  1478         return !to.isAncestor(from);
  1484     }
  1479     }
  1485 
  1480 
  1486     // Returns the invoker's class loader, or null if none.
  1481     // Returns the class's class loader, or null if none.
  1487     // NOTE: This must always be invoked when there is exactly one intervening
  1482     static ClassLoader getClassLoader(Class<?> caller) {
  1488     // frame from the core libraries on the stack between this method's
       
  1489     // invocation and the desired invoker.
       
  1490     static ClassLoader getCallerClassLoader() {
       
  1491         // NOTE use of more generic Reflection.getCallerClass()
       
  1492         Class<?> caller = Reflection.getCallerClass(3);
       
  1493         // This can be null if the VM is requesting it
  1483         // This can be null if the VM is requesting it
  1494         if (caller == null) {
  1484         if (caller == null) {
  1495             return null;
  1485             return null;
  1496         }
  1486         }
  1497         // Circumvent security check since this is package-private
  1487         // Circumvent security check since this is package-private
  1498         return caller.getClassLoader0();
  1488         return caller.getClassLoader0();
       
  1489     }
       
  1490 
       
  1491     static void checkClassLoaderPermission(ClassLoader cl, Class<?> caller) {
       
  1492         SecurityManager sm = System.getSecurityManager();
       
  1493         if (sm != null) {
       
  1494             // caller can be null if the VM is requesting it
       
  1495             ClassLoader ccl = getClassLoader(caller);
       
  1496             if (needsClassLoaderPermissionCheck(ccl, cl)) {
       
  1497                 sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
       
  1498             }
       
  1499         }
  1499     }
  1500     }
  1500 
  1501 
  1501     // The class loader for the system
  1502     // The class loader for the system
  1502     // @GuardedBy("ClassLoader.class")
  1503     // @GuardedBy("ClassLoader.class")
  1503     private static ClassLoader scl;
  1504     private static ClassLoader scl;