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

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

Open
danieldietrich opened this Issue Jan 19, 2019 · 4 comments

Comments

Projects
None yet
2 participants
@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

This comment has been minimized.

Copy link
Member

adriaanm commented Jan 21, 2019

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

This comment has been minimized.

Copy link
Member

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

This comment has been minimized.

Copy link
Member

adriaanm commented Jan 21, 2019

I proposed a fix scheduled for 2.12.9

@adriaanm adriaanm added this to the 2.12.9 milestone Jan 21, 2019

@danieldietrich

This comment has been minimized.

Copy link
Author

danieldietrich commented Jan 21, 2019

Thx, that was fast!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment