-
Bug
-
Resolution: Unresolved
-
P4
-
9
-
None
-
Fix Understood
MethodHandle lookups mimic the JVM's method resolution behavior (JVMS 5.4.3.3). This involves taking a *referenced* class and a method name/descriptor, and returning a *declared* class and method. Often, the declaring class is a supertype of the referenced class, rather than being the same as the referenced class.
MethodHandleInfo provides getDeclaringClass, but does not have any way to get the referenced class.
Example:
import java.lang.invoke.*;
public class MethodHandleInfoTest {
public static void main(String... args) throws Exception {
MethodHandles.Lookup l = MethodHandles.lookup();
MethodHandle mh = l.findVirtual(MethodHandleInfoTest.class, "toString", MethodType.methodType(String.class));
MethodHandleInfo info = l.revealDirect(mh);
System.out.println(info.getDeclaringClass()); // declaring class
System.out.println(info.???); // referenced class
}
}
The referenced class is important, because i) the mapping from a referenced class to a declaring class is nondeterministic if there are multiple superinterfaces that declare equivalent methods (the VM may pick any one superinterface); ii) access restrictions on the declaring class may be different than access restrictions on the referenced class.
Concretely, for example, an implementation of LambdaMetafactory may wish to serialize a MethodHandle in bytecode. In order to avoid access problems, this serialized form needs to name the referenced class, not the declaring class.
MethodHandleInfo provides getDeclaringClass, but does not have any way to get the referenced class.
Example:
import java.lang.invoke.*;
public class MethodHandleInfoTest {
public static void main(String... args) throws Exception {
MethodHandles.Lookup l = MethodHandles.lookup();
MethodHandle mh = l.findVirtual(MethodHandleInfoTest.class, "toString", MethodType.methodType(String.class));
MethodHandleInfo info = l.revealDirect(mh);
System.out.println(info.getDeclaringClass()); // declaring class
System.out.println(info.???); // referenced class
}
}
The referenced class is important, because i) the mapping from a referenced class to a declaring class is nondeterministic if there are multiple superinterfaces that declare equivalent methods (the VM may pick any one superinterface); ii) access restrictions on the declaring class may be different than access restrictions on the referenced class.
Concretely, for example, an implementation of LambdaMetafactory may wish to serialize a MethodHandle in bytecode. In order to avoid access problems, this serialized form needs to name the referenced class, not the declaring class.
- blocks
-
JDK-8172817 LambdaMetafactory should use the referenced class of static implMethods
- Open
- relates to
-
JDK-8172815 MethodHandles.Lookup.revealDirect performs access checking against wrong class
- Open
-
JDK-8282080 Lambda deserialization fails for Object method references on interfaces
- Closed
-
JDK-8068254 Method reference uses wrong qualifying type
- Closed
-
JDK-8075779 JSR 292 enhancements for maintenance releases
- Open