Skip to content
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

'NoSuchMethodError' during runtime when using lambda as ITD field value with binary weaving #200

Open
cts3 opened this issue Dec 12, 2022 · 3 comments
Labels
bug Something isn't working

Comments

@cts3
Copy link

cts3 commented Dec 12, 2022

Thank you for your quick reply.(#199)

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");
    }
}

Originally posted by @cts3 in #199 (comment)

@kriegaex
Copy link
Contributor

kriegaex commented Dec 17, 2022

At first I could not reproduce the problem, because accidentally I compiled the aspect from #199 with the same class name instead of overwriting it by the new version. Now the error reproduces.

Anyway, I have a follow-up question about your somewhat contrived build command with aspectjrt.jar on the inpath instead of the classpath, like it should be. What are you trying to achieve? I can only speculate that you wish to build the core application and an aspect library separately, weaving them together using binary weaving. Or did you put the AspectJ runtime on the inpath in order to create something like a shaded fat JAR? Please explain.

@kriegaex
Copy link
Contributor

One initial finding ist that when compiling aspect and application together from source code, the public static void lambda$0(java.lang.String) exists in Testjava, and the code works as expected. Only when doing binary weaving, the lambda does not end up in the target class.

However, the workaround from #199 (comment), i.e. replacing the lambda by a method reference, also helps.

@kriegaex kriegaex added the bug Something isn't working label Dec 18, 2022
@kriegaex kriegaex changed the title Occur NoSuchMethodError method runtime error with lambda statement 'NoSuchMethodError' runtime error when using lambda as ITD field value Dec 18, 2022
@kriegaex kriegaex changed the title 'NoSuchMethodError' runtime error when using lambda as ITD field value 'NoSuchMethodError' during runtime when using lambda as ITD field value Dec 18, 2022
@kriegaex kriegaex changed the title 'NoSuchMethodError' during runtime when using lambda as ITD field value 'NoSuchMethodError' during runtime when using lambda as ITD field value with binary weaving Dec 18, 2022
@kriegaex
Copy link
Contributor

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)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants