Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8005043

Bootstrap method error when converting constructor ref of local class

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Cannot Reproduce
    • Icon: P3 P3
    • 8-repo-lambda
    • None
    • tools
    • 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?

            rfield Robert Field (Inactive)
            briangoetz Brian Goetz
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: