src/share/classes/java/lang/invoke/MethodHandles.java

Print this page




  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 {