Skip to content

java.lang.invoke.LambdaConversionException: Incorrect number of parameters for bridge signature #11373

Closed
@danieldietrich

Description

@danieldietrich

There seems to be a general scala/scalac problem that does occur with Scala 2.12.7+ but not with Scala 2.12.4 for example. I also tested it with Scala 2.13.0-M5.

@2m originally reported it as possible Vavr bug: vavr-io/vavr#2337
I found a minimal example that only depends on standard Java 8 (or above).

// file test/A.java
package test;
public interface A extends B {
    @Override A ap();
    @Override default A test(B b) { return null; }
}
// file test/B.java
package test;
public interface B {
    B ap();
    default B test(B b) { return null; }
}
// file ./Main.scala
object Main {
  def main(args: Array[String]): Unit = {
    val f: test.A = () => null
  }
}

Running it

Tested with Oracle JDK 1.8.0_181

javac -cp . ./test/B.java && javac -cp . ./test/A.java && scalac -d out -classpath . Main.scala && scala -classpath out:. Main

Output

Exception in thread "main" java.lang.BootstrapMethodError: call site initialization exception
        at java.lang.invoke.CallSite.makeSite(CallSite.java:341)
        at java.lang.invoke.MethodHandleNatives.linkCallSiteImpl(MethodHandleNatives.java:307)
        at java.lang.invoke.MethodHandleNatives.linkCallSite(MethodHandleNatives.java:297)
        at Main$.main(Main.scala:3)
        at Main.main(Main.scala)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at scala.reflect.internal.util.ScalaClassLoader.$anonfun$run$2(ScalaClassLoader.scala:99)
        at scala.reflect.internal.util.ScalaClassLoader.asContext(ScalaClassLoader.scala:33)
        at scala.reflect.internal.util.ScalaClassLoader.asContext$(ScalaClassLoader.scala:31)
        at scala.reflect.internal.util.ScalaClassLoader$URLClassLoader.asContext(ScalaClassLoader.scala:130)
        at scala.reflect.internal.util.ScalaClassLoader.run(ScalaClassLoader.scala:99)
        at scala.reflect.internal.util.ScalaClassLoader.run$(ScalaClassLoader.scala:91)
        at scala.reflect.internal.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:130)
        at scala.tools.nsc.CommonRunner.run(ObjectRunner.scala:22)
        at scala.tools.nsc.CommonRunner.run$(ObjectRunner.scala:21)
        at scala.tools.nsc.ObjectRunner$.run(ObjectRunner.scala:37)
        at scala.tools.nsc.CommonRunner.runAndCatch(ObjectRunner.scala:28)
        at scala.tools.nsc.CommonRunner.runAndCatch$(ObjectRunner.scala:27)
        at scala.tools.nsc.ObjectRunner$.runAndCatch(ObjectRunner.scala:37)
        at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:63)
        at scala.tools.nsc.MainGenericRunner.run$1(MainGenericRunner.scala:84)
        at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:95)
        at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:100)
        at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)
Caused by: java.lang.invoke.LambdaConversionException: Incorrect number of parameters for bridge signature (B)B; incompatible with ()A
        at java.lang.invoke.AbstractValidatingLambdaMetafactory.validateMetafactoryArgs(AbstractValidatingLambdaMetafactory.java:206)
        at java.lang.invoke.LambdaMetafactory.altMetafactory(LambdaMetafactory.java:473)
        at java.lang.invoke.CallSite.makeSite(CallSite.java:325)
        ... 26 more

Notes

The example does run properly if we do one of the following modifications:

  1. removing parameter of method test():
public interface A extends B {
    @Override A ap();
    @Override default A test() { return null; }
}
public interface B {
    B ap();
    default B test() { return null; }
}
  1. OR returning the same type B test(B b):
public interface A extends B {
    @Override A ap();
    @Override default B test(B b) { return null; }
}
public interface B {
    B ap();
    default B test(B b) { return null; }
}

Thanks for looking into it!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions