Details
-
Bug
-
Resolution: Fixed
-
P2
-
9
-
b168
-
Verified
Backports
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8179748 | 10 | Paul Sandoz | P2 | Resolved | Fixed | b07 |
Description
MethodHandles.Lookup::bind allows to create a method handle for an inherited protected member bound to an instance of a parent class.
That's forbidden by the protected access rules. JVMS 4.9.2 says: "If invokevirtual or invokespecial is used to access a protected method declared in a superclass that is a member of a different run-time package than the current class, then the type of the class instance being accessed must be the same as or a subclass of the current class."
Other Lookup factories take that into account by restricting the receiver type (e.g. see the findVirtual + bindTo throwing CCE in the example)
Example:
=================================
public class B extends A {
public static void main(String[] args) throws Throwable {
// prints "B", as expected
MethodHandle bound = lookup().bind(new B() , "m", MethodType.methodType(void.class));
bound.invoke();
// prints "A", but should've thrown an exception (IAE or CCE?)
MethodHandle bound2 = lookup().bind(new A() , "m", MethodType.methodType(void.class));
bound2.invoke();
// throws CCE
lookup().findVirtual(A.class, "m", MethodType.methodType(void.class))
.bindTo(new A());
}
}
package pkg;
public class A {
protected void m() {
System.out.println(this.getClass().getSimpleName());
}
}
=================================
That's forbidden by the protected access rules. JVMS 4.9.2 says: "If invokevirtual or invokespecial is used to access a protected method declared in a superclass that is a member of a different run-time package than the current class, then the type of the class instance being accessed must be the same as or a subclass of the current class."
Other Lookup factories take that into account by restricting the receiver type (e.g. see the findVirtual + bindTo throwing CCE in the example)
Example:
=================================
public class B extends A {
public static void main(String[] args) throws Throwable {
// prints "B", as expected
MethodHandle bound = lookup().bind(new B() , "m", MethodType.methodType(void.class));
bound.invoke();
// prints "A", but should've thrown an exception (IAE or CCE?)
MethodHandle bound2 = lookup().bind(new A() , "m", MethodType.methodType(void.class));
bound2.invoke();
// throws CCE
lookup().findVirtual(A.class, "m", MethodType.methodType(void.class))
.bindTo(new A());
}
}
package pkg;
public class A {
protected void m() {
System.out.println(this.getClass().getSimpleName());
}
}
=================================
Attachments
Issue Links
- backported by
-
JDK-8179748 MethodHandles.Lookup::bind allows illegal protected access
- Resolved
- relates to
-
JDK-8180075 Javadoc of MethodHandles.Lookup::bind should note the difference from MethodHandle::bindTo
- Closed
There are no Sub-Tasks for this issue.