452 * In addition, if the desired member is a non-static field or method
453 * in a different package, the resulting method handle may only be applied
454 * to objects of the lookup class or one of its subclasses.
455 * This requirement is enforced by narrowing the type of the leading
456 * {@code this} parameter from {@code C}
457 * (which will necessarily be a superclass of the lookup class)
458 * to the lookup class itself.
459 * <p>
460 * The JVM imposes a similar requirement on {@code invokespecial} instruction,
461 * that the receiver argument must match both the resolved method <em>and</em>
462 * the current class. Again, this requirement is enforced by narrowing the
463 * type of the leading parameter to the resulting method handle.
464 * (See the Java Virtual Machine Specification, section 4.10.1.9.)
465 * <p>
466 * The JVM represents constructors and static initializer blocks as internal methods
467 * with special names ({@code "<init>"} and {@code "<clinit>"}).
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.
470 * A lookup of such an internal method will produce a {@code NoSuchMethodException}.
471 * <p>
472 * In some cases, access between nested classes is obtained by the Java compiler by creating
473 * an wrapper method to access a private method of another class
474 * in the same top-level declaration.
475 * For example, a nested class {@code C.D}
476 * can access private members within other related classes such as
477 * {@code C}, {@code C.D.E}, or {@code C.B},
478 * but the Java compiler may need to generate wrapper methods in
479 * those related classes. In such cases, a {@code Lookup} object on
480 * {@code C.E} would be unable to those private members.
481 * 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
483 * classes, without special elevation of privilege.
484 * <p>
485 * The accesses permitted to a given lookup object may be limited,
486 * according to its set of {@link #lookupModes lookupModes},
487 * to a subset of members normally accessible to the lookup class.
488 * For example, the {@link MethodHandles#publicLookup publicLookup}
489 * method produces a lookup object which is only allowed to access
490 * public members in public classes of exported packages.
491 * The caller sensitive method {@link MethodHandles#lookup lookup}
492 * produces a lookup object with full capabilities relative to
493 * its caller class, to emulate all supported bytecode behaviors.
494 * Also, the {@link Lookup#in Lookup.in} method may produce a lookup object
495 * with fewer access modes than the original lookup object.
496 *
497 * <p style="font-size:smaller;">
498 * <a id="privacc"></a>
499 * <em>Discussion of private access:</em>
500 * We say that a lookup has <em>private access</em>
501 * if its {@linkplain #lookupModes lookup modes}
502 * include the possibility of accessing {@code private} members.
503 * As documented in the relevant methods elsewhere,
504 * only lookups with private access possess the following capabilities:
505 * <ul style="font-size:smaller;">
506 * <li>access private fields, methods, and constructors of the lookup class
507 * <li>create method handles which invoke <a href="MethodHandles.Lookup.html#callsens">caller sensitive</a> methods,
508 * such as {@code Class.forName}
509 * <li>create method handles which {@link Lookup#findSpecial emulate invokespecial} instructions
510 * <li>avoid <a href="MethodHandles.Lookup.html#secmgr">package access checks</a>
511 * for classes accessible to the lookup class
512 * <li>create {@link Lookup#in delegated lookup objects} which have private access to other classes
513 * within the same package member
514 * </ul>
515 * <p style="font-size:smaller;">
516 * Each of these permissions is a consequence of the fact that a lookup object
517 * with private access can be securely traced back to an originating class,
518 * whose <a href="MethodHandles.Lookup.html#equiv">bytecode behaviors</a> and Java language access permissions
519 * can be reliably determined and emulated by method handles.
520 *
521 * <h1><a id="secmgr"></a>Security manager interactions</h1>
522 * Although bytecode instructions can only refer to classes in
523 * a related class loader, this API can search for methods in any
524 * class, as long as a reference to its {@code Class} object is
525 * available. Such cross-loader references are also possible with the
526 * Core Reflection API, and are impossible to bytecode instructions
711 public Class<?> lookupClass() {
712 return lookupClass;
713 }
714
715 // This is just for calling out to MethodHandleImpl.
716 private Class<?> lookupClassOrNull() {
717 return (allowedModes == TRUSTED) ? null : lookupClass;
718 }
719
720 /** Tells which access-protection classes of members this lookup object can produce.
721 * The result is a bit-mask of the bits
722 * {@linkplain #PUBLIC PUBLIC (0x01)},
723 * {@linkplain #PRIVATE PRIVATE (0x02)},
724 * {@linkplain #PROTECTED PROTECTED (0x04)},
725 * {@linkplain #PACKAGE PACKAGE (0x08)},
726 * {@linkplain #MODULE MODULE (0x10)},
727 * and {@linkplain #UNCONDITIONAL UNCONDITIONAL (0x20)}.
728 * <p>
729 * A freshly-created lookup object
730 * 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
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
735 * {@linkplain java.lang.invoke.MethodHandles.Lookup#in created from a previous lookup object}
736 * may have some mode bits set to zero.
737 * Mode bits can also be
738 * {@linkplain java.lang.invoke.MethodHandles.Lookup#dropLookupMode directly cleared}.
739 * Once cleared, mode bits cannot be restored from the downgraded lookup object.
740 * The purpose of this is to restrict access via the new lookup object,
741 * so that it can access only names which can be reached by the original
742 * lookup object, and also by the new lookup class.
743 * @return the lookup modes, which limit the kinds of access performed by this lookup object
744 * @see #in
745 * @see #dropLookupMode
746 *
747 * @revised 9
748 * @spec JPMS
749 */
750 public int lookupModes() {
751 return allowedModes & ALL_MODES;
752 }
753
1089 * or if the method is not {@code static},
1090 * or if the method's variable arity modifier bit
1091 * is set and {@code asVarargsCollector} fails
1092 * @exception SecurityException if a security manager is present and it
1093 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1094 * @throws NullPointerException if any argument is null
1095 */
1096 public
1097 MethodHandle findStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
1098 MemberName method = resolveOrFail(REF_invokeStatic, refc, name, type);
1099 return getDirectMethod(REF_invokeStatic, refc, method, findBoundCallerClass(method));
1100 }
1101
1102 /**
1103 * Produces a method handle for a virtual method.
1104 * The type of the method handle will be that of the method,
1105 * with the receiver type (usually {@code refc}) prepended.
1106 * The method and all its argument types must be accessible to the lookup object.
1107 * <p>
1108 * When called, the handle will treat the first argument as a receiver
1109 * and dispatch on the receiver's type to determine which method
1110 * implementation to enter.
1111 * (The dispatching action is identical with that performed by an
1112 * {@code invokevirtual} or {@code invokeinterface} instruction.)
1113 * <p>
1114 * The first argument will be of type {@code refc} if the lookup
1115 * class has full privileges to access the member. Otherwise
1116 * the member must be {@code protected} and the first argument
1117 * will be restricted in type to the lookup class.
1118 * <p>
1119 * The returned method handle will have
1120 * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
1121 * the method's variable arity modifier bit ({@code 0x0080}) is set.
1122 * <p>
1123 * Because of the general <a href="MethodHandles.Lookup.html#equiv">equivalence</a> between {@code invokevirtual}
1124 * instructions and method handles produced by {@code findVirtual},
1125 * if the class is {@code MethodHandle} and the name string is
1126 * {@code invokeExact} or {@code invoke}, the resulting
1127 * method handle is equivalent to one produced by
1128 * {@link java.lang.invoke.MethodHandles#exactInvoker MethodHandles.exactInvoker} or
1129 * {@link java.lang.invoke.MethodHandles#invoker MethodHandles.invoker}
1130 * with the same {@code type} argument.
1154 MethodHandle MH_subSequence = publicLookup().findVirtual(CharSequence.class,
1155 "subSequence", methodType(CharSequence.class, int.class, int.class));
1156 assertEquals("def", MH_subSequence.invoke("abcdefghi", 3, 6).toString());
1157 // constructor "internal method" must be accessed differently:
1158 MethodType MT_newString = methodType(void.class); //()V for new String()
1159 try { assertEquals("impossible", lookup()
1160 .findVirtual(String.class, "<init>", MT_newString));
1161 } catch (NoSuchMethodException ex) { } // OK
1162 MethodHandle MH_newString = publicLookup()
1163 .findConstructor(String.class, MT_newString);
1164 assertEquals("", (String) MH_newString.invokeExact());
1165 * }</pre></blockquote>
1166 *
1167 * @param refc the class or interface from which the method is accessed
1168 * @param name the name of the method
1169 * @param type the type of the method, with the receiver argument omitted
1170 * @return the desired method handle
1171 * @throws NoSuchMethodException if the method does not exist
1172 * @throws IllegalAccessException if access checking fails,
1173 * 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
1176 * is set and {@code asVarargsCollector} fails
1177 * @exception SecurityException if a security manager is present and it
1178 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1179 * @throws NullPointerException if any argument is null
1180 */
1181 public MethodHandle findVirtual(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
1182 if (refc == MethodHandle.class) {
1183 MethodHandle mh = findVirtualForMH(name, type);
1184 if (mh != null) return mh;
1185 } else if (refc == VarHandle.class) {
1186 MethodHandle mh = findVirtualForVH(name, type);
1187 if (mh != null) return mh;
1188 }
1189 byte refKind = (refc.isInterface() ? REF_invokeInterface : REF_invokeVirtual);
1190 MemberName method = resolveOrFail(refKind, refc, name, type);
1191 return getDirectMethod(refKind, refc, method, findBoundCallerClass(method));
1192 }
1193 private MethodHandle findVirtualForMH(String name, MethodType type) {
1194 // these names require special lookups because of the implicit MethodType argument
2208 // check the class first:
2209 boolean classOK = (Modifier.isPublic(defc.getModifiers()) &&
2210 (defc == refc ||
2211 Modifier.isPublic(refc.getModifiers())));
2212 if (!classOK && (allowedModes & PACKAGE) != 0) {
2213 classOK = (VerifyAccess.isClassAccessible(defc, lookupClass(), FULL_POWER_MODES) &&
2214 (defc == refc ||
2215 VerifyAccess.isClassAccessible(refc, lookupClass(), FULL_POWER_MODES)));
2216 }
2217 if (!classOK)
2218 return "class is not public";
2219 if (Modifier.isPublic(mods))
2220 return "access to public member failed"; // (how?, module not readable?)
2221 if (Modifier.isPrivate(mods))
2222 return "member is private";
2223 if (Modifier.isProtected(mods))
2224 return "member is protected";
2225 return "member is private to package";
2226 }
2227
2228 private static final boolean ALLOW_NESTMATE_ACCESS = false;
2229
2230 private void checkSpecialCaller(Class<?> specialCaller, Class<?> refc) throws IllegalAccessException {
2231 int allowedModes = this.allowedModes;
2232 if (allowedModes == TRUSTED) return;
2233 if (!hasPrivateAccess()
2234 || (specialCaller != lookupClass()
2235 // ensure non-abstract methods in superinterfaces can be special-invoked
2236 && !(refc != null && refc.isInterface() && refc.isAssignableFrom(specialCaller))
2237 && !(ALLOW_NESTMATE_ACCESS &&
2238 VerifyAccess.isSamePackageMember(specialCaller, lookupClass()))))
2239 throw new MemberName(specialCaller).
2240 makeAccessException("no private access for invokespecial", this);
2241 }
2242
2243 private boolean restrictProtectedReceiver(MemberName method) {
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.
2246 if (!method.isProtected() || method.isStatic()
2247 || allowedModes == TRUSTED
2248 || method.getDeclaringClass() == lookupClass()
2249 || VerifyAccess.isSamePackage(method.getDeclaringClass(), lookupClass())
2250 || (ALLOW_NESTMATE_ACCESS &&
2251 VerifyAccess.isSamePackageMember(method.getDeclaringClass(), lookupClass())))
2252 return false;
2253 return true;
2254 }
2255 private MethodHandle restrictReceiver(MemberName method, DirectMethodHandle mh, Class<?> caller) throws IllegalAccessException {
2256 assert(!method.isStatic());
2257 // receiver type of mh is too wide; narrow to caller
2258 if (!method.getDeclaringClass().isAssignableFrom(caller)) {
2259 throw method.makeAccessException("caller class must be a subclass below the method", caller);
2260 }
2261 MethodType rawType = mh.type();
2262 if (caller.isAssignableFrom(rawType.parameterType(0))) return mh; // no need to restrict; already narrow
2263 MethodType narrowType = rawType.changeParameterType(0, caller);
2264 assert(!mh.isVarargsCollector()); // viewAsType will lose varargs-ness
2265 assert(mh.viewAsTypeChecks(narrowType, true));
2266 return mh.copyWith(narrowType, mh.form);
2267 }
2268
2269 /** Check access and get the requested method. */
2270 private MethodHandle getDirectMethod(byte refKind, Class<?> refc, MemberName method, Class<?> boundCallerClass) throws IllegalAccessException {
2271 final boolean doRestrict = true;
2272 final boolean checkSecurity = true;
2273 return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, boundCallerClass);
2274 }
2275 /** Check access and get the requested method, for invokespecial with no restriction on the application of narrowing rules. */
2276 private MethodHandle getDirectMethodNoRestrictInvokeSpecial(Class<?> refc, MemberName method, Class<?> boundCallerClass) throws IllegalAccessException {
2277 final boolean doRestrict = false;
2278 final boolean checkSecurity = true;
2279 return getDirectMethodCommon(REF_invokeSpecial, refc, method, checkSecurity, doRestrict, boundCallerClass);
2280 }
2281 /** Check access and get the requested method, eliding security manager checks. */
2282 private MethodHandle getDirectMethodNoSecurityManager(byte refKind, Class<?> refc, MemberName method, Class<?> boundCallerClass) throws IllegalAccessException {
2283 final boolean doRestrict = true;
2284 final boolean checkSecurity = false; // not needed for reflection or for linking CONSTANT_MH constants
2285 return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, boundCallerClass);
2286 }
2287 /** Common code for all methods; do not call directly except from immediately above. */
2288 private MethodHandle getDirectMethodCommon(byte refKind, Class<?> refc, MemberName method,
2289 boolean checkSecurity,
2290 boolean doRestrict, Class<?> boundCallerClass) throws IllegalAccessException {
2291 checkMethod(refKind, refc, method);
2292 // Optionally check with the security manager; this isn't needed for unreflect* calls.
2293 if (checkSecurity)
2294 checkSecurityManager(refc, method);
2295 assert(!method.isMethodHandleInvoke());
2296
2297 if (refKind == REF_invokeSpecial &&
2298 refc != lookupClass() &&
2299 !refc.isInterface() &&
2300 refc != lookupClass().getSuperclass() &&
2301 refc.isAssignableFrom(lookupClass())) {
2302 assert(!method.getName().equals("<init>")); // not this code path
2303 // Per JVMS 6.5, desc. of invokespecial instruction:
2304 // If the method is in a superclass of the LC,
2305 // and if our original search was above LC.super,
2306 // repeat the search (symbolic lookup) from LC.super
2307 // and continue with the direct superclass of that class,
2308 // and so forth, until a match is found or no further superclasses exist.
2309 // FIXME: MemberName.resolve should handle this instead.
2310 Class<?> refcAsSuper = lookupClass();
2311 MemberName m2;
2312 do {
2313 refcAsSuper = refcAsSuper.getSuperclass();
2314 m2 = new MemberName(refcAsSuper,
2315 method.getName(),
2316 method.getMethodType(),
2317 REF_invokeSpecial);
2318 m2 = IMPL_NAMES.resolveOrNull(refKind, m2, lookupClassOrNull());
2319 } while (m2 == null && // no method is found yet
2320 refc != refcAsSuper); // search up to refc
2321 if (m2 == null) throw new InternalError(method.toString());
2322 method = m2;
|
452 * In addition, if the desired member is a non-static field or method
453 * in a different package, the resulting method handle may only be applied
454 * to objects of the lookup class or one of its subclasses.
455 * This requirement is enforced by narrowing the type of the leading
456 * {@code this} parameter from {@code C}
457 * (which will necessarily be a superclass of the lookup class)
458 * to the lookup class itself.
459 * <p>
460 * The JVM imposes a similar requirement on {@code invokespecial} instruction,
461 * that the receiver argument must match both the resolved method <em>and</em>
462 * the current class. Again, this requirement is enforced by narrowing the
463 * type of the leading parameter to the resulting method handle.
464 * (See the Java Virtual Machine Specification, section 4.10.1.9.)
465 * <p>
466 * The JVM represents constructors and static initializer blocks as internal methods
467 * with special names ({@code "<init>"} and {@code "<clinit>"}).
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.
470 * A lookup of such an internal method will produce a {@code NoSuchMethodException}.
471 * <p>
472 * If the relationship between nested types is expressed directly through the
473 * {@code NestHost} and {@code NestMembers} attributes
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.
480 * For example, a nested class {@code C.D}
481 * can access private members within other related classes such as
482 * {@code C}, {@code C.D.E}, or {@code C.B},
483 * but the Java compiler may need to generate wrapper methods in
484 * those related classes. In such cases, a {@code Lookup} object on
485 * {@code C.E} would be unable to access those private members.
486 * A workaround for this limitation is the {@link Lookup#in Lookup.in} method,
487 * which can transform a lookup on {@code C.E} into one on any of those other
488 * classes, without special elevation of privilege.
489 * <p>
490 * The accesses permitted to a given lookup object may be limited,
491 * according to its set of {@link #lookupModes lookupModes},
492 * to a subset of members normally accessible to the lookup class.
493 * For example, the {@link MethodHandles#publicLookup publicLookup}
494 * method produces a lookup object which is only allowed to access
495 * public members in public classes of exported packages.
496 * The caller sensitive method {@link MethodHandles#lookup lookup}
497 * produces a lookup object with full capabilities relative to
498 * its caller class, to emulate all supported bytecode behaviors.
499 * Also, the {@link Lookup#in Lookup.in} method may produce a lookup object
500 * with fewer access modes than the original lookup object.
501 *
502 * <p style="font-size:smaller;">
503 * <a id="privacc"></a>
504 * <em>Discussion of private access:</em>
505 * We say that a lookup has <em>private access</em>
506 * if its {@linkplain #lookupModes lookup modes}
507 * include the possibility of accessing {@code private} members
508 * (which includes the private members of nestmates).
509 * As documented in the relevant methods elsewhere,
510 * only lookups with private access possess the following capabilities:
511 * <ul style="font-size:smaller;">
512 * <li>access private fields, methods, and constructors of the lookup class and its nestmates
513 * <li>create method handles which invoke <a href="MethodHandles.Lookup.html#callsens">caller sensitive</a> methods,
514 * such as {@code Class.forName}
515 * <li>create method handles which {@link Lookup#findSpecial emulate invokespecial} instructions
516 * <li>avoid <a href="MethodHandles.Lookup.html#secmgr">package access checks</a>
517 * for classes accessible to the lookup class
518 * <li>create {@link Lookup#in delegated lookup objects} which have private access to other classes
519 * within the same package member
520 * </ul>
521 * <p style="font-size:smaller;">
522 * Each of these permissions is a consequence of the fact that a lookup object
523 * with private access can be securely traced back to an originating class,
524 * whose <a href="MethodHandles.Lookup.html#equiv">bytecode behaviors</a> and Java language access permissions
525 * can be reliably determined and emulated by method handles.
526 *
527 * <h1><a id="secmgr"></a>Security manager interactions</h1>
528 * Although bytecode instructions can only refer to classes in
529 * a related class loader, this API can search for methods in any
530 * class, as long as a reference to its {@code Class} object is
531 * available. Such cross-loader references are also possible with the
532 * Core Reflection API, and are impossible to bytecode instructions
717 public Class<?> lookupClass() {
718 return lookupClass;
719 }
720
721 // This is just for calling out to MethodHandleImpl.
722 private Class<?> lookupClassOrNull() {
723 return (allowedModes == TRUSTED) ? null : lookupClass;
724 }
725
726 /** Tells which access-protection classes of members this lookup object can produce.
727 * The result is a bit-mask of the bits
728 * {@linkplain #PUBLIC PUBLIC (0x01)},
729 * {@linkplain #PRIVATE PRIVATE (0x02)},
730 * {@linkplain #PROTECTED PROTECTED (0x04)},
731 * {@linkplain #PACKAGE PACKAGE (0x08)},
732 * {@linkplain #MODULE MODULE (0x10)},
733 * and {@linkplain #UNCONDITIONAL UNCONDITIONAL (0x20)}.
734 * <p>
735 * A freshly-created lookup object
736 * on the {@linkplain java.lang.invoke.MethodHandles#lookup() caller's class} has
737 * all possible bits set, except {@code UNCONDITIONAL}.
738 * A lookup object on a new lookup class
739 * {@linkplain java.lang.invoke.MethodHandles.Lookup#in created from a previous lookup object}
740 * may have some mode bits set to zero.
741 * Mode bits can also be
742 * {@linkplain java.lang.invoke.MethodHandles.Lookup#dropLookupMode directly cleared}.
743 * Once cleared, mode bits cannot be restored from the downgraded lookup object.
744 * The purpose of this is to restrict access via the new lookup object,
745 * so that it can access only names which can be reached by the original
746 * lookup object, and also by the new lookup class.
747 * @return the lookup modes, which limit the kinds of access performed by this lookup object
748 * @see #in
749 * @see #dropLookupMode
750 *
751 * @revised 9
752 * @spec JPMS
753 */
754 public int lookupModes() {
755 return allowedModes & ALL_MODES;
756 }
757
1093 * or if the method is not {@code static},
1094 * or if the method's variable arity modifier bit
1095 * is set and {@code asVarargsCollector} fails
1096 * @exception SecurityException if a security manager is present and it
1097 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1098 * @throws NullPointerException if any argument is null
1099 */
1100 public
1101 MethodHandle findStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
1102 MemberName method = resolveOrFail(REF_invokeStatic, refc, name, type);
1103 return getDirectMethod(REF_invokeStatic, refc, method, findBoundCallerClass(method));
1104 }
1105
1106 /**
1107 * Produces a method handle for a virtual method.
1108 * The type of the method handle will be that of the method,
1109 * with the receiver type (usually {@code refc}) prepended.
1110 * The method and all its argument types must be accessible to the lookup object.
1111 * <p>
1112 * When called, the handle will treat the first argument as a receiver
1113 * and, for non-private methods, dispatch on the receiver's type to determine which method
1114 * implementation to enter.
1115 * For private methods the named method in {@code refc} will be invoked on the receiver.
1116 * (The dispatching action is identical with that performed by an
1117 * {@code invokevirtual} or {@code invokeinterface} instruction.)
1118 * <p>
1119 * The first argument will be of type {@code refc} if the lookup
1120 * class has full privileges to access the member. Otherwise
1121 * the member must be {@code protected} and the first argument
1122 * will be restricted in type to the lookup class.
1123 * <p>
1124 * The returned method handle will have
1125 * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
1126 * the method's variable arity modifier bit ({@code 0x0080}) is set.
1127 * <p>
1128 * Because of the general <a href="MethodHandles.Lookup.html#equiv">equivalence</a> between {@code invokevirtual}
1129 * instructions and method handles produced by {@code findVirtual},
1130 * if the class is {@code MethodHandle} and the name string is
1131 * {@code invokeExact} or {@code invoke}, the resulting
1132 * method handle is equivalent to one produced by
1133 * {@link java.lang.invoke.MethodHandles#exactInvoker MethodHandles.exactInvoker} or
1134 * {@link java.lang.invoke.MethodHandles#invoker MethodHandles.invoker}
1135 * with the same {@code type} argument.
1159 MethodHandle MH_subSequence = publicLookup().findVirtual(CharSequence.class,
1160 "subSequence", methodType(CharSequence.class, int.class, int.class));
1161 assertEquals("def", MH_subSequence.invoke("abcdefghi", 3, 6).toString());
1162 // constructor "internal method" must be accessed differently:
1163 MethodType MT_newString = methodType(void.class); //()V for new String()
1164 try { assertEquals("impossible", lookup()
1165 .findVirtual(String.class, "<init>", MT_newString));
1166 } catch (NoSuchMethodException ex) { } // OK
1167 MethodHandle MH_newString = publicLookup()
1168 .findConstructor(String.class, MT_newString);
1169 assertEquals("", (String) MH_newString.invokeExact());
1170 * }</pre></blockquote>
1171 *
1172 * @param refc the class or interface from which the method is accessed
1173 * @param name the name of the method
1174 * @param type the type of the method, with the receiver argument omitted
1175 * @return the desired method handle
1176 * @throws NoSuchMethodException if the method does not exist
1177 * @throws IllegalAccessException if access checking fails,
1178 * or if the method is {@code static},
1179 * or if the method's variable arity modifier bit
1180 * is set and {@code asVarargsCollector} fails
1181 * @exception SecurityException if a security manager is present and it
1182 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1183 * @throws NullPointerException if any argument is null
1184 */
1185 public MethodHandle findVirtual(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
1186 if (refc == MethodHandle.class) {
1187 MethodHandle mh = findVirtualForMH(name, type);
1188 if (mh != null) return mh;
1189 } else if (refc == VarHandle.class) {
1190 MethodHandle mh = findVirtualForVH(name, type);
1191 if (mh != null) return mh;
1192 }
1193 byte refKind = (refc.isInterface() ? REF_invokeInterface : REF_invokeVirtual);
1194 MemberName method = resolveOrFail(refKind, refc, name, type);
1195 return getDirectMethod(refKind, refc, method, findBoundCallerClass(method));
1196 }
1197 private MethodHandle findVirtualForMH(String name, MethodType type) {
1198 // these names require special lookups because of the implicit MethodType argument
2212 // check the class first:
2213 boolean classOK = (Modifier.isPublic(defc.getModifiers()) &&
2214 (defc == refc ||
2215 Modifier.isPublic(refc.getModifiers())));
2216 if (!classOK && (allowedModes & PACKAGE) != 0) {
2217 classOK = (VerifyAccess.isClassAccessible(defc, lookupClass(), FULL_POWER_MODES) &&
2218 (defc == refc ||
2219 VerifyAccess.isClassAccessible(refc, lookupClass(), FULL_POWER_MODES)));
2220 }
2221 if (!classOK)
2222 return "class is not public";
2223 if (Modifier.isPublic(mods))
2224 return "access to public member failed"; // (how?, module not readable?)
2225 if (Modifier.isPrivate(mods))
2226 return "member is private";
2227 if (Modifier.isProtected(mods))
2228 return "member is protected";
2229 return "member is private to package";
2230 }
2231
2232 private void checkSpecialCaller(Class<?> specialCaller, Class<?> refc) throws IllegalAccessException {
2233 int allowedModes = this.allowedModes;
2234 if (allowedModes == TRUSTED) return;
2235 if (!hasPrivateAccess()
2236 || (specialCaller != lookupClass()
2237 // ensure non-abstract methods in superinterfaces can be special-invoked
2238 && !(refc != null && refc.isInterface() && refc.isAssignableFrom(specialCaller))))
2239 throw new MemberName(specialCaller).
2240 makeAccessException("no private access for invokespecial", this);
2241 }
2242
2243 private boolean restrictProtectedReceiver(MemberName method) {
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.
2246 if (!method.isProtected() || method.isStatic()
2247 || allowedModes == TRUSTED
2248 || method.getDeclaringClass() == lookupClass()
2249 || VerifyAccess.isSamePackage(method.getDeclaringClass(), lookupClass()))
2250 return false;
2251 return true;
2252 }
2253 private MethodHandle restrictReceiver(MemberName method, DirectMethodHandle mh, Class<?> caller) throws IllegalAccessException {
2254 assert(!method.isStatic());
2255 // receiver type of mh is too wide; narrow to caller
2256 if (!method.getDeclaringClass().isAssignableFrom(caller)) {
2257 throw method.makeAccessException("caller class must be a subclass below the method", caller);
2258 }
2259 MethodType rawType = mh.type();
2260 if (caller.isAssignableFrom(rawType.parameterType(0))) return mh; // no need to restrict; already narrow
2261 MethodType narrowType = rawType.changeParameterType(0, caller);
2262 assert(!mh.isVarargsCollector()); // viewAsType will lose varargs-ness
2263 assert(mh.viewAsTypeChecks(narrowType, true));
2264 return mh.copyWith(narrowType, mh.form);
2265 }
2266
2267 /** Check access and get the requested method. */
2268 private MethodHandle getDirectMethod(byte refKind, Class<?> refc, MemberName method, Class<?> boundCallerClass) throws IllegalAccessException {
2269 final boolean doRestrict = true;
2270 final boolean checkSecurity = true;
2271 return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, boundCallerClass);
2272 }
2273 /** Check access and get the requested method, for invokespecial with no restriction on the application of narrowing rules. */
2274 private MethodHandle getDirectMethodNoRestrictInvokeSpecial(Class<?> refc, MemberName method, Class<?> boundCallerClass) throws IllegalAccessException {
2275 final boolean doRestrict = false;
2276 final boolean checkSecurity = true;
2277 return getDirectMethodCommon(REF_invokeSpecial, refc, method, checkSecurity, doRestrict, boundCallerClass);
2278 }
2279 /** Check access and get the requested method, eliding security manager checks. */
2280 private MethodHandle getDirectMethodNoSecurityManager(byte refKind, Class<?> refc, MemberName method, Class<?> boundCallerClass) throws IllegalAccessException {
2281 final boolean doRestrict = true;
2282 final boolean checkSecurity = false; // not needed for reflection or for linking CONSTANT_MH constants
2283 return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, boundCallerClass);
2284 }
2285 /** Common code for all methods; do not call directly except from immediately above. */
2286 private MethodHandle getDirectMethodCommon(byte refKind, Class<?> refc, MemberName method,
2287 boolean checkSecurity,
2288 boolean doRestrict, Class<?> boundCallerClass) throws IllegalAccessException {
2289
2290 checkMethod(refKind, refc, method);
2291 // Optionally check with the security manager; this isn't needed for unreflect* calls.
2292 if (checkSecurity)
2293 checkSecurityManager(refc, method);
2294 assert(!method.isMethodHandleInvoke());
2295
2296 if (refKind == REF_invokeSpecial &&
2297 refc != lookupClass() &&
2298 !refc.isInterface() &&
2299 refc != lookupClass().getSuperclass() &&
2300 refc.isAssignableFrom(lookupClass())) {
2301 assert(!method.getName().equals("<init>")); // not this code path
2302
2303 // Per JVMS 6.5, desc. of invokespecial instruction:
2304 // If the method is in a superclass of the LC,
2305 // and if our original search was above LC.super,
2306 // repeat the search (symbolic lookup) from LC.super
2307 // and continue with the direct superclass of that class,
2308 // and so forth, until a match is found or no further superclasses exist.
2309 // FIXME: MemberName.resolve should handle this instead.
2310 Class<?> refcAsSuper = lookupClass();
2311 MemberName m2;
2312 do {
2313 refcAsSuper = refcAsSuper.getSuperclass();
2314 m2 = new MemberName(refcAsSuper,
2315 method.getName(),
2316 method.getMethodType(),
2317 REF_invokeSpecial);
2318 m2 = IMPL_NAMES.resolveOrNull(refKind, m2, lookupClassOrNull());
2319 } while (m2 == null && // no method is found yet
2320 refc != refcAsSuper); // search up to refc
2321 if (m2 == null) throw new InternalError(method.toString());
2322 method = m2;
|