JDK-8207834 : Calling MethodHandleProxies.aII via MethodHandle throws InternalError
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang.invoke
  • Affected Version: 8
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • OS: generic
  • CPU: generic
  • Submitted: 2018-07-14
  • Updated: 2023-09-12
Related Reports
Relates :  
Description
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



Comments
Additional Information from submitter >Mandy Chung added a comment > MethodHandleProxies::asInterfaceInstance still binds caller when security manager is enabled. We should look deeper and understand why the test case passes since 9. This was apparently changed due JDK-8149574. The bind caller works by injecting an anonymous inner class. In Java 8 it looks like java.lang.invoke.MethodHandleImpl$BindCaller$T/303563356 for any class. Starting with java 9, the name of this anonymous inner class has changed and is based on the bound class, so it's name doesn't start with java.lang.invoke.
23-07-2018

MethodHandleProxies::asInterfaceInstance still binds caller when security manager is enabled. We should look deeper and understand why the test case passes since 9.
19-07-2018

InternalError is only observed on 8, no error observed on 9, 10, 11 and 12 -sh-4.2$ ../jdk/8u181/all/b11/binaries/linux-x64/bin/java IndirectMHP 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/531885035.invoke_V(MethodHandleImpl.java:1258) at IndirectMHP.main(IndirectMHP.java:27)
19-07-2018