Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
danieldietrich opened this issue Jan 19, 2019 · 5 comments
Milestone

Comments

@danieldietrich
Copy link

danieldietrich commented Jan 19, 2019

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!

@adriaanm
Copy link
Contributor

Interesting! Playing around with the repro, trying to minimise a bit more still:

public interface Fun0 {
    String ap();

    default Fun0 test(Fun0 b) { return null; }
}

public interface Fun0Impl extends Fun0 {
    default Fun0Impl test(Fun0 b) { return null; }
}
object Test extends App {
  (() => null): Fun0Impl
}

@adriaanm
Copy link
Contributor

adriaanm commented Jan 21, 2019

Looks like the linked PR regressed here. The log says

[log delambdafy] will add SAM bridges for (() => Test.this.$anonfun$f$1()): List(method test)
<snip>
Caused by: java.lang.invoke.LambdaConversionException: Incorrect number of parameters for bridge signature (Fun0)Fun0; incompatible with ()String
	at java.lang.invoke.AbstractValidatingLambdaMetafactory.validateMetafactoryArgs(AbstractValidatingLambdaMetafactory.java:206)

the sam bridges are only intended for bridges for the actual sam method, whereas here test needs a bridge, which AbstractValidatingLambdaMetafactory is unprepared for

@adriaanm
Copy link
Contributor

I proposed a fix scheduled for 2.12.9

@adriaanm adriaanm added this to the 2.12.9 milestone Jan 21, 2019
@danieldietrich
Copy link
Author

Thx, that was fast!

@lrytz
Copy link
Member

lrytz commented Jul 17, 2019

Fixed in scala/scala#7668

@lrytz lrytz closed this as completed Jul 17, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants