Java 8: имя и подпись повторяющегося метода lambda

Я играл с Java 8 lambdas, ссылки на методы и методы интерфейса по умолчанию, чтобы исследовать чудесный мир currying, а затем я получил эту ошибку Java, которую я не могу понять.

Вот код:

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 не дает мне никакой ошибки, но когда я запускаю ее, я получаю эту ошибку времени выполнения:

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

Может кто-нибудь объяснить, что это за ошибка, почему это происходит и как обойти это?

Спасибо:)

Ответ 1

Задайте системное свойство jdk.internal.lambda.dumpProxyClasses, чтобы указать каталог вашей файловой системы. Вы получите байт-код синтезированного анонимного класса com/test8/Main$$Lambda$1, сбрасываемого в это место. Откройте этот файл класса с помощью javap, чтобы узнать, что произошло. Вы должны найти там два объявления того же метода.

Update

Это результат javap, созданный описанной выше процедурой, когда скомпилирован с 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        
}

И так должно быть, и что javac делает:

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        
}

Заключение: это проблема с компилятором Eclipse JDT. Кто-то должен сообщить об этом:)

Update

Как и Eclipse Luna, эта ошибка исправлена.