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)
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)
- duplicates
-
JDK-8005183 Missing accessor for constructor reference pointing to private inner class ctor
-
- Closed
-