467 * with special names ({@code "<init>"} and {@code "<clinit>"}). |
467 * with special names ({@code "<init>"} and {@code "<clinit>"}). |
468 * The internal syntax of invocation instructions allows them to refer to such internal |
468 * The internal syntax of invocation instructions allows them to refer to such internal |
469 * methods as if they were normal methods, but the JVM bytecode verifier rejects them. |
469 * methods as if they were normal methods, but the JVM bytecode verifier rejects them. |
470 * A lookup of such an internal method will produce a {@code NoSuchMethodException}. |
470 * A lookup of such an internal method will produce a {@code NoSuchMethodException}. |
471 * <p> |
471 * <p> |
472 * In some cases, access between nested classes is obtained by the Java compiler by creating |
472 * If the relationship between nested types is expressed directly through the |
473 * an wrapper method to access a private method of another class |
473 * {@code NestHost} and {@code NestMembers} attributes |
474 * in the same top-level declaration. |
474 * (see the Java Virtual Machine Specification, sections 4.7.28 and 4.7.29), |
|
475 * then the associated {@code Lookup} object provides direct access to |
|
476 * the lookup class and all of its nestmates |
|
477 * (see {@link java.lang.Class#getNestHost Class.getNestHost}). |
|
478 * Otherwise, access between nested classes is obtained by the Java compiler creating |
|
479 * a wrapper method to access a private method of another class in the same nest. |
475 * For example, a nested class {@code C.D} |
480 * For example, a nested class {@code C.D} |
476 * can access private members within other related classes such as |
481 * can access private members within other related classes such as |
477 * {@code C}, {@code C.D.E}, or {@code C.B}, |
482 * {@code C}, {@code C.D.E}, or {@code C.B}, |
478 * but the Java compiler may need to generate wrapper methods in |
483 * but the Java compiler may need to generate wrapper methods in |
479 * those related classes. In such cases, a {@code Lookup} object on |
484 * those related classes. In such cases, a {@code Lookup} object on |
480 * {@code C.E} would be unable to those private members. |
485 * {@code C.E} would be unable to access those private members. |
481 * A workaround for this limitation is the {@link Lookup#in Lookup.in} method, |
486 * A workaround for this limitation is the {@link Lookup#in Lookup.in} method, |
482 * which can transform a lookup on {@code C.E} into one on any of those other |
487 * which can transform a lookup on {@code C.E} into one on any of those other |
483 * classes, without special elevation of privilege. |
488 * classes, without special elevation of privilege. |
484 * <p> |
489 * <p> |
485 * The accesses permitted to a given lookup object may be limited, |
490 * The accesses permitted to a given lookup object may be limited, |
497 * <p style="font-size:smaller;"> |
502 * <p style="font-size:smaller;"> |
498 * <a id="privacc"></a> |
503 * <a id="privacc"></a> |
499 * <em>Discussion of private access:</em> |
504 * <em>Discussion of private access:</em> |
500 * We say that a lookup has <em>private access</em> |
505 * We say that a lookup has <em>private access</em> |
501 * if its {@linkplain #lookupModes lookup modes} |
506 * if its {@linkplain #lookupModes lookup modes} |
502 * include the possibility of accessing {@code private} members. |
507 * include the possibility of accessing {@code private} members |
|
508 * (which includes the private members of nestmates). |
503 * As documented in the relevant methods elsewhere, |
509 * As documented in the relevant methods elsewhere, |
504 * only lookups with private access possess the following capabilities: |
510 * only lookups with private access possess the following capabilities: |
505 * <ul style="font-size:smaller;"> |
511 * <ul style="font-size:smaller;"> |
506 * <li>access private fields, methods, and constructors of the lookup class |
512 * <li>access private fields, methods, and constructors of the lookup class and its nestmates |
507 * <li>create method handles which invoke <a href="MethodHandles.Lookup.html#callsens">caller sensitive</a> methods, |
513 * <li>create method handles which invoke <a href="MethodHandles.Lookup.html#callsens">caller sensitive</a> methods, |
508 * such as {@code Class.forName} |
514 * such as {@code Class.forName} |
509 * <li>create method handles which {@link Lookup#findSpecial emulate invokespecial} instructions |
515 * <li>create method handles which {@link Lookup#findSpecial emulate invokespecial} instructions |
510 * <li>avoid <a href="MethodHandles.Lookup.html#secmgr">package access checks</a> |
516 * <li>avoid <a href="MethodHandles.Lookup.html#secmgr">package access checks</a> |
511 * for classes accessible to the lookup class |
517 * for classes accessible to the lookup class |
726 * {@linkplain #MODULE MODULE (0x10)}, |
732 * {@linkplain #MODULE MODULE (0x10)}, |
727 * and {@linkplain #UNCONDITIONAL UNCONDITIONAL (0x20)}. |
733 * and {@linkplain #UNCONDITIONAL UNCONDITIONAL (0x20)}. |
728 * <p> |
734 * <p> |
729 * A freshly-created lookup object |
735 * A freshly-created lookup object |
730 * on the {@linkplain java.lang.invoke.MethodHandles#lookup() caller's class} has |
736 * on the {@linkplain java.lang.invoke.MethodHandles#lookup() caller's class} has |
731 * all possible bits set, except {@code UNCONDITIONAL}. The lookup can be used to |
737 * all possible bits set, except {@code UNCONDITIONAL}. |
732 * access all members of the caller's class, all public types in the caller's module, |
|
733 * and all public types in packages exported by other modules to the caller's module. |
|
734 * A lookup object on a new lookup class |
738 * A lookup object on a new lookup class |
735 * {@linkplain java.lang.invoke.MethodHandles.Lookup#in created from a previous lookup object} |
739 * {@linkplain java.lang.invoke.MethodHandles.Lookup#in created from a previous lookup object} |
736 * may have some mode bits set to zero. |
740 * may have some mode bits set to zero. |
737 * Mode bits can also be |
741 * Mode bits can also be |
738 * {@linkplain java.lang.invoke.MethodHandles.Lookup#dropLookupMode directly cleared}. |
742 * {@linkplain java.lang.invoke.MethodHandles.Lookup#dropLookupMode directly cleared}. |
1104 * The type of the method handle will be that of the method, |
1108 * The type of the method handle will be that of the method, |
1105 * with the receiver type (usually {@code refc}) prepended. |
1109 * with the receiver type (usually {@code refc}) prepended. |
1106 * The method and all its argument types must be accessible to the lookup object. |
1110 * The method and all its argument types must be accessible to the lookup object. |
1107 * <p> |
1111 * <p> |
1108 * When called, the handle will treat the first argument as a receiver |
1112 * When called, the handle will treat the first argument as a receiver |
1109 * and dispatch on the receiver's type to determine which method |
1113 * and, for non-private methods, dispatch on the receiver's type to determine which method |
1110 * implementation to enter. |
1114 * implementation to enter. |
|
1115 * For private methods the named method in {@code refc} will be invoked on the receiver. |
1111 * (The dispatching action is identical with that performed by an |
1116 * (The dispatching action is identical with that performed by an |
1112 * {@code invokevirtual} or {@code invokeinterface} instruction.) |
1117 * {@code invokevirtual} or {@code invokeinterface} instruction.) |
1113 * <p> |
1118 * <p> |
1114 * The first argument will be of type {@code refc} if the lookup |
1119 * The first argument will be of type {@code refc} if the lookup |
1115 * class has full privileges to access the member. Otherwise |
1120 * class has full privileges to access the member. Otherwise |
1169 * @param type the type of the method, with the receiver argument omitted |
1174 * @param type the type of the method, with the receiver argument omitted |
1170 * @return the desired method handle |
1175 * @return the desired method handle |
1171 * @throws NoSuchMethodException if the method does not exist |
1176 * @throws NoSuchMethodException if the method does not exist |
1172 * @throws IllegalAccessException if access checking fails, |
1177 * @throws IllegalAccessException if access checking fails, |
1173 * or if the method is {@code static}, |
1178 * or if the method is {@code static}, |
1174 * or if the method is {@code private} method of interface, |
|
1175 * or if the method's variable arity modifier bit |
1179 * or if the method's variable arity modifier bit |
1176 * is set and {@code asVarargsCollector} fails |
1180 * is set and {@code asVarargsCollector} fails |
1177 * @exception SecurityException if a security manager is present and it |
1181 * @exception SecurityException if a security manager is present and it |
1178 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a> |
1182 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a> |
1179 * @throws NullPointerException if any argument is null |
1183 * @throws NullPointerException if any argument is null |
2223 if (Modifier.isProtected(mods)) |
2227 if (Modifier.isProtected(mods)) |
2224 return "member is protected"; |
2228 return "member is protected"; |
2225 return "member is private to package"; |
2229 return "member is private to package"; |
2226 } |
2230 } |
2227 |
2231 |
2228 private static final boolean ALLOW_NESTMATE_ACCESS = false; |
|
2229 |
|
2230 private void checkSpecialCaller(Class<?> specialCaller, Class<?> refc) throws IllegalAccessException { |
2232 private void checkSpecialCaller(Class<?> specialCaller, Class<?> refc) throws IllegalAccessException { |
2231 int allowedModes = this.allowedModes; |
2233 int allowedModes = this.allowedModes; |
2232 if (allowedModes == TRUSTED) return; |
2234 if (allowedModes == TRUSTED) return; |
2233 if (!hasPrivateAccess() |
2235 if (!hasPrivateAccess() |
2234 || (specialCaller != lookupClass() |
2236 || (specialCaller != lookupClass() |
2235 // ensure non-abstract methods in superinterfaces can be special-invoked |
2237 // ensure non-abstract methods in superinterfaces can be special-invoked |
2236 && !(refc != null && refc.isInterface() && refc.isAssignableFrom(specialCaller)) |
2238 && !(refc != null && refc.isInterface() && refc.isAssignableFrom(specialCaller)))) |
2237 && !(ALLOW_NESTMATE_ACCESS && |
|
2238 VerifyAccess.isSamePackageMember(specialCaller, lookupClass())))) |
|
2239 throw new MemberName(specialCaller). |
2239 throw new MemberName(specialCaller). |
2240 makeAccessException("no private access for invokespecial", this); |
2240 makeAccessException("no private access for invokespecial", this); |
2241 } |
2241 } |
2242 |
2242 |
2243 private boolean restrictProtectedReceiver(MemberName method) { |
2243 private boolean restrictProtectedReceiver(MemberName method) { |
2244 // The accessing class only has the right to use a protected member |
2244 // The accessing class only has the right to use a protected member |
2245 // on itself or a subclass. Enforce that restriction, from JVMS 5.4.4, etc. |
2245 // on itself or a subclass. Enforce that restriction, from JVMS 5.4.4, etc. |
2246 if (!method.isProtected() || method.isStatic() |
2246 if (!method.isProtected() || method.isStatic() |
2247 || allowedModes == TRUSTED |
2247 || allowedModes == TRUSTED |
2248 || method.getDeclaringClass() == lookupClass() |
2248 || method.getDeclaringClass() == lookupClass() |
2249 || VerifyAccess.isSamePackage(method.getDeclaringClass(), lookupClass()) |
2249 || VerifyAccess.isSamePackage(method.getDeclaringClass(), lookupClass())) |
2250 || (ALLOW_NESTMATE_ACCESS && |
|
2251 VerifyAccess.isSamePackageMember(method.getDeclaringClass(), lookupClass()))) |
|
2252 return false; |
2250 return false; |
2253 return true; |
2251 return true; |
2254 } |
2252 } |
2255 private MethodHandle restrictReceiver(MemberName method, DirectMethodHandle mh, Class<?> caller) throws IllegalAccessException { |
2253 private MethodHandle restrictReceiver(MemberName method, DirectMethodHandle mh, Class<?> caller) throws IllegalAccessException { |
2256 assert(!method.isStatic()); |
2254 assert(!method.isStatic()); |
2286 } |
2284 } |
2287 /** Common code for all methods; do not call directly except from immediately above. */ |
2285 /** Common code for all methods; do not call directly except from immediately above. */ |
2288 private MethodHandle getDirectMethodCommon(byte refKind, Class<?> refc, MemberName method, |
2286 private MethodHandle getDirectMethodCommon(byte refKind, Class<?> refc, MemberName method, |
2289 boolean checkSecurity, |
2287 boolean checkSecurity, |
2290 boolean doRestrict, Class<?> boundCallerClass) throws IllegalAccessException { |
2288 boolean doRestrict, Class<?> boundCallerClass) throws IllegalAccessException { |
|
2289 |
2291 checkMethod(refKind, refc, method); |
2290 checkMethod(refKind, refc, method); |
2292 // Optionally check with the security manager; this isn't needed for unreflect* calls. |
2291 // Optionally check with the security manager; this isn't needed for unreflect* calls. |
2293 if (checkSecurity) |
2292 if (checkSecurity) |
2294 checkSecurityManager(refc, method); |
2293 checkSecurityManager(refc, method); |
2295 assert(!method.isMethodHandleInvoke()); |
2294 assert(!method.isMethodHandleInvoke()); |
2298 refc != lookupClass() && |
2297 refc != lookupClass() && |
2299 !refc.isInterface() && |
2298 !refc.isInterface() && |
2300 refc != lookupClass().getSuperclass() && |
2299 refc != lookupClass().getSuperclass() && |
2301 refc.isAssignableFrom(lookupClass())) { |
2300 refc.isAssignableFrom(lookupClass())) { |
2302 assert(!method.getName().equals("<init>")); // not this code path |
2301 assert(!method.getName().equals("<init>")); // not this code path |
|
2302 |
2303 // Per JVMS 6.5, desc. of invokespecial instruction: |
2303 // Per JVMS 6.5, desc. of invokespecial instruction: |
2304 // If the method is in a superclass of the LC, |
2304 // If the method is in a superclass of the LC, |
2305 // and if our original search was above LC.super, |
2305 // and if our original search was above LC.super, |
2306 // repeat the search (symbolic lookup) from LC.super |
2306 // repeat the search (symbolic lookup) from LC.super |
2307 // and continue with the direct superclass of that class, |
2307 // and continue with the direct superclass of that class, |