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

Print this page




  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 
  26 package java.lang.invoke;
  27 
  28 import java.lang.reflect.*;
  29 import sun.invoke.util.ValueConversions;
  30 import sun.invoke.util.VerifyAccess;
  31 import sun.invoke.util.Wrapper;
  32 import java.util.List;
  33 import java.util.ArrayList;
  34 import java.util.Arrays;
  35 import sun.reflect.Reflection;
  36 import static java.lang.invoke.MethodHandleStatics.*;
  37 import static java.lang.invoke.MethodHandleNatives.Constants.*;

  38 
  39 /**
  40  * This class consists exclusively of static methods that operate on or return
  41  * method handles. They fall into several categories:
  42  * <ul>
  43  * <li>Lookup methods which help create method handles for methods and fields.
  44  * <li>Combinator methods, which combine or transform pre-existing method handles into new ones.
  45  * <li>Other factory methods to create method handles that emulate other common JVM operations or control flow patterns.
  46  * <li>Wrapper methods which can convert between method handles and interface types.
  47  * </ul>
  48  * <p>
  49  * @author John Rose, JSR 292 EG
  50  */
  51 public class MethodHandles {
  52 
  53     private MethodHandles() { }  // do not instantiate
  54 
  55     private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
  56     static { MethodHandleImpl.initStatics(); }
  57     // See IMPL_LOOKUP below.


 286      * constructors, and fields.
 287      * Other method handle creation methods, such as
 288      * {@link MethodHandle#asType MethodHandle.asType},
 289      * do not require any access checks, and are done
 290      * with static methods of {@link MethodHandles},
 291      * independently of any {@code Lookup} object.
 292      *
 293      * <h3>Security manager interactions</h3>
 294      * <a name="secmgr"></a>
 295      * If a security manager is present, member lookups are subject to
 296      * additional checks.
 297      * From one to four calls are made to the security manager.
 298      * Any of these calls can refuse access by throwing a
 299      * {@link java.lang.SecurityException SecurityException}.
 300      * Define {@code smgr} as the security manager,
 301      * {@code refc} as the containing class in which the member
 302      * is being sought, and {@code defc} as the class in which the
 303      * member is actually defined.
 304      * The calls are made according to the following rules:
 305      * <ul>
 306      * <li>In all cases, {@link SecurityManager#checkMemberAccess
 307      *     smgr.checkMemberAccess(refc, Member.PUBLIC)} is called.
 308      * <li>If the class loader of the lookup class is not
 309      *     the same as or an ancestor of the class loader of {@code refc},
 310      *     then {@link SecurityManager#checkPackageAccess
 311      *     smgr.checkPackageAccess(refcPkg)} is called,
 312      *     where {@code refcPkg} is the package of {@code refc}.
 313      * <li>If the retrieved member is not public,
 314      *     {@link SecurityManager#checkMemberAccess
 315      *     smgr.checkMemberAccess(defc, Member.DECLARED)} is called.
 316      *     (Note that {@code defc} might be the same as {@code refc}.)
 317      *     The default implementation of this security manager method
 318      *     inspects the stack to determine the original caller of
 319      *     the reflective request (such as {@code findStatic}),
 320      *     and performs additional permission checks if the
 321      *     class loader of {@code defc} differs from the class
 322      *     loader of the class from which the reflective request came.
 323      * <li>If the retrieved member is not public,
 324      *     and if {@code defc} and {@code refc} are in different class loaders,
 325      *     and if the class loader of the lookup class is not
 326      *     the same as or an ancestor of the class loader of {@code defc},
 327      *     then {@link SecurityManager#checkPackageAccess
 328      *     smgr.checkPackageAccess(defcPkg)} is called,
 329      *     where {@code defcPkg} is the package of {@code defc}.
 330      * </ul>
 331      */
 332     // 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
 333     public static final
 334     class Lookup {
 335         /** The class on behalf of whom the lookup is being performed. */
 336         private final Class<?> lookupClass;
 337 
 338         /** The allowed sorts of members which may be looked up (PUBLIC, etc.). */
 339         private final int allowedModes;
 340 
 341         /** A single-bit mask representing {@code public} access,
 342          *  which may contribute to the result of {@link #lookupModes lookupModes}.


1059                 // Note that this is the same expression as in Step 2 below in checkSecurityManager.
1060                 callerClass = ((allowedModes & PRIVATE) != 0
1061                                ? lookupClass  // for strong access modes, no extra check
1062                                // next line does stack walk magic; do not refactor:
1063                                : getCallerClassAtEntryPoint(true));
1064             }
1065             return callerClass;
1066         }
1067         /**
1068          * Perform necessary <a href="MethodHandles.Lookup.html#secmgr">access checks</a>.
1069          * Determines a trustable caller class to compare with refc, the symbolic reference class.
1070          * If this lookup object has private access, then the caller class is the lookupClass.
1071          * Otherwise, it is the caller of the currently executing public API method (e.g., findVirtual).
1072          * This function performs stack walk magic: do not refactor it.
1073          */
1074         void checkSecurityManager(Class<?> refc, MemberName m) {
1075             SecurityManager smgr = System.getSecurityManager();
1076             if (smgr == null)  return;
1077             if (allowedModes == TRUSTED)  return;
1078             // Step 1:
1079             smgr.checkMemberAccess(refc, Member.PUBLIC);
1080             // Step 2:
1081             Class<?> callerClass = ((allowedModes & PRIVATE) != 0
1082                                     ? lookupClass  // for strong access modes, no extra check
1083                                     // next line does stack walk magic; do not refactor:
1084                                     : getCallerClassAtEntryPoint(true));
1085             if (!VerifyAccess.classLoaderIsAncestor(lookupClass, refc) ||
1086                 (callerClass != lookupClass &&
1087                  !VerifyAccess.classLoaderIsAncestor(callerClass, refc)))
1088                 smgr.checkPackageAccess(VerifyAccess.getPackageName(refc));
1089             // Step 3:
1090             if (m.isPublic()) return;
1091             Class<?> defc = m.getDeclaringClass();
1092             smgr.checkMemberAccess(defc, Member.DECLARED);  // STACK WALK HERE
1093             // Step 4:




1094             if (defc != refc)
1095                 smgr.checkPackageAccess(VerifyAccess.getPackageName(defc));
1096 
1097             // Comment from SM.checkMemberAccess, where which=DECLARED:
1098             /*
1099              * stack depth of 4 should be the caller of one of the
1100              * methods in java.lang.Class that invoke checkMember
1101              * access. The stack should look like:
1102              *
1103              * someCaller                        [3]
1104              * java.lang.Class.someReflectionAPI [2]
1105              * java.lang.Class.checkMemberAccess [1]
1106              * SecurityManager.checkMemberAccess [0]
1107              *
1108              */
1109             // For us it is this stack:
1110             // someCaller                        [3]
1111             // Lookup.findSomeMember             [2]
1112             // Lookup.checkSecurityManager       [1]
1113             // SecurityManager.checkMemberAccess [0]
1114         }
1115 
1116         void checkMethod(byte refKind, Class<?> refc, MemberName m) throws IllegalAccessException {
1117             boolean wantStatic = (refKind == REF_invokeStatic);
1118             String message;
1119             if (m.isConstructor())
1120                 message = "expected a method, not a constructor";
1121             else if (!m.isMethod())
1122                 message = "expected a method";
1123             else if (wantStatic != m.isStatic())
1124                 message = wantStatic ? "expected a static method" : "expected a non-static method";
1125             else
1126                 { checkAccess(refKind, refc, m); return; }
1127             throw m.makeAccessException(message, this);
1128         }
1129 
1130         void checkField(byte refKind, Class<?> refc, MemberName m) throws IllegalAccessException {
1131             boolean wantStatic = !MethodHandleNatives.refKindHasReceiver(refKind);
1132             String message;
1133             if (wantStatic != m.isStatic())




  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 
  26 package java.lang.invoke;
  27 
  28 import java.lang.reflect.*;
  29 import sun.invoke.util.ValueConversions;
  30 import sun.invoke.util.VerifyAccess;
  31 import sun.invoke.util.Wrapper;
  32 import java.util.List;
  33 import java.util.ArrayList;
  34 import java.util.Arrays;
  35 import sun.reflect.Reflection;
  36 import static java.lang.invoke.MethodHandleStatics.*;
  37 import static java.lang.invoke.MethodHandleNatives.Constants.*;
  38 import sun.security.util.SecurityConstants;
  39 
  40 /**
  41  * This class consists exclusively of static methods that operate on or return
  42  * method handles. They fall into several categories:
  43  * <ul>
  44  * <li>Lookup methods which help create method handles for methods and fields.
  45  * <li>Combinator methods, which combine or transform pre-existing method handles into new ones.
  46  * <li>Other factory methods to create method handles that emulate other common JVM operations or control flow patterns.
  47  * <li>Wrapper methods which can convert between method handles and interface types.
  48  * </ul>
  49  * <p>
  50  * @author John Rose, JSR 292 EG
  51  */
  52 public class MethodHandles {
  53 
  54     private MethodHandles() { }  // do not instantiate
  55 
  56     private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
  57     static { MethodHandleImpl.initStatics(); }
  58     // See IMPL_LOOKUP below.


 287      * constructors, and fields.
 288      * Other method handle creation methods, such as
 289      * {@link MethodHandle#asType MethodHandle.asType},
 290      * do not require any access checks, and are done
 291      * with static methods of {@link MethodHandles},
 292      * independently of any {@code Lookup} object.
 293      *
 294      * <h3>Security manager interactions</h3>
 295      * <a name="secmgr"></a>
 296      * If a security manager is present, member lookups are subject to
 297      * additional checks.
 298      * From one to four calls are made to the security manager.
 299      * Any of these calls can refuse access by throwing a
 300      * {@link java.lang.SecurityException SecurityException}.
 301      * Define {@code smgr} as the security manager,
 302      * {@code refc} as the containing class in which the member
 303      * is being sought, and {@code defc} as the class in which the
 304      * member is actually defined.
 305      * The calls are made according to the following rules:
 306      * <ul>


 307      * <li>If the class loader of the lookup class is not
 308      *     the same as or an ancestor of the class loader of {@code refc},
 309      *     then {@link SecurityManager#checkPackageAccess
 310      *     smgr.checkPackageAccess(refcPkg)} is called,
 311      *     where {@code refcPkg} is the package of {@code refc}.
 312      * <li>If the retrieved member is not public and
 313      *     the class loader of {@code defc} differs from the class
 314      *     loader of the class from which the reflective request came
 315      *     (such as {@code findStatic}),
 316      *     {@link SecurityManager#checkPermission smgr.checkPermission}
 317      *     with {@code RuntimePermission("accessDeclaredMembers")} is called.




 318      * <li>If the retrieved member is not public,
 319      *     and if {@code defc} and {@code refc} are in different class loaders,
 320      *     and if the class loader of the lookup class is not
 321      *     the same as or an ancestor of the class loader of {@code defc},
 322      *     then {@link SecurityManager#checkPackageAccess
 323      *     smgr.checkPackageAccess(defcPkg)} is called,
 324      *     where {@code defcPkg} is the package of {@code defc}.
 325      * </ul>
 326      */
 327     // 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
 328     public static final
 329     class Lookup {
 330         /** The class on behalf of whom the lookup is being performed. */
 331         private final Class<?> lookupClass;
 332 
 333         /** The allowed sorts of members which may be looked up (PUBLIC, etc.). */
 334         private final int allowedModes;
 335 
 336         /** A single-bit mask representing {@code public} access,
 337          *  which may contribute to the result of {@link #lookupModes lookupModes}.


1054                 // Note that this is the same expression as in Step 2 below in checkSecurityManager.
1055                 callerClass = ((allowedModes & PRIVATE) != 0
1056                                ? lookupClass  // for strong access modes, no extra check
1057                                // next line does stack walk magic; do not refactor:
1058                                : getCallerClassAtEntryPoint(true));
1059             }
1060             return callerClass;
1061         }
1062         /**
1063          * Perform necessary <a href="MethodHandles.Lookup.html#secmgr">access checks</a>.
1064          * Determines a trustable caller class to compare with refc, the symbolic reference class.
1065          * If this lookup object has private access, then the caller class is the lookupClass.
1066          * Otherwise, it is the caller of the currently executing public API method (e.g., findVirtual).
1067          * This function performs stack walk magic: do not refactor it.
1068          */
1069         void checkSecurityManager(Class<?> refc, MemberName m) {
1070             SecurityManager smgr = System.getSecurityManager();
1071             if (smgr == null)  return;
1072             if (allowedModes == TRUSTED)  return;
1073             // Step 1:


1074             Class<?> callerClass = ((allowedModes & PRIVATE) != 0
1075                                     ? lookupClass  // for strong access modes, no extra check
1076                                     // next line does stack walk magic; do not refactor:
1077                                     : getCallerClassAtEntryPoint(true));
1078             if (!VerifyAccess.classLoaderIsAncestor(lookupClass, refc) ||
1079                 (callerClass != lookupClass &&
1080                  !VerifyAccess.classLoaderIsAncestor(callerClass, refc)))
1081                 smgr.checkPackageAccess(VerifyAccess.getPackageName(refc));
1082             // Step 2:
1083             if (m.isPublic()) return;
1084             Class<?> defc = m.getDeclaringClass();
1085             ClassLoader ccl = callerClass != null ? callerClass.getClassLoader() : null;
1086             // access Member.DECLARED
1087             if (ccl != defc.getClassLoader()) {
1088                 smgr.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
1089             }
1090             // Step 3:
1091             if (defc != refc)
1092                 smgr.checkPackageAccess(VerifyAccess.getPackageName(defc));


















1093         }
1094 
1095         void checkMethod(byte refKind, Class<?> refc, MemberName m) throws IllegalAccessException {
1096             boolean wantStatic = (refKind == REF_invokeStatic);
1097             String message;
1098             if (m.isConstructor())
1099                 message = "expected a method, not a constructor";
1100             else if (!m.isMethod())
1101                 message = "expected a method";
1102             else if (wantStatic != m.isStatic())
1103                 message = wantStatic ? "expected a static method" : "expected a non-static method";
1104             else
1105                 { checkAccess(refKind, refc, m); return; }
1106             throw m.makeAccessException(message, this);
1107         }
1108 
1109         void checkField(byte refKind, Class<?> refc, MemberName m) throws IllegalAccessException {
1110             boolean wantStatic = !MethodHandleNatives.refKindHasReceiver(refKind);
1111             String message;
1112             if (wantStatic != m.isStatic())