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; |