24 */
25
26 package java.lang.invoke;
27
28 import java.lang.reflect.*;
29 import java.security.AccessController;
30 import java.security.PrivilegedAction;
31 import java.util.List;
32 import java.util.ArrayList;
33 import java.util.Arrays;
34
35 import sun.invoke.util.ValueConversions;
36 import sun.invoke.util.VerifyAccess;
37 import sun.invoke.util.Wrapper;
38 import sun.reflect.CallerSensitive;
39 import sun.reflect.Reflection;
40 import sun.reflect.misc.ReflectUtil;
41 import sun.security.util.SecurityConstants;
42 import static java.lang.invoke.MethodHandleStatics.*;
43 import static java.lang.invoke.MethodHandleNatives.Constants.*;
44
45 /**
46 * This class consists exclusively of static methods that operate on or return
47 * method handles. They fall into several categories:
48 * <ul>
49 * <li>Lookup methods which help create method handles for methods and fields.
50 * <li>Combinator methods, which combine or transform pre-existing method handles into new ones.
51 * <li>Other factory methods to create method handles that emulate other common JVM operations or control flow patterns.
52 * <li>Wrapper methods which can convert between method handles and interface types.
53 * </ul>
54 * <p>
55 * @author John Rose, JSR 292 EG
56 */
57 public class MethodHandles {
58
59 private MethodHandles() { } // do not instantiate
60
61 private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
62 static { MethodHandleImpl.initStatics(); }
63 // See IMPL_LOOKUP below.
284 * Core Reflection API, and are impossible to bytecode instructions
285 * such as {@code invokestatic} or {@code getfield}.
286 * There is a {@linkplain java.lang.SecurityManager security manager API}
287 * to allow applications to check such cross-loader references.
288 * These checks apply to both the {@code MethodHandles.Lookup} API
289 * and the Core Reflection API
290 * (as found on {@link java.lang.Class Class}).
291 * <p>
292 * Access checks only apply to named and reflected methods,
293 * constructors, and fields.
294 * Other method handle creation methods, such as
295 * {@link MethodHandle#asType MethodHandle.asType},
296 * do not require any access checks, and are done
297 * with static methods of {@link MethodHandles},
298 * independently of any {@code Lookup} object.
299 *
300 * <h3>Security manager interactions</h3>
301 * <a name="secmgr"></a>
302 * If a security manager is present, member lookups are subject to
303 * additional checks.
304 * From one to four calls are made to the security manager.
305 * Any of these calls can refuse access by throwing a
306 * {@link java.lang.SecurityException SecurityException}.
307 * Define {@code smgr} as the security manager,
308 * {@code refc} as the containing class in which the member
309 * is being sought, and {@code defc} as the class in which the
310 * member is actually defined.
311 * The calls are made according to the following rules:
312 * <ul>
313 * <li>In all cases, {@link SecurityManager#checkMemberAccess
314 * smgr.checkMemberAccess(refc, Member.PUBLIC)} is called.
315 * <li>If the class loader of the lookup class is not
316 * the same as or an ancestor of the class loader of {@code refc},
317 * then {@link SecurityManager#checkPackageAccess
318 * smgr.checkPackageAccess(refcPkg)} is called,
319 * where {@code refcPkg} is the package of {@code refc}.
320 * <li>If the retrieved member is not public,
321 * {@link SecurityManager#checkMemberAccess
322 * smgr.checkMemberAccess(defc, Member.DECLARED)} is called.
323 * (Note that {@code defc} might be the same as {@code refc}.)
324 * The default implementation of this security manager method
325 * inspects the stack to determine the original caller of
326 * the reflective request (such as {@code findStatic}),
327 * and performs additional permission checks if the
328 * class loader of {@code defc} differs from the class
329 * loader of the class from which the reflective request came.
330 * <li>If the retrieved member is not public,
331 * and if {@code defc} and {@code refc} are in different class loaders,
332 * and if the class loader of the lookup class is not
333 * the same as or an ancestor of the class loader of {@code defc},
334 * then {@link SecurityManager#checkPackageAccess
335 * smgr.checkPackageAccess(defcPkg)} is called,
336 * where {@code defcPkg} is the package of {@code defc}.
337 * </ul>
338 */
339 // FIXME in MR1: clarify that the bytecode behavior of a caller-ID method (like Class.forName) is relative to the lookupClass used to create the method handle, not the dynamic caller of the method handle
340 public static final
341 class Lookup {
342 /** The class on behalf of whom the lookup is being performed. */
343 private final Class<?> lookupClass;
344
345 /** The allowed sorts of members which may be looked up (PUBLIC, etc.). */
346 private final int allowedModes;
347
348 /** A single-bit mask representing {@code public} access,
349 * which may contribute to the result of {@link #lookupModes lookupModes}.
350 * The value, {@code 0x01}, happens to be the same as the value of the
351 * {@code public} {@linkplain java.lang.reflect.Modifier#PUBLIC modifier bit}.
352 */
353 public static final int PUBLIC = Modifier.PUBLIC;
1031 * Otherwise, if m is caller-sensitive, throw IllegalAccessException.
1032 */
1033 Class<?> findBoundCallerClass(MemberName m) throws IllegalAccessException {
1034 Class<?> callerClass = null;
1035 if (MethodHandleNatives.isCallerSensitive(m)) {
1036 // Only full-power lookup is allowed to resolve caller-sensitive methods
1037 if (isFullPowerLookup()) {
1038 callerClass = lookupClass;
1039 } else {
1040 throw new IllegalAccessException("Attempt to lookup caller-sensitive method using restricted lookup object");
1041 }
1042 }
1043 return callerClass;
1044 }
1045
1046 private boolean isFullPowerLookup() {
1047 return (allowedModes & PRIVATE) != 0;
1048 }
1049
1050 /**
1051 * Determine whether a security manager has an overridden
1052 * SecurityManager.checkMemberAccess method.
1053 */
1054 private boolean isCheckMemberAccessOverridden(SecurityManager sm) {
1055 final Class<? extends SecurityManager> cls = sm.getClass();
1056 if (cls == SecurityManager.class) return false;
1057
1058 try {
1059 return cls.getMethod("checkMemberAccess", Class.class, int.class).
1060 getDeclaringClass() != SecurityManager.class;
1061 } catch (NoSuchMethodException e) {
1062 throw new InternalError("should not reach here");
1063 }
1064 }
1065
1066 /**
1067 * Perform necessary <a href="MethodHandles.Lookup.html#secmgr">access checks</a>.
1068 * Determines a trustable caller class to compare with refc, the symbolic reference class.
1069 * If this lookup object has private access, then the caller class is the lookupClass.
1070 */
1071 void checkSecurityManager(Class<?> refc, MemberName m) {
1072 SecurityManager smgr = System.getSecurityManager();
1073 if (smgr == null) return;
1074 if (allowedModes == TRUSTED) return;
1075
1076 final boolean overridden = isCheckMemberAccessOverridden(smgr);
1077 // Step 1:
1078 {
1079 // Default policy is to allow Member.PUBLIC; no need to check
1080 // permission if SecurityManager is the default implementation
1081 final int which = Member.PUBLIC;
1082 final Class<?> clazz = refc;
1083 if (overridden) {
1084 // Don't refactor; otherwise break the stack depth for
1085 // checkMemberAccess of subclasses of SecurityManager as specified.
1086 smgr.checkMemberAccess(clazz, which);
1087 }
1088 }
1089
1090 // Step 2:
1091 if (!isFullPowerLookup() ||
1092 !VerifyAccess.classLoaderIsAncestor(lookupClass, refc)) {
1093 ReflectUtil.checkPackageAccess(refc);
1094 }
1095
1096 // Step 3:
1097 if (m.isPublic()) return;
1098 Class<?> defc = m.getDeclaringClass();
1099 {
1100 // Inline SecurityManager.checkMemberAccess
1101 final int which = Member.DECLARED;
1102 final Class<?> clazz = defc;
1103 if (!overridden) {
1104 if (!isFullPowerLookup()) {
1105 smgr.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
1106 }
1107 } else {
1108 // Don't refactor; otherwise break the stack depth for
1109 // checkMemberAccess of subclasses of SecurityManager as specified.
1110 smgr.checkMemberAccess(clazz, which);
1111 }
1112 }
1113
1114 // Step 4:
1115 if (defc != refc) {
1116 ReflectUtil.checkPackageAccess(defc);
1117 }
1118 }
1119
1120 void checkMethod(byte refKind, Class<?> refc, MemberName m) throws IllegalAccessException {
1121 boolean wantStatic = (refKind == REF_invokeStatic);
1122 String message;
1123 if (m.isConstructor())
1124 message = "expected a method, not a constructor";
1125 else if (!m.isMethod())
1126 message = "expected a method";
1127 else if (wantStatic != m.isStatic())
1128 message = wantStatic ? "expected a static method" : "expected a non-static method";
1129 else
1130 { checkAccess(refKind, refc, m); return; }
1131 throw m.makeAccessException(message, this);
1132 }
1133
1134 void checkField(byte refKind, Class<?> refc, MemberName m) throws IllegalAccessException {
|
24 */
25
26 package java.lang.invoke;
27
28 import java.lang.reflect.*;
29 import java.security.AccessController;
30 import java.security.PrivilegedAction;
31 import java.util.List;
32 import java.util.ArrayList;
33 import java.util.Arrays;
34
35 import sun.invoke.util.ValueConversions;
36 import sun.invoke.util.VerifyAccess;
37 import sun.invoke.util.Wrapper;
38 import sun.reflect.CallerSensitive;
39 import sun.reflect.Reflection;
40 import sun.reflect.misc.ReflectUtil;
41 import sun.security.util.SecurityConstants;
42 import static java.lang.invoke.MethodHandleStatics.*;
43 import static java.lang.invoke.MethodHandleNatives.Constants.*;
44 import sun.security.util.SecurityConstants;
45
46 /**
47 * This class consists exclusively of static methods that operate on or return
48 * method handles. They fall into several categories:
49 * <ul>
50 * <li>Lookup methods which help create method handles for methods and fields.
51 * <li>Combinator methods, which combine or transform pre-existing method handles into new ones.
52 * <li>Other factory methods to create method handles that emulate other common JVM operations or control flow patterns.
53 * <li>Wrapper methods which can convert between method handles and interface types.
54 * </ul>
55 * <p>
56 * @author John Rose, JSR 292 EG
57 */
58 public class MethodHandles {
59
60 private MethodHandles() { } // do not instantiate
61
62 private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
63 static { MethodHandleImpl.initStatics(); }
64 // See IMPL_LOOKUP below.
285 * Core Reflection API, and are impossible to bytecode instructions
286 * such as {@code invokestatic} or {@code getfield}.
287 * There is a {@linkplain java.lang.SecurityManager security manager API}
288 * to allow applications to check such cross-loader references.
289 * These checks apply to both the {@code MethodHandles.Lookup} API
290 * and the Core Reflection API
291 * (as found on {@link java.lang.Class Class}).
292 * <p>
293 * Access checks only apply to named and reflected methods,
294 * constructors, and fields.
295 * Other method handle creation methods, such as
296 * {@link MethodHandle#asType MethodHandle.asType},
297 * do not require any access checks, and are done
298 * with static methods of {@link MethodHandles},
299 * independently of any {@code Lookup} object.
300 *
301 * <h3>Security manager interactions</h3>
302 * <a name="secmgr"></a>
303 * If a security manager is present, member lookups are subject to
304 * additional checks.
305 * From one to three calls are made to the security manager.
306 * Any of these calls can refuse access by throwing a
307 * {@link java.lang.SecurityException SecurityException}.
308 * Define {@code smgr} as the security manager,
309 * {@code lookc} as the lookup class of the current lookup object,
310 * {@code refc} as the containing class in which the member
311 * is being sought, and {@code defc} as the class in which the
312 * member is actually defined.
313 * The calls are made according to the following rules:
314 * <ul>
315 * <li>If the class loader of {@code lookc} is not
316 * the same as or an ancestor of the class loader of {@code refc},
317 * then {@link SecurityManager#checkPackageAccess
318 * smgr.checkPackageAccess(refcPkg)} is called,
319 * where {@code refcPkg} is the package of {@code refc}.
320 * <li>If the retrieved member is not public and
321 * {@link SecurityManager#checkPermission smgr.checkPermission}
322 * with {@code RuntimePermission("accessDeclaredMembers")} is called.
323 * <li>If the retrieved member is not public,
324 * and if {@code defc} and {@code refc} are different,
325 * then {@link SecurityManager#checkPackageAccess
326 * smgr.checkPackageAccess(defcPkg)} is called,
327 * where {@code defcPkg} is the package of {@code defc}.
328 * </ul>
329 */
330 // FIXME in MR1: clarify that the bytecode behavior of a caller-ID method (like Class.forName) is relative to the lookupClass used to create the method handle, not the dynamic caller of the method handle
331 public static final
332 class Lookup {
333 /** The class on behalf of whom the lookup is being performed. */
334 private final Class<?> lookupClass;
335
336 /** The allowed sorts of members which may be looked up (PUBLIC, etc.). */
337 private final int allowedModes;
338
339 /** A single-bit mask representing {@code public} access,
340 * which may contribute to the result of {@link #lookupModes lookupModes}.
341 * The value, {@code 0x01}, happens to be the same as the value of the
342 * {@code public} {@linkplain java.lang.reflect.Modifier#PUBLIC modifier bit}.
343 */
344 public static final int PUBLIC = Modifier.PUBLIC;
1022 * Otherwise, if m is caller-sensitive, throw IllegalAccessException.
1023 */
1024 Class<?> findBoundCallerClass(MemberName m) throws IllegalAccessException {
1025 Class<?> callerClass = null;
1026 if (MethodHandleNatives.isCallerSensitive(m)) {
1027 // Only full-power lookup is allowed to resolve caller-sensitive methods
1028 if (isFullPowerLookup()) {
1029 callerClass = lookupClass;
1030 } else {
1031 throw new IllegalAccessException("Attempt to lookup caller-sensitive method using restricted lookup object");
1032 }
1033 }
1034 return callerClass;
1035 }
1036
1037 private boolean isFullPowerLookup() {
1038 return (allowedModes & PRIVATE) != 0;
1039 }
1040
1041 /**
1042 * Perform necessary <a href="MethodHandles.Lookup.html#secmgr">access checks</a>.
1043 * Determines a trustable caller class to compare with refc, the symbolic reference class.
1044 * If this lookup object has private access, then the caller class is the lookupClass.
1045 */
1046 void checkSecurityManager(Class<?> refc, MemberName m) {
1047 SecurityManager smgr = System.getSecurityManager();
1048 if (smgr == null) return;
1049 if (allowedModes == TRUSTED) return;
1050
1051 // Step 1:
1052 if (!isFullPowerLookup() ||
1053 !VerifyAccess.classLoaderIsAncestor(lookupClass, refc)) {
1054 ReflectUtil.checkPackageAccess(refc);
1055 }
1056
1057 // Step 2:
1058 if (m.isPublic()) return;
1059 Class<?> defc = m.getDeclaringClass();
1060 {
1061 if (!isFullPowerLookup()) {
1062 smgr.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
1063 }
1064 }
1065
1066 // Step 3:
1067 if (defc != refc) {
1068 ReflectUtil.checkPackageAccess(defc);
1069 }
1070 }
1071
1072 void checkMethod(byte refKind, Class<?> refc, MemberName m) throws IllegalAccessException {
1073 boolean wantStatic = (refKind == REF_invokeStatic);
1074 String message;
1075 if (m.isConstructor())
1076 message = "expected a method, not a constructor";
1077 else if (!m.isMethod())
1078 message = "expected a method";
1079 else if (wantStatic != m.isStatic())
1080 message = wantStatic ? "expected a static method" : "expected a non-static method";
1081 else
1082 { checkAccess(refKind, refc, m); return; }
1083 throw m.makeAccessException(message, this);
1084 }
1085
1086 void checkField(byte refKind, Class<?> refc, MemberName m) throws IllegalAccessException {
|