JDK-8008256 : Runtime error with method refs to members of private classes
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • Submitted: 2013-02-14
  • Updated: 2013-02-15
  • Resolved: 2013-02-15
Related Reports
Duplicate :  
Description
In the following test case, the test methods fail at runtime when they capture a method ref to the constructor of a private class.  (I would expect the same problem with any member of a private class.)  The exception is reproduced below.  

The JSR-292 EG has confirmed that this is expected behavior.  Therefore, javac needs to work around this by converting certain member references to inaccessible members into "bridge" methods, and taking a ref to the bridge instead.  

@Test
public class TestPrivateCtorRef {
    static<T> T makeOne(Supplier<T> supp) {
        T t = supp.get();
        assertNotNull(t != null);
        return t;
    }

    public void testPrivateStatic() {
        makeOne(PS::new);
    }

    private static class PS {
    }

    public void testPrivateInstance() {
        makeOne(PI::new);
    }

    private class PI {
    }
}


java.lang.IncompatibleClassChangeError
	at java.lang.invoke.MethodHandleNatives.linkMethodHandleConstant(MethodHandleNatives.java:383)
	at lambda.TestPrivateCtorRef.testPrivateInstance(TestPrivateCtorRef.java:53)
	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:483)
	at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:80)
	at org.testng.internal.Invoker.invokeMethod(Invoker.java:714)
	at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901)
	at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231)
	at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
	at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
	at org.testng.TestRunner.privateRun(TestRunner.java:767)
	at org.testng.TestRunner.run(TestRunner.java:617)
	at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)
	at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329)
	at org.testng.SuiteRunner.privateRun(SuiteRunner.java:291)
	at org.testng.SuiteRunner.run(SuiteRunner.java:240)
	at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
	at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
	at org.testng.TestNG.runSuitesSequentially(TestNG.java:1198)
	at org.testng.TestNG.runSuitesLocally(TestNG.java:1123)
	at org.testng.TestNG.run(TestNG.java:1031)
	at org.testng.TestNG.privateMain(TestNG.java:1338)
	at org.testng.TestNG.main(TestNG.java:1307)
Caused by: java.lang.IllegalAccessException: member is private: lambda.TestPrivateCtorRef$PI.<init>(TestPrivateCtorRef)void/invokeSpecial, from lambda.TestPrivateCtorRef
	at java.lang.invoke.MemberName.makeAccessException(MemberName.java:732)
	at java.lang.invoke.MethodHandles$Lookup.checkAccess(MethodHandles.java:1135)
	at java.lang.invoke.MethodHandles$Lookup.getDirectConstructor(MethodHandles.java:1243)
	at java.lang.invoke.MethodHandles$Lookup.linkMethodHandleConstant(MethodHandles.java:1270)
	at java.lang.invoke.MethodHandleNatives.linkMethodHandleConstant(MethodHandleNatives.java:381)