JDK-7077803 : java.lang.InternalError in java.lang.invoke.MethodHandleNatives.init
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang.invoke
  • Affected Version: hs22,7
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2011-08-11
  • Updated: 2013-09-13
  • Resolved: 2012-01-27
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7 JDK 8
7u4Fixed 8 b23Fixed
Description
JCK tests
	api/java_lang/invoke/MethodHandles/Lookup/index.html#MethodsTests[unreflectConstructorAF]	
	api/java_lang/invoke/MethodHandles/Lookup/index.html#MethodsTests[unreflectAF]	

fail with fastdebug build:
java.lang.InternalError: javasoft.sqe.tests.api.java.lang.invoke.MethodHandles.Lookup.TestCls.m3()I
	at java.lang.invoke.MethodHandleNatives.init(Native Method)
	at java.lang.invoke.DirectMethodHandle.<init>(DirectMethodHandle.java:47)
	at java.lang.invoke.MethodHandleImpl.findMethod(MethodHandleImpl.java:85)
	at java.lang.invoke.MethodHandles$Lookup.unreflect(MethodHandles.java:952)
	at javasoft.sqe.tests.api.java.lang.invoke.MethodHandles.Lookup.MethodsTests.unreflectAF(MethodsTests.java:944)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:601)
	at com.sun.tck.lib.tgf.Util.invokeMethod(Util.java:309)
	at com.sun.tck.lib.tgf.Runner.invokeTestCase(Runner.java:275)
	at com.sun.tck.lib.tgf.Runner.performRunWithData(Runner.java:246)
	at com.sun.tck.lib.tgf.Runner.getDataAndRun(Runner.java:185)
	at com.sun.tck.lib.tgf.Runner.executeTestMethods(Runner.java:130)
	at com.sun.tck.lib.tgf.Runner.run(Runner.java:116)
	at com.sun.tck.lib.tgf.Runner.execute(Runner.java:108)
	at com.sun.tck.lib.tgf.TGFTest.run(TGFTest.java:58)
	at com.sun.tck.lib.tgf.TGFTest.run(TGFTest.java:64)
	at javasoft.sqe.tests.api.java.lang.invoke.MethodHandles.Lookup.MethodsTests.main(MethodsTests.java:64)


java.lang.InternalError: javasoft.sqe.tests.api.java.lang.invoke.MethodHandles.Lookup.TestCls.<init>(II)V
	at java.lang.invoke.MethodHandleNatives.init(Native Method)
	at java.lang.invoke.DirectMethodHandle.<init>(DirectMethodHandle.java:47)
	at java.lang.invoke.MethodHandleImpl.findMethod(MethodHandleImpl.java:85)
	at java.lang.invoke.MethodHandles$Lookup.unreflectConstructor(MethodHandles.java:1013)
	at javasoft.sqe.tests.api.java.lang.invoke.MethodHandles.Lookup.MethodsTests.unreflectConstructorAF(MethodsTests.java:994)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:601)
	at com.sun.tck.lib.tgf.Util.invokeMethod(Util.java:309)
	at com.sun.tck.lib.tgf.Runner.invokeTestCase(Runner.java:275)
	at com.sun.tck.lib.tgf.Runner.performRunWithData(Runner.java:246)
	at com.sun.tck.lib.tgf.Runner.getDataAndRun(Runner.java:185)
	at com.sun.tck.lib.tgf.Runner.executeTestMethods(Runner.java:130)
	at com.sun.tck.lib.tgf.Runner.run(Runner.java:116)
	at com.sun.tck.lib.tgf.Runner.execute(Runner.java:108)
	at com.sun.tck.lib.tgf.TGFTest.run(TGFTest.java:58)
	at com.sun.tck.lib.tgf.TGFTest.run(TGFTest.java:64)
	at javasoft.sqe.tests.api.java.lang.invoke.MethodHandles.Lookup.MethodsTests.main(MethodsTests.java:64)

Comments
SUGGESTED FIX diff --git a/src/share/classes/java/lang/invoke/MethodHandles.java b/src/share/classes/java/lang/invoke/MethodHandles.java --- a/src/share/classes/java/lang/invoke/MethodHandles.java +++ b/src/share/classes/java/lang/invoke/MethodHandles.java @@ -948,10 +948,11 @@ public MethodHandle unreflect(Method m) throws IllegalAccessException { MemberName method = new MemberName(m); assert(method.isMethod()); - if (!m.isAccessible()) checkMethod(method.getDeclaringClass(), method, method.isStatic()); + if (m.isAccessible()) + return MethodHandleImpl.findMethod(method, true, /*no lookupClass*/ null); + checkMethod(method.getDeclaringClass(), method, method.isStatic()); MethodHandle mh = MethodHandleImpl.findMethod(method, true, lookupClassOrNull()); - if (!m.isAccessible()) mh = restrictProtectedReceiver(method, mh); - return mh; + return restrictProtectedReceiver(method, mh); } /** @@ -1009,8 +1010,13 @@ public MethodHandle unreflectConstructor(Constructor c) throws IllegalAccessException { MemberName ctor = new MemberName(c); assert(ctor.isConstructor()); - if (!c.isAccessible()) checkAccess(c.getDeclaringClass(), ctor); - MethodHandle rawCtor = MethodHandleImpl.findMethod(ctor, false, lookupClassOrNull()); + MethodHandle rawCtor; + if (c.isAccessible()) { + rawCtor = MethodHandleImpl.findMethod(ctor, false, /*no lookupClass*/ null); + } else { + checkAccess(c.getDeclaringClass(), ctor); + rawCtor = MethodHandleImpl.findMethod(ctor, false, lookupClassOrNull()); + } MethodHandle allocator = MethodHandleImpl.makeAllocator(rawCtor); return fixVarargs(allocator, rawCtor); } @@ -1225,7 +1231,7 @@ ? "expected a static field" : "expected a non-static field", this); if (trusted) - return MethodHandleImpl.accessField(field, isSetter, lookupClassOrNull()); + return MethodHandleImpl.accessField(field, isSetter, /*no lookupClass*/ null); checkAccess(refc, field); MethodHandle mh = MethodHandleImpl.accessField(field, isSetter, lookupClassOrNull()); return restrictProtectedReceiver(field, mh);
17-08-2011

EVALUATION It fails with fastdebug 7b147 too. MethodHandleNatives.<init> has extra sanity checking in debug mode which is where the InternalError comes from. I suspect the logic in the JVM should just be removed since I don't think it can take into account all the tests that the Java code uses to decide accessibility. In particular the access checks are skipped if Method.isAccessible() returns true but that's not passed through.
11-08-2011