-
Bug
-
Resolution: Cannot Reproduce
-
P3
-
None
-
lambda repo
When capturing a constructor ref to a local class that captures values from its lexical context, we get a LambdaConversionError
ava.lang.BootstrapMethodError: call site initialization exception
at java.lang.invoke.CallSite.makeSite(CallSite.java:298)
at java.lang.invoke.MethodHandleNatives.linkCallSite(MethodHandleNatives.java:294)
at lambda.A.make(TestInnerCtorRef.java:55)
at lambda.TestInnerCtorRef.testCtorRef(TestInnerCtorRef.java:40)
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:474)
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.invoke.LambdaConversionException: Incorrect number of parameters for static method newinvokespecial lambda.A$1Local.<init>:(Supplier)void; 0 captured parameters, 0 functional interface parameters, 1 implementation parameters
at java.lang.invoke.AbstractValidatingLambdaMetafactory.validateMetafactoryArgs(AbstractValidatingLambdaMetafactory.java:154)
at java.lang.invoke.LambdaMetafactory.metaFactory(LambdaMetafactory.java:178)
at java.lang.invoke.CallSite.makeSite(CallSite.java:283)
TestNG test case that reproduces the problem:
@Test
public class TestInnerCtorRef {
public void testCtorRef() {
A<String> a = A.make(() -> "");
}
}
abstract class A<T> {
abstract T make();
private A() {
}
public interface Foo<T> { }
public static<T> A<T> make(Supplier<T> factory) {
class Local implements Foo<T> {
Supplier<T> f = factory;
}
return new Helper<T>(Local::new);
}
private static class Helper<T> extends A<T> {
private Helper(Supplier<Foo<T>> factory) {
}
@Override
T make() {
return null;
}
}
}
We pass the following as the implementation MH:
newinvokespecial lambda/A$1Local."<init>":(Ljava/util/function/Supplier;)V
The ctor for A$1Local wants to receive the enclosing instance, but it is not put on the stack when calling the invokedynamic.
Appears to be a javac issue, where we're treating the local class as if it were static, but it is not?
ava.lang.BootstrapMethodError: call site initialization exception
at java.lang.invoke.CallSite.makeSite(CallSite.java:298)
at java.lang.invoke.MethodHandleNatives.linkCallSite(MethodHandleNatives.java:294)
at lambda.A.make(TestInnerCtorRef.java:55)
at lambda.TestInnerCtorRef.testCtorRef(TestInnerCtorRef.java:40)
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:474)
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.invoke.LambdaConversionException: Incorrect number of parameters for static method newinvokespecial lambda.A$1Local.<init>:(Supplier)void; 0 captured parameters, 0 functional interface parameters, 1 implementation parameters
at java.lang.invoke.AbstractValidatingLambdaMetafactory.validateMetafactoryArgs(AbstractValidatingLambdaMetafactory.java:154)
at java.lang.invoke.LambdaMetafactory.metaFactory(LambdaMetafactory.java:178)
at java.lang.invoke.CallSite.makeSite(CallSite.java:283)
TestNG test case that reproduces the problem:
@Test
public class TestInnerCtorRef {
public void testCtorRef() {
A<String> a = A.make(() -> "");
}
}
abstract class A<T> {
abstract T make();
private A() {
}
public interface Foo<T> { }
public static<T> A<T> make(Supplier<T> factory) {
class Local implements Foo<T> {
Supplier<T> f = factory;
}
return new Helper<T>(Local::new);
}
private static class Helper<T> extends A<T> {
private Helper(Supplier<Foo<T>> factory) {
}
@Override
T make() {
return null;
}
}
}
We pass the following as the implementation MH:
newinvokespecial lambda/A$1Local."<init>":(Ljava/util/function/Supplier;)V
The ctor for A$1Local wants to receive the enclosing instance, but it is not put on the stack when calling the invokedynamic.
Appears to be a javac issue, where we're treating the local class as if it were static, but it is not?