jdk/src/share/classes/java/dyn/MethodHandles.java
changeset 8349 e1ba54c43609
parent 8347 e5daa5772ffd
child 8821 2836ee97ee27
equal deleted inserted replaced
8348:3b2ac15dfc16 8349:e1ba54c43609
   196      * <li>Likewise, if {@code T} or {@code MT}
   196      * <li>Likewise, if {@code T} or {@code MT}
   197      * is not symbolically accessible from the lookup class's loader,
   197      * is not symbolically accessible from the lookup class's loader,
   198      * the lookup can still succeed.
   198      * the lookup can still succeed.
   199      * For example, lookups for {@code MethodHandle.invokeExact} and
   199      * For example, lookups for {@code MethodHandle.invokeExact} and
   200      * {@code MethodHandle.invokeGeneric} will always succeed, regardless of requested type.
   200      * {@code MethodHandle.invokeGeneric} will always succeed, regardless of requested type.
       
   201      * <li>If there is a security manager installed, it can forbid the lookup
       
   202      * on various grounds (<a href="#secmgr">see below</a>).
       
   203      * By contrast, the {@code ldc} instruction is not subject to
       
   204      * security manager checks.
   201      * </ul>
   205      * </ul>
   202      *
   206      *
   203      * <h3><a name="access"></a>Access checking</h3>
   207      * <h3><a name="access"></a>Access checking</h3>
   204      * Access checks are applied in the factory methods of {@code Lookup},
   208      * Access checks are applied in the factory methods of {@code Lookup},
   205      * when a method handle is created.
   209      * when a method handle is created.
   253      * {@code C.E} would be unable to those private members.
   257      * {@code C.E} would be unable to those private members.
   254      * A workaround for this limitation is the {@link Lookup#in Lookup.in} method,
   258      * A workaround for this limitation is the {@link Lookup#in Lookup.in} method,
   255      * which can transform a lookup on {@code C.E} into one on any of those other
   259      * which can transform a lookup on {@code C.E} into one on any of those other
   256      * classes, without special elevation of privilege.
   260      * classes, without special elevation of privilege.
   257      * <p>
   261      * <p>
       
   262      * Although bytecode instructions can only refer to classes in
       
   263      * a related class loader, this API can search for methods in any
       
   264      * class, as long as a reference to its {@code Class} object is
       
   265      * available.  Such cross-loader references are also possible with the
       
   266      * Core Reflection API, and are impossible to bytecode instructions
       
   267      * such as {@code invokestatic} or {@code getfield}.
       
   268      * There is a {@linkplain java.lang.SecurityManager security manager API}
       
   269      * to allow applications to check such cross-loader references.
       
   270      * These checks apply to both the {@code MethodHandles.Lookup} API
       
   271      * and the Core Reflection API
       
   272      * (as found on {@link java.lang.Class Class}).
       
   273      * <p>
   258      * Access checks only apply to named and reflected methods,
   274      * Access checks only apply to named and reflected methods,
   259      * constructors, and fields.
   275      * constructors, and fields.
   260      * Other method handle creation methods, such as
   276      * Other method handle creation methods, such as
   261      * {@link #convertArguments MethodHandles.convertArguments},
   277      * {@link #convertArguments MethodHandles.convertArguments},
   262      * do not require any access checks, and are done
   278      * do not require any access checks, and are done
   263      * with static methods of {@link MethodHandles},
   279      * with static methods of {@link MethodHandles},
   264      * independently of any {@code Lookup} object.
   280      * independently of any {@code Lookup} object.
       
   281      *
       
   282      * <h3>Security manager interactions</h3>
       
   283      * <a name="secmgr"></a>
       
   284      * If a security manager is present, member lookups are subject to
       
   285      * additional checks.
       
   286      * From one to four calls are made to the security manager.
       
   287      * Any of these calls can refuse access by throwing a
       
   288      * {@link java.lang.SecurityException SecurityException}.
       
   289      * Define {@code smgr} as the security manager,
       
   290      * {@code refc} as the containing class in which the member
       
   291      * is being sought, and {@code defc} as the class in which the
       
   292      * member is actually defined.
       
   293      * The calls are made according to the following rules:
       
   294      * <ul>
       
   295      * <li>In all cases, {@link SecurityManager#checkMemberAccess
       
   296      *     smgr.checkMemberAccess(refc, Member.PUBLIC)} is called.
       
   297      * <li>If the class loader of the lookup class is not
       
   298      *     the same as or an ancestor of the class loader of {@code refc},
       
   299      *     then {@link SecurityManager#checkPackageAccess
       
   300      *     smgr.checkPackageAccess(refcPkg)} is called,
       
   301      *     where {@code refcPkg} is the package of {@code refc}.
       
   302      * <li>If the retrieved member is not public,
       
   303      *     {@link SecurityManager#checkMemberAccess
       
   304      *     smgr.checkMemberAccess(defc, Member.DECLARED)} is called.
       
   305      *     (Note that {@code defc} might be the same as {@code refc}.)
       
   306      * <li>If the retrieved member is not public,
       
   307      *     and if {@code defc} and {@code refc} are in different class loaders,
       
   308      *     and if the class loader of the lookup class is not
       
   309      *     the same as or an ancestor of the class loader of {@code defc},
       
   310      *     then {@link SecurityManager#checkPackageAccess
       
   311      *     smgr.checkPackageAccess(defcPkg)} is called,
       
   312      *     where {@code defcPkg} is the package of {@code defc}.
       
   313      * </ul>
       
   314      * In all cases, the requesting class presented to the security
       
   315      * manager will be the lookup class from the current {@code Lookup} object.
   265      */
   316      */
   266     public static final
   317     public static final
   267     class Lookup {
   318     class Lookup {
   268         /** The class on behalf of whom the lookup is being performed. */
   319         /** The class on behalf of whom the lookup is being performed. */
   269         private final Class<?> lookupClass;
   320         private final Class<?> lookupClass;
   516          * @param name the name of the method
   567          * @param name the name of the method
   517          * @param type the type of the method
   568          * @param type the type of the method
   518          * @return the desired method handle
   569          * @return the desired method handle
   519          * @throws NoSuchMethodException if the method does not exist
   570          * @throws NoSuchMethodException if the method does not exist
   520          * @throws IllegalAccessException if access checking fails, or if the method is not {@code static}
   571          * @throws IllegalAccessException if access checking fails, or if the method is not {@code static}
       
   572          * @exception SecurityException if a security manager is present and it
       
   573          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
   521          * @throws NullPointerException if any argument is null
   574          * @throws NullPointerException if any argument is null
   522          */
   575          */
   523         public
   576         public
   524         MethodHandle findStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
   577         MethodHandle findStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
   525             MemberName method = resolveOrFail(refc, name, type, true);
   578             MemberName method = resolveOrFail(refc, name, type, true);
   556          * @param name the name of the method
   609          * @param name the name of the method
   557          * @param type the type of the method, with the receiver argument omitted
   610          * @param type the type of the method, with the receiver argument omitted
   558          * @return the desired method handle
   611          * @return the desired method handle
   559          * @throws NoSuchMethodException if the method does not exist
   612          * @throws NoSuchMethodException if the method does not exist
   560          * @throws IllegalAccessException if access checking fails, or if the method is {@code static}
   613          * @throws IllegalAccessException if access checking fails, or if the method is {@code static}
       
   614          * @exception SecurityException if a security manager is present and it
       
   615          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
   561          * @throws NullPointerException if any argument is null
   616          * @throws NullPointerException if any argument is null
   562          */
   617          */
   563         public MethodHandle findVirtual(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
   618         public MethodHandle findVirtual(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
   564             MemberName method = resolveOrFail(refc, name, type, false);
   619             MemberName method = resolveOrFail(refc, name, type, false);
   565             checkMethod(refc, method, false);
   620             checkMethod(refc, method, false);
   585          * @param refc the class or interface from which the method is accessed
   640          * @param refc the class or interface from which the method is accessed
   586          * @param type the type of the method, with the receiver argument omitted, and a void return type
   641          * @param type the type of the method, with the receiver argument omitted, and a void return type
   587          * @return the desired method handle
   642          * @return the desired method handle
   588          * @throws NoSuchMethodException if the constructor does not exist
   643          * @throws NoSuchMethodException if the constructor does not exist
   589          * @throws IllegalAccessException if access checking fails
   644          * @throws IllegalAccessException if access checking fails
       
   645          * @exception SecurityException if a security manager is present and it
       
   646          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
   590          * @throws NullPointerException if any argument is null
   647          * @throws NullPointerException if any argument is null
   591          */
   648          */
   592         public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
   649         public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
   593             String name = "<init>";
   650             String name = "<init>";
   594             MemberName ctor = resolveOrFail(refc, name, type, false, false, lookupClassOrNull());
   651             MemberName ctor = resolveOrFail(refc, name, type, false, false, lookupClassOrNull());
   640          * @param type the type of the method, with the receiver argument omitted
   697          * @param type the type of the method, with the receiver argument omitted
   641          * @param specialCaller the proposed calling class to perform the {@code invokespecial}
   698          * @param specialCaller the proposed calling class to perform the {@code invokespecial}
   642          * @return the desired method handle
   699          * @return the desired method handle
   643          * @throws NoSuchMethodException if the method does not exist
   700          * @throws NoSuchMethodException if the method does not exist
   644          * @throws IllegalAccessException if access checking fails
   701          * @throws IllegalAccessException if access checking fails
       
   702          * @exception SecurityException if a security manager is present and it
       
   703          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
   645          * @throws NullPointerException if any argument is null
   704          * @throws NullPointerException if any argument is null
   646          */
   705          */
   647         public MethodHandle findSpecial(Class<?> refc, String name, MethodType type,
   706         public MethodHandle findSpecial(Class<?> refc, String name, MethodType type,
   648                                         Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException {
   707                                         Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException {
   649             checkSpecialCaller(specialCaller);
   708             checkSpecialCaller(specialCaller);
   664          * @param name the field's name
   723          * @param name the field's name
   665          * @param type the field's type
   724          * @param type the field's type
   666          * @return a method handle which can load values from the field
   725          * @return a method handle which can load values from the field
   667          * @throws NoSuchFieldException if the field does not exist
   726          * @throws NoSuchFieldException if the field does not exist
   668          * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
   727          * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
       
   728          * @exception SecurityException if a security manager is present and it
       
   729          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
   669          * @throws NullPointerException if any argument is null
   730          * @throws NullPointerException if any argument is null
   670          */
   731          */
   671         public MethodHandle findGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
   732         public MethodHandle findGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
   672             return makeAccessor(refc, name, type, false, false);
   733             return makeAccessor(refc, name, type, false, false);
   673         }
   734         }
   683          * @param name the field's name
   744          * @param name the field's name
   684          * @param type the field's type
   745          * @param type the field's type
   685          * @return a method handle which can store values into the field
   746          * @return a method handle which can store values into the field
   686          * @throws NoSuchFieldException if the field does not exist
   747          * @throws NoSuchFieldException if the field does not exist
   687          * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
   748          * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
       
   749          * @exception SecurityException if a security manager is present and it
       
   750          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
   688          * @throws NullPointerException if any argument is null
   751          * @throws NullPointerException if any argument is null
   689          */
   752          */
   690         public MethodHandle findSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
   753         public MethodHandle findSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
   691             return makeAccessor(refc, name, type, false, true);
   754             return makeAccessor(refc, name, type, false, true);
   692         }
   755         }
   701          * @param name the field's name
   764          * @param name the field's name
   702          * @param type the field's type
   765          * @param type the field's type
   703          * @return a method handle which can load values from the field
   766          * @return a method handle which can load values from the field
   704          * @throws NoSuchFieldException if the field does not exist
   767          * @throws NoSuchFieldException if the field does not exist
   705          * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
   768          * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
       
   769          * @exception SecurityException if a security manager is present and it
       
   770          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
   706          * @throws NullPointerException if any argument is null
   771          * @throws NullPointerException if any argument is null
   707          */
   772          */
   708         public MethodHandle findStaticGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
   773         public MethodHandle findStaticGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
   709             return makeAccessor(refc, name, type, true, false);
   774             return makeAccessor(refc, name, type, true, false);
   710         }
   775         }
   719          * @param name the field's name
   784          * @param name the field's name
   720          * @param type the field's type
   785          * @param type the field's type
   721          * @return a method handle which can store values into the field
   786          * @return a method handle which can store values into the field
   722          * @throws NoSuchFieldException if the field does not exist
   787          * @throws NoSuchFieldException if the field does not exist
   723          * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
   788          * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
       
   789          * @exception SecurityException if a security manager is present and it
       
   790          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
   724          * @throws NullPointerException if any argument is null
   791          * @throws NullPointerException if any argument is null
   725          */
   792          */
   726         public MethodHandle findStaticSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
   793         public MethodHandle findStaticSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
   727             return makeAccessor(refc, name, type, true, true);
   794             return makeAccessor(refc, name, type, true, true);
   728         }
   795         }
   762          * @param name the name of the method
   829          * @param name the name of the method
   763          * @param type the type of the method, with the receiver argument omitted
   830          * @param type the type of the method, with the receiver argument omitted
   764          * @return the desired method handle
   831          * @return the desired method handle
   765          * @throws NoSuchMethodException if the method does not exist
   832          * @throws NoSuchMethodException if the method does not exist
   766          * @throws IllegalAccessException if access checking fails
   833          * @throws IllegalAccessException if access checking fails
       
   834          * @exception SecurityException if a security manager is present and it
       
   835          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
   767          * @throws NullPointerException if any argument is null
   836          * @throws NullPointerException if any argument is null
   768          */
   837          */
   769         public MethodHandle bind(Object receiver, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
   838         public MethodHandle bind(Object receiver, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
   770             Class<? extends Object> refc = receiver.getClass(); // may get NPE
   839             Class<? extends Object> refc = receiver.getClass(); // may get NPE
   771             MemberName method = resolveOrFail(refc, name, type, false);
   840             MemberName method = resolveOrFail(refc, name, type, false);