eclipse-aspectj / aspectj

Other
299 stars 86 forks source link

'ClassFormatError: Duplicate method name' during runtime when using lambda as ITD field value #199

Open cts3 opened 1 year ago

cts3 commented 1 year ago

Hi, I want that two statement(variable, method) including lambda was added Testjava class. So after code was written as below code, I compiled code. But when running code, It occur duplicate method runtime error with lambda statement.

There are below error log, source code and build command.

Build environment

java version - openjdk version "1.8.0_292"
aspectj version - 1.9.9.1

Error log of runtime

Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.ClassFormatError: Duplicate method name "lambda$0" with signature "(Ljava.lang.String;)V" in class file Testjava
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:756)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:468)
        at java.net.URLClassLoader.access$100(URLClassLoader.java:74)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:369)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:363)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:362)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:352)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
        at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:601)

Source code Testjava.java

public class Testjava {
  public static void main(String[] argv) {
      Testjava tj = new Testjava();
      tj.testMethod(1);
  }

  void testMethod(int a) {
      System.out.println("call testMethod, " + a);
  }
}

TestjavaAO.aj

import java.util.function.Consumer;

privileged aspect TestjavaAO {
    private Consumer<String> Testjava.sConsumer2 = task -> { System.out.println("call sConsumer2 " + task); };

    private void Testjava.assignLambda() {
        Consumer<String> consumer = (String task) -> { System.out.println("call Testjava.assignLambda"); };
        consumer.accept("hello world");
    }

    void logAll() {
        Consumer<String> sConsumer1 = (String task) -> { System.out.println("call logAll"); };
        sConsumer1.accept("hello world");
    }

    void around(Testjava tj, int a):
            execution(* Testjava.testMethod(int)) &&
            within(Testjava) &&
            this(tj) && args(a) {
        proceed(tj, a+1);
        logAll();
        tj.assignLambda();
        tj.sConsumer2.accept("test");
    }
}

build command

$ bin/ajc -inpath lib/aspectjrt.jar Testjava.java TestjavaAO.aj -outjar test.jar -showWeaveInfo -1.8
kriegaex commented 1 year ago

Thanks for raising this issue. It really looks like a bug to me at first glance. Like I just said in another issue: Andy as a project lead is basically inactive due to his daytime job. All things related to byte code generation are not my strong suit anyway, so usually I am reluctant to touch that stuff. But I might be able to at least take a look during holiday season, using your reproducer to guide me to the root cause. But that something is wrong with the byte code becomes clear when using javap:

$ javap -v bin\Testjava.class

Classfile /C:/Users/Alexander/Documents/java-src/AJ_GH_199_DuplicateMethodErrorLambda/bin/Testjava.class
  Last modified 10.12.2022; size 4205 bytes
  SHA-256 checksum 058ba8cc7573df88330269352aaa19c829a53bc3ae6163fe04ab6971676e7da4
  Compiled from "Testjava.java"
public class Testjava
  minor version: 0
  major version: 52
  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
  this_class: #1                          // Testjava
  super_class: #3                         // java/lang/Object
  interfaces: 0, fields: 1, methods: 10, attributes: 3
Constant pool:
    #1 = Class              #2            // Testjava
    #2 = Utf8               Testjava
    #3 = Class              #4            // java/lang/Object
    #4 = Utf8               java/lang/Object
    #5 = Utf8               <init>
    #6 = Utf8               ()V
    #7 = Utf8               Code
    #8 = Methodref          #3.#9         // java/lang/Object."<init>":()V
    #9 = NameAndType        #5:#6         // "<init>":()V
   #10 = Utf8               LineNumberTable
   #11 = Utf8               LocalVariableTable
   #12 = Utf8               this
   #13 = Utf8               LTestjava;
   #14 = Utf8               main
   #15 = Utf8               ([Ljava/lang/String;)V
   #16 = Utf8               org.aspectj.weaver.MethodDeclarationLineNumber
   #17 = Methodref          #1.#9         // Testjava."<init>":()V
   #18 = Methodref          #1.#19        // Testjava.testMethod:(I)V
   #19 = NameAndType        #20:#21       // testMethod:(I)V
   #20 = Utf8               testMethod
   #21 = Utf8               (I)V
   #22 = Utf8               argv
   #23 = Utf8               [Ljava/lang/String;
   #24 = Utf8               tj
   #25 = Fieldref           #26.#28       // java/lang/System.out:Ljava/io/PrintStream;
   #26 = Class              #27           // java/lang/System
   #27 = Utf8               java/lang/System
   #28 = NameAndType        #29:#30       // out:Ljava/io/PrintStream;
   #29 = Utf8               out
   #30 = Utf8               Ljava/io/PrintStream;
   #31 = Class              #32           // java/lang/StringBuilder
   #32 = Utf8               java/lang/StringBuilder
   #33 = String             #34           // call testMethod,
   #34 = Utf8               call testMethod,
   #35 = Methodref          #31.#36       // java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
   #36 = NameAndType        #5:#37        // "<init>":(Ljava/lang/String;)V
   #37 = Utf8               (Ljava/lang/String;)V
   #38 = Methodref          #31.#39       // java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
   #39 = NameAndType        #40:#41       // append:(I)Ljava/lang/StringBuilder;
   #40 = Utf8               append
   #41 = Utf8               (I)Ljava/lang/StringBuilder;
   #42 = Methodref          #31.#43       // java/lang/StringBuilder.toString:()Ljava/lang/String;
   #43 = NameAndType        #44:#45       // toString:()Ljava/lang/String;
   #44 = Utf8               toString
   #45 = Utf8               ()Ljava/lang/String;
   #46 = Methodref          #47.#49       // java/io/PrintStream.println:(Ljava/lang/String;)V
   #47 = Class              #48           // java/io/PrintStream
   #48 = Utf8               java/io/PrintStream
   #49 = NameAndType        #50:#37       // println:(Ljava/lang/String;)V
   #50 = Utf8               println
   #51 = Utf8               a
   #52 = Utf8               I
   #53 = Utf8               lambda$0
   #54 = String             #55           // call sConsumer2
   #55 = Utf8               call sConsumer2
   #56 = Methodref          #31.#57       // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   #57 = NameAndType        #40:#58       // append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   #58 = Utf8               (Ljava/lang/String;)Ljava/lang/StringBuilder;
   #59 = Utf8               task
   #60 = Utf8               Ljava/lang/String;
   #61 = String             #62           // call Testjava.assignLambda
   #62 = Utf8               call Testjava.assignLambda
   #63 = Utf8               SourceFile
   #64 = Utf8               Testjava.java
   #65 = Utf8               Signature
   #66 = Utf8               Ljava/util/function/Consumer<Ljava/lang/String;>;
   #67 = Utf8               sConsumer2
   #68 = Utf8               Ljava/util/function/Consumer;
   #69 = Utf8               ajc$interMethod$TestjavaAO$Testjava$assignLambda
   #70 = Utf8               (LTestjava;)V
   #71 = NameAndType        #69:#70       // ajc$interMethod$TestjavaAO$Testjava$assignLambda:(LTestjava;)V
   #72 = Utf8               TestjavaAO
   #73 = Class              #72           // TestjavaAO
   #74 = Methodref          #73.#71       // TestjavaAO.ajc$interMethod$TestjavaAO$Testjava$assignLambda:(LTestjava;)V
   #75 = Utf8               Synthetic
   #76 = Utf8               ajc$interMethodDispatch2$TestjavaAO$assignLambda
   #77 = NameAndType        #67:#68       // sConsumer2:Ljava/util/function/Consumer;
   #78 = Fieldref           #1.#77        // Testjava.sConsumer2:Ljava/util/function/Consumer;
   #79 = Utf8               ajc$get$sConsumer2
   #80 = Utf8               (LTestjava;)Ljava/util/function/Consumer;
   #81 = Utf8               ajc$set$sConsumer2
   #82 = Utf8               (LTestjava;Ljava/util/function/Consumer;)V
   #83 = Utf8               ajc$interFieldInit$TestjavaAO$Testjava$sConsumer2
   #84 = NameAndType        #83:#70       // ajc$interFieldInit$TestjavaAO$Testjava$sConsumer2:(LTestjava;)V
   #85 = Methodref          #73.#84       // TestjavaAO.ajc$interFieldInit$TestjavaAO$Testjava$sConsumer2:(LTestjava;)V
   #86 = Utf8               testMethod_aroundBody0
   #87 = Utf8               (LTestjava;I)V
   #88 = Utf8               ajc$this
   #89 = Utf8               ajc$around$TestjavaAO$1$1a78e94dproceed
   #90 = Utf8               (LTestjava;ILorg/aspectj/runtime/internal/AroundClosure;)V
   #91 = NameAndType        #89:#90       // ajc$around$TestjavaAO$1$1a78e94dproceed:(LTestjava;ILorg/aspectj/runtime/internal/AroundClosure;)V
   #92 = Methodref          #73.#91       // TestjavaAO.ajc$around$TestjavaAO$1$1a78e94dproceed:(LTestjava;ILorg/aspectj/runtime/internal/AroundClosure;)V
   #93 = Utf8               ajc$inlineAccessMethod$TestjavaAO$TestjavaAO$logAll
   #94 = Utf8               (LTestjavaAO;)V
   #95 = NameAndType        #93:#94       // ajc$inlineAccessMethod$TestjavaAO$TestjavaAO$logAll:(LTestjavaAO;)V
   #96 = Methodref          #73.#95       // TestjavaAO.ajc$inlineAccessMethod$TestjavaAO$TestjavaAO$logAll:(LTestjavaAO;)V
   #97 = Utf8               ajc$interMethodDispatch1$TestjavaAO$Testjava$assignLambda
   #98 = NameAndType        #97:#70       // ajc$interMethodDispatch1$TestjavaAO$Testjava$assignLambda:(LTestjava;)V
   #99 = Methodref          #73.#98       // TestjavaAO.ajc$interMethodDispatch1$TestjavaAO$Testjava$assignLambda:(LTestjava;)V
  #100 = Utf8               ajc$interFieldGetDispatch$TestjavaAO$Testjava$sConsumer2
  #101 = NameAndType        #100:#80      // ajc$interFieldGetDispatch$TestjavaAO$Testjava$sConsumer2:(LTestjava;)Ljava/util/function/Consumer;
  #102 = Methodref          #73.#101      // TestjavaAO.ajc$interFieldGetDispatch$TestjavaAO$Testjava$sConsumer2:(LTestjava;)Ljava/util/function/Consumer;
  #103 = Utf8               test
  #104 = String             #103          // test
  #105 = Utf8               java/util/function/Consumer
  #106 = Class              #105          // java/util/function/Consumer
  #107 = Utf8               accept
  #108 = Utf8               (Ljava/lang/Object;)V
  #109 = NameAndType        #107:#108     // accept:(Ljava/lang/Object;)V
  #110 = InterfaceMethodref #106.#109     // java/util/function/Consumer.accept:(Ljava/lang/Object;)V
  #111 = Utf8               aspectOf
  #112 = Utf8               ()LTestjavaAO;
  #113 = NameAndType        #111:#112     // aspectOf:()LTestjavaAO;
  #114 = Methodref          #73.#113      // TestjavaAO.aspectOf:()LTestjavaAO;
  #115 = Utf8               testMethod_aroundBody1$advice
  #116 = Utf8               (LTestjava;ILTestjavaAO;LTestjava;ILorg/aspectj/runtime/internal/AroundClosure;)V
  #117 = NameAndType        #115:#116     // testMethod_aroundBody1$advice:(LTestjava;ILTestjavaAO;LTestjava;ILorg/aspectj/runtime/internal/AroundClosure;)V
  #118 = Methodref          #1.#117       // Testjava.testMethod_aroundBody1$advice:(LTestjava;ILTestjavaAO;LTestjava;ILorg/aspectj/runtime/internal/AroundClosure;)V
  #119 = NameAndType        #86:#87       // testMethod_aroundBody0:(LTestjava;I)V
  #120 = Methodref          #1.#119       // Testjava.testMethod_aroundBody0:(LTestjava;I)V
  #121 = Utf8               org.aspectj.weaver.WeaverVersion
  #122 = Utf8               org.aspectj.weaver.WeaverState
  #123 = Utf8               ajc$aspectInstance
  #124 = Utf8               LTestjavaAO;
  #125 = Utf8               ajc$aroundClosure
  #126 = Utf8               Lorg/aspectj/runtime/internal/AroundClosure;
{
  public Testjava();
    descriptor: ()V
    flags: (0x0001) ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #8                  // Method java/lang/Object."<init>":()V
         4: aload_0
         5: invokestatic  #85                 // Method TestjavaAO.ajc$interFieldInit$TestjavaAO$Testjava$sConsumer2:(LTestjava;)V
         8: return
      LineNumberTable:
        line 1: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       9     0  this   LTestjava;

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=2, args_size=1
         0: new           #1                  // class Testjava
         3: dup
         4: invokespecial #17                 // Method "<init>":()V
         7: astore_1
         8: aload_1
         9: iconst_1
        10: invokevirtual #18                 // Method testMethod:(I)V
        13: return
      LineNumberTable:
        line 3: 0
        line 4: 8
        line 5: 13
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      14     0  argv   [Ljava/lang/String;
            8       6     1    tj   LTestjava;
      org.aspectj.weaver.MethodDeclarationLineNumber: length = 0x8 (unknown attribute)
       00 00 00 02 00 00 00 2D

  void testMethod(int);
    descriptor: (I)V
    flags: (0x0000)
    Code:
      stack=6, locals=3, args_size=2
         0: iload_1
         1: istore_2
         2: aload_0
         3: iload_2
         4: invokestatic  #114                // Method TestjavaAO.aspectOf:()LTestjavaAO;
         7: aload_0
         8: iload_2
         9: aconst_null
        10: invokestatic  #118                // Method testMethod_aroundBody1$advice:(LTestjava;ILTestjavaAO;LTestjava;ILorg/aspectj/runtime/internal/AroundClosure;)V
        13: return
      LineNumberTable:
        line 1: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      14     0  this   LTestjava;
            0      14     1     a   I
      org.aspectj.weaver.MethodDeclarationLineNumber: length = 0x8 (unknown attribute)
       00 00 00 07 00 00 00 87

  public static void lambda$0(java.lang.String);
    descriptor: (Ljava/lang/String;)V
    flags: (0x1009) ACC_PUBLIC, ACC_STATIC, ACC_SYNTHETIC
    Code:
      stack=4, locals=1, args_size=1
         0: getstatic     #25                 // Field java/lang/System.out:Ljava/io/PrintStream;
         3: new           #31                 // class java/lang/StringBuilder
         6: dup
         7: ldc           #54                 // String call sConsumer2
         9: invokespecial #35                 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
        12: aload_0
        13: invokevirtual #56                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        16: invokevirtual #42                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
        19: invokevirtual #46                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        22: return
      LineNumberTable:
        line 7: 0
        line 8: 12
        line 7: 19
        line 8: 22
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      23     0  task   Ljava/lang/String;

  public static void lambda$0(java.lang.String);
    descriptor: (Ljava/lang/String;)V
    flags: (0x1009) ACC_PUBLIC, ACC_STATIC, ACC_SYNTHETIC
    Code:
      stack=2, locals=1, args_size=1
         0: getstatic     #25                 // Field java/lang/System.out:Ljava/io/PrintStream;
         3: ldc           #61                 // String call Testjava.assignLambda
         5: invokevirtual #46                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
         8: return
      LineNumberTable:
        line 11: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       9     0  task   Ljava/lang/String;

  public static java.util.function.Consumer ajc$get$sConsumer2(Testjava);
    descriptor: (LTestjava;)Ljava/util/function/Consumer;
    flags: (0x1009) ACC_PUBLIC, ACC_STATIC, ACC_SYNTHETIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: getfield      #78                 // Field sConsumer2:Ljava/util/function/Consumer;
         4: areturn
      LineNumberTable:
        line 1: 0

  public static void ajc$set$sConsumer2(Testjava, java.util.function.Consumer);
    descriptor: (LTestjava;Ljava/util/function/Consumer;)V
    flags: (0x1009) ACC_PUBLIC, ACC_STATIC, ACC_SYNTHETIC
    Code:
      stack=2, locals=2, args_size=2
         0: aload_0
         1: aload_1
         2: putfield      #78                 // Field sConsumer2:Ljava/util/function/Consumer;
         5: return
      LineNumberTable:
        line 1: 0

  public void ajc$interMethodDispatch2$TestjavaAO$assignLambda();
    descriptor: ()V
    flags: (0x1001) ACC_PUBLIC, ACC_SYNTHETIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokestatic  #74                 // Method TestjavaAO.ajc$interMethod$TestjavaAO$Testjava$assignLambda:(LTestjava;)V
         4: return
      LineNumberTable:
        line 1: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   LTestjava;
}
SourceFile: "Testjava.java"
  org.aspectj.weaver.WeaverVersion: length = 0xC (unknown attribute)
   00 07 00 00 00 00 00 00 00 00 00 00
  org.aspectj.weaver.WeaverState: length = 0x4FB (unknown attribute)
   53 00 00 02 00 0C 4C 54 65 73 74 6A 61 76 61 41
   4F 3B 01 02 00 00 0A 4C 54 65 73 74 6A 61 76 61
   3B 00 00 00 02 00 0A 73 43 6F 6E 73 75 6D 65 72
   32 00 1D 4C 6A 61 76 61 2F 75 74 69 6C 2F 66 75
   6E 63 74 69 6F 6E 2F 43 6F 6E 73 75 6D 65 72 3B
   00 00 00 00 00 68 00 00 00 71 00 00 00 00 31 50
   6A 61 76 61 2F 75 74 69 6C 2F 66 75 6E 63 74 69
   6F 6E 2F 43 6F 6E 73 75 6D 65 72 3C 4C 6A 61 76
   61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 3E 3B
   00 00 AC ED 00 05 73 72 00 11 6A 61 76 61 2E 6C
   61 6E 67 2E 42 6F 6F 6C 65 61 6E CD 20 72 80 D5
   9C FA EE 02 00 01 5A 00 05 76 61 6C 75 65 78 70
   01 73 72 00 0C 6A 61 76 61 2E 69 6F 2E 46 69 6C
   65 04 2D A4 45 0E 0D E4 FF 03 00 01 4C 00 04 70
   61 74 68 74 00 12 4C 6A 61 76 61 2F 6C 61 6E 67
   2F 53 74 72 69 6E 67 3B 78 70 74 00 5C 43 3A 5C
   55 73 65 72 73 5C 41 6C 65 78 61 6E 64 65 72 5C
   44 6F 63 75 6D 65 6E 74 73 5C 6A 61 76 61 2D 73
   72 63 5C 41 4A 5F 47 48 5F 31 39 39 5F 44 75 70
   6C 69 63 61 74 65 4D 65 74 68 6F 64 45 72 72 6F
   72 4C 61 6D 62 64 61 5C 73 72 63 5C 54 65 73 74
   6A 61 76 61 41 4F 2E 61 6A 77 02 00 5C 78 73 72
   00 11 6A 61 76 61 2E 6C 61 6E 67 2E 49 6E 74 65
   67 65 72 12 E2 A0 A4 F7 81 87 38 02 00 01 49 00
   05 76 61 6C 75 65 78 72 00 10 6A 61 76 61 2E 6C
   61 6E 67 2E 4E 75 6D 62 65 72 86 AC 95 1D 0B 94
   E0 8B 02 00 00 78 70 00 00 00 04 73 71 00 7E 00
   06 00 00 00 68 00 00 00 00 02 00 0C 4C 54 65 73
   74 6A 61 76 61 41 4F 3B 02 01 00 00 0A 4C 54 65
   73 74 6A 61 76 61 3B 00 00 00 02 00 0C 61 73 73
   69 67 6E 4C 61 6D 62 64 61 00 03 28 29 56 00 00
   00 00 00 D0 00 00 00 DD 00 00 FF 00 00 AC ED 00
   05 73 72 00 11 6A 61 76 61 2E 6C 61 6E 67 2E 42
   6F 6F 6C 65 61 6E CD 20 72 80 D5 9C FA EE 02 00
   01 5A 00 05 76 61 6C 75 65 78 70 01 73 72 00 0C
   6A 61 76 61 2E 69 6F 2E 46 69 6C 65 04 2D A4 45
   0E 0D E4 FF 03 00 01 4C 00 04 70 61 74 68 74 00
   12 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69
   6E 67 3B 78 70 74 00 5C 43 3A 5C 55 73 65 72 73
   5C 41 6C 65 78 61 6E 64 65 72 5C 44 6F 63 75 6D
   65 6E 74 73 5C 6A 61 76 61 2D 73 72 63 5C 41 4A
   5F 47 48 5F 31 39 39 5F 44 75 70 6C 69 63 61 74
   65 4D 65 74 68 6F 64 45 72 72 6F 72 4C 61 6D 62
   64 61 5C 73 72 63 5C 54 65 73 74 6A 61 76 61 41
   4F 2E 61 6A 77 02 00 5C 78 73 72 00 11 6A 61 76
   61 2E 6C 61 6E 67 2E 49 6E 74 65 67 65 72 12 E2
   A0 A4 F7 81 87 38 02 00 01 49 00 05 76 61 6C 75
   65 78 72 00 10 6A 61 76 61 2E 6C 61 6E 67 2E 4E
   75 6D 62 65 72 86 AC 95 1D 0B 94 E0 8B 02 00 00
   78 70 00 00 00 08 73 71 00 7E 00 06 00 00 00 D0
   00 00 01 00 0C 4C 54 65 73 74 6A 61 76 61 41 4F
   3B 00 00 01 C6 00 41 00 00 02 F0 00 21 00 01 00
   03 00 00 00 00 00 05 00 01 00 05 00 06 00 01 00
   07 00 00 00 2F 00 01 00 01 00 00 00 05 2A B7 00
   08 B1 00 00 00 02 00 0A 00 00 00 06 00 01 00 00
   00 01 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C
   00 0D 00 00 00 09 00 0E 00 0F 00 02 00 10 00 00
   00 08 00 00 00 02 00 00 00 2D 00 07 00 00 00 4A
   00 02 00 02 00 00 00 0E BB 00 01 59 B7 00 11 4C
   2B 04 B6 00 12 B1 00 00 00 02 00 0A 00 00 00 0E
   00 03 00 00 00 03 00 08 00 04 00 0D 00 05 00 0B
   00 00 00 16 00 02 00 00 00 0E 00 16 00 17 00 00
   00 08 00 06 00 18 00 0D 00 01 00 00 00 14 00 15
   00 02 00 10 00 00 00 08 00 00 00 07 00 00 00 87
   00 07 00 00 00 4F 00 04 00 02 00 00 00 17 B2 00
   19 BB 00 1F 59 12 21 B7 00 23 1B B6 00 26 B6 00
   2A B6 00 2E B1 00 00 00 02 00 0A 00 00 00 0A 00
   02 00 00 00 08 00 16 00 09 00 0B 00 00 00 16 00
   02 00 00 00 17 00 0C 00 0D 00 00 00 00 00 17 00
   33 00 34 00 01 10 09 00 35 00 25 00 01 00 07 00
   00 00 4D 00 04 00 01 00 00 00 17 B2 00 19 BB 00
   1F 59 12 36 B7 00 23 2A B6 00 38 B6 00 2A B6 00
   2E B1 00 00 00 02 00 0A 00 00 00 12 00 04 00 00
   00 07 00 0C 00 08 00 13 00 07 00 16 00 08 00 0B
   00 00 00 0C 00 01 00 00 00 17 00 3B 00 3C 00 00
   10 09 00 35 00 25 00 01 00 07 00 00 00 33 00 02
   00 01 00 00 00 09 B2 00 19 12 3D B6 00 2E B1 00
   00 00 02 00 0A 00 00 00 06 00 01 00 00 00 0B 00
   0B 00 00 00 0C 00 01 00 00 00 09 00 3B 00 3C 00
   00 00 01 00 3F 00 00 00 02 00 40

There we find:

  public static void lambda$0(java.lang.String);
    descriptor: (Ljava/lang/String;)V
    flags: (0x1009) ACC_PUBLIC, ACC_STATIC, ACC_SYNTHETIC
    Code:
      stack=4, locals=1, args_size=1
         0: getstatic     #25                 // Field java/lang/System.out:Ljava/io/PrintStream;
         3: new           #31                 // class java/lang/StringBuilder
         6: dup
         7: ldc           #54                 // String call sConsumer2
         9: invokespecial #35                 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
        12: aload_0
        13: invokevirtual #56                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        16: invokevirtual #42                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
        19: invokevirtual #46                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        22: return
      LineNumberTable:
        line 7: 0
        line 8: 12
        line 7: 19
        line 8: 22
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      23     0  task   Ljava/lang/String;

  public static void lambda$0(java.lang.String);
    descriptor: (Ljava/lang/String;)V
    flags: (0x1009) ACC_PUBLIC, ACC_STATIC, ACC_SYNTHETIC
    Code:
      stack=2, locals=1, args_size=1
         0: getstatic     #25                 // Field java/lang/System.out:Ljava/io/PrintStream;
         3: ldc           #61                 // String call Testjava.assignLambda
         5: invokevirtual #46                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
         8: return
      LineNumberTable:
        line 11: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       9     0  task   Ljava/lang/String;

Uh-oh! Maybe they should not be named the same. @aclement, where would you start looking in order to fix this?

kriegaex commented 1 year ago

For now, you can refactor the first lambda into a method reference as a workaround:

  private Consumer<String> Testjava.sConsumer2 = TestjavaAO::accept;

  private static void accept(String task) {
    System.out.println("call sConsumer2 " + task);
  }

Then the code runs fine:

call testMethod, 2
call logAll
call Testjava.assignLambda
call sConsumer2 test

That is, of course, not a solution forever, but at least you can continue to work.

cts3 commented 1 year ago

Thank you for your quick reply.

It seems to be a similar problem, please check below error. Below case(test_jar + Testjava.aj = test.jar), It occur error that not generated lambda$0 in Testjava.class.

execute & error log

$ java -cp test.jar Testjava
Picked up _JAVA_OPTIONS: -Xmx4000m
Exception in thread "main" java.lang.BootstrapMethodError: java.lang.NoSuchMethodError: Testjava.lambda$0(Ljava/lang/String;)V
        at TestjavaAO.ajc$interFieldInit$TestjavaAO$Testjava$sConsumer2(TestjavaAO.aj:4)
        at Testjava.<init>(Testjava.java:1)
        at Testjava.main(Testjava.java:3)
Caused by: java.lang.NoSuchMethodError: Testjava.lambda$0(Ljava/lang/String;)V
        at java.lang.invoke.MethodHandleNatives.resolve(Native Method)
        at java.lang.invoke.MemberName$Factory.resolve(MemberName.java:975)
        at java.lang.invoke.MemberName$Factory.resolveOrFail(MemberName.java:1000)
        at java.lang.invoke.MethodHandles$Lookup.resolveOrFail(MethodHandles.java:1394)
        at java.lang.invoke.MethodHandles$Lookup.linkMethodHandleConstant(MethodHandles.java:1750)
        at java.lang.invoke.MethodHandleNatives.linkMethodHandleConstant(MethodHandleNatives.java:477)
        ... 3 more

build command

test_.jar
    $ bin/ajc -inpath lib/aspectjrt.jar Testjava.java -outjar test_.jar -showWeaveInfo -1.8

test.jar
    $ bin/ajc -classpath lib/aspectjrt.jar -inpath test_.jar TestjavaAO.aj -outjar test.jar -showWeaveInfo -1.8

source code Testjava.java

public class Testjava {
  public static void main(String[] argv) {
      Testjava tj = new Testjava();
      tj.testMethod(1);
  }

  void testMethod(int a) {
      System.out.println("call testMethod, " + a);
  }
}

TestjavaAO.aj

import java.util.function.Consumer;

privileged aspect TestjavaAO {
    private Consumer<String> Testjava.sConsumer2 = (String task) -> { System.out.println("call logAll"); };

    void logAll() {
        Consumer<String> sConsumer1 = (String task) -> { System.out.println("call logAll"); };
        sConsumer1.accept("hello world");
    }

    void around(Testjava tj, int a):
            execution(* Testjava.testMethod(int)) &&
            within(Testjava) &&
            target(tj) && args(a) {
        proceed(tj, a+1);
        logAll();
        //tj.assignLambda();
        tj.sConsumer2.accept("test");
    }
}
kriegaex commented 1 year ago

This is not a support channel, but a bug and feature request tracker. The bug has not been fixed yet, so I am reopening it. The suggested workaround does not fix the problem.

kriegaex commented 1 year ago

gh-199-200.zip contains reproducers for both #199 and #200. Unpack into an empty directory and run with Git Bash:

$ ./reproduce-gh-199.sh
Compiling and weaving application + aspect
Type 'Testjava' (Testjava.java) has intertyped field from 'TestjavaAO' (TestjavaAO.aj:'java.util.function.Consumer<java.lang.String> Testjava.sConsumer2')

Type 'Testjava' (Testjava.java) has intertyped method from 'TestjavaAO' (TestjavaAO.aj:'void Testjava.assignLambda()')

Join point 'method-execution(void Testjava.testMethod(int))' in Type 'Testjava' (Testjava.java:7) advised by around advice from 'TestjavaAO' (TestjavaAO.aj:24)

Running woven application
Fehler: Beim Laden der Klasse Testjava ist ein LinkageError aufgetreten
        java.lang.ClassFormatError: Duplicate method name "lambda$0" with signature "(Ljava.lang.String;)V" in class file Testjava

$ ./reproduce-gh-200.sh
Compiling application
Compiling aspect and binary-weaving application
Type 'Testjava' (Testjava.java) has intertyped field from 'TestjavaAO2' (TestjavaAO2.aj:'java.util.function.Consumer<java.lang.String> Testjava.sConsumer3')

Join point 'method-execution(void Testjava.testMethod(int))' in Type 'Testjava' (Testjava.java:7) advised by around advice from 'TestjavaAO2' (TestjavaAO2.aj:19)

Running woven application
Exception in thread "main" java.lang.NoSuchMethodError: 'void Testjava.lambda$0(java.lang.String)'
        at TestjavaAO2.ajc$interFieldInit$TestjavaAO2$Testjava$sConsumer3(TestjavaAO2.aj:8)
        at Testjava.<init>(Testjava.java:1)
        at Testjava.main(Testjava.java:3)
aclement commented 1 year ago

I'd first look at where the names are generated for lambdas - why is the second one not getting a 1 suffix. I don't recall where that is done though. My quick thought is whether it is because the intertype scope in use for ITDs is somehow hiding the counter from the parent scope?

kriegaex commented 1 year ago

@aclement: Sure, that is what I also thought. But I do not know where to find that part of the code, and debugging without knowing where to start looking can take a lot of time. We discussed my wish to get a proper introduction to the code base from you many times before. I am still waiting for that. At least pointers into the right direction would be better than nothing for the time being. Thank you.