Java 8: Duplicate method name&signature lambda

java, java-8

Solution

Set the system property `jdk.internal.lambda.dumpProxyClasses` to point to a directory on your filesystem. You'll get the bytecode of the synthesized anonymous class `com/test8/Main$$Lambda$1` dumped to that location. Open that class file with `javap` to see what has happened. You should find two declarations of the same method there.

Update

This is the `javap` output produced by the above procedure, when compiled with Eclipse:

final class test.Main$$Lambda$1 implements test.Main$CurryBiConsumer {
  public void accept(java.lang.Object, java.lang.Object);
    Code:
       0: aload_1       
       1: checkcast     #14                 // class java/lang/String
       4: aload_2       
       5: checkcast     #16                 // class java/lang/Integer
       8: invokestatic  #22                 // Method test/Main.lambda$0:(Ljava/lang/String;Ljava/lang/Integer;)V
      11: return        

  public void accept(java.lang.Object, java.lang.Object);
    Code:
       0: aload_1       
       1: checkcast     #14                 // class java/lang/String
       4: aload_2       
       5: checkcast     #16                 // class java/lang/Integer
       8: invokestatic  #22                 // Method test/Main.lambda$0:(Ljava/lang/String;Ljava/lang/Integer;)V
      11: return        
}

And this is how it should be, and what `javac` does:

final class test.Main$$Lambda$1 implements test.Main$CurryBiConsumer {
  public void accept(java.lang.Object, java.lang.Object);
    Code:
       0: aload_1       
       1: checkcast     #14                 // class java/lang/String
       4: aload_2       
       5: checkcast     #16                 // class java/lang/Integer
       8: invokevirtual #20                 // Method java/lang/Integer.intValue:()I
      11: invokestatic  #26                 // Method test/Main.display:(Ljava/lang/String;I)V
      14: return        
}

Conclusion: this is an issue with the Eclipse JDT compiler. Someone should report it :)

Update

As of Eclipse Luna this bug has been fixed.

Problem

I was playing around with Java 8 lambdas, method references and interface default methods to explore the wonderful world of currying, and then I got this Java error I cannot understand. Here is the code : ``` public class Main { public interface CurryBiConsumer<T, U> extends BiConsumer<T, U> { default public CurryConsumer<U> curryFirst(T t) { return (u) -> accept(t, u); } default public CurryConsumer<T> currySecond(U u) { return (t) -> accept(t, u); } } public interface CurryConsumer<T> extends Consumer<T> { default public Runnable curry(T t) { return () -> accept(t); } } static void execute(Runnable r) { System.out.println("BEFORE"); r.run(); System.out.println("AFTER"); } static void display(String str, int count) { System.out.println("DISP: " + str + " " + count); } public static void main(String[] args) { CurryBiConsumer<String, Integer> bc = Main::display; execute(bc.curryFirst("Salomon").curry(42)); } } ``` Eclipse gives me no error but when I run it, I get this runtime error : ``` Exception in thread "main" java.lang.BootstrapMethodError: call site initialization exception at java.lang.invoke.CallSite.makeSite(CallSite.java:328) at java.lang.invoke.MethodHandleNatives.linkCallSite(MethodHandleNatives.java:296) at com.test8.Main.main(Main.java:34) Caused by: java.lang.ClassFormatError: Duplicate method name&signature in class file com/test8/Main$$Lambda$1 at sun.misc.Unsafe.defineAnonymousClass(Native Method) at java.lang.invoke.InnerClassLambdaMetafactory.spinInnerClass(InnerClassLambdaMetafactory.java:324) at java.lang.invoke.InnerClassLambdaMetafactory.buildCallSite(InnerClassLambdaMetafactory.java:194) at java.lang.invoke.LambdaMetafactory.altMetafactory(LambdaMetafactory.java:473) at java.lang.invoke.CallSite.makeSite(CallSite.java:301) ... 2 more ``` Can someone explain What is this error, why it is happening and how to get around it ? Thanks :)

Original source

Related problems