A DESCRIPTION OF THE PROBLEM :
Calling java.lang.invoke.MethodHandleProxies.asInterfaceInstance vis MethodHandle throws InternalError if a SecurityManager is installed.
The line that throws this error has the following comment:
// does not happen, and should not anyway
The problem here is that the name of the caller class for a bound MethondHandle starts with java.lang.invoke, e.g. class java.lang.invoke.MethodHandleImpl$BindCaller$T/1828757853
This is also the problem with JDK-8013527 [1].
Using JDK 10, this works, because the name of the bound class has changed and now starts with the package the caller is in.
[1]: https://bugs.openjdk.java.net/browse/JDK-8013527
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Try to call java.lang.invoke.MethodHandleProxies.asInterfaceInstance using a MethodHandle while a SecurityManager is installed.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
A instance of the interface is returned.
ACTUAL -
An InternalError is thrown.
Stacktrace:
Exception in thread "main" java.lang.InternalError
at java.lang.invoke.MethodHandleImpl$BindCaller.bindCaller(MethodHandleImpl.java:1131)
at java.lang.invoke.MethodHandleImpl.bindCaller(MethodHandleImpl.java:1117)
at java.lang.invoke.MethodHandleProxies.bindCaller(MethodHandleProxies.java:219)
at java.lang.invoke.MethodHandleProxies.asInterfaceInstance(MethodHandleProxies.java:158)
at java.lang.invoke.MethodHandleImpl$BindCaller$T/303563356.invoke_V(MethodHandleImpl.java:1258)
at bug.IndirectMHP.main(IndirectMHP.java:29)
---------- BEGIN SOURCE ----------
package bug;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandleProxies;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodHandles.Lookup;
import java.lang.invoke.MethodType;
import java.util.Comparator;
public class IndirectMHP {
public static void main(String[] args) throws Throwable {
MethodHandle const0 = MethodHandles.constant(int.class, 0);
MethodHandle compMH = MethodHandles.dropArguments(const0, 0, Object.class, Object.class);
Lookup l = MethodHandles.lookup();
MethodType asInterfaceMT = MethodType.methodType(Object.class, Class.class,
MethodHandle.class);
MethodHandle asInterfaceMH = l.findStatic(MethodHandleProxies.class, "asInterfaceInstance",
asInterfaceMT);
// This works.
Comparator<?> cmp1 = MethodHandleProxies.asInterfaceInstance(Comparator.class, compMH);
// This also works.
Object cmp2 = asInterfaceMH.invokeExact(Comparator.class, compMH);
System.setSecurityManager(new SecurityManager());
// This also works.
Comparator<?> cmp3 = MethodHandleProxies.asInterfaceInstance(Comparator.class, compMH);
// This will throw an InternalError
Object cmp4 = asInterfaceMH.invokeExact(Comparator.class, compMH);
}
}
---------- END SOURCE ----------
FREQUENCY : always