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

JaCoCo 0.8.4 and Java 11 Agent Conflict #68

Closed
vladimir-mhl opened this issue Jun 8, 2021 · 16 comments
Closed

JaCoCo 0.8.4 and Java 11 Agent Conflict #68

vladimir-mhl opened this issue Jun 8, 2021 · 16 comments
Labels
bug Something isn't working
Milestone

Comments

@vladimir-mhl
Copy link

This is copy of https://bugs.eclipse.org/bugs/show_bug.cgi?id=549438

Matthew Pearsall CLA Friend 2019-07-20 07:55:16 EDT

See https://github.com/jacoco/jacoco/issues/909

After updating to JDK 11 the Maven Surefire plugin fails to run when both Jacoco agent and AspectJ weaver agent present.

Steps to reproduce

JaCoCo version: 0.8.4
Operating system: Windows 10
JDK: open-jdk-11.0.1
Tool integration: Maven
aspectjweaver: 1.9.4

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>${maven-surefire-plugin.version}</version>
    <configuration>
        <argLine>
            @{argLine} -javaagent:${user.home}/.m2/repository/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar
        </argLine>
        <trimStackTrace>false</trimStackTrace>
    </configuration>
</plugin>
<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.8.4</version>
    <configuration>
        <skip>false</skip>
        <includes>
            ...
        </includes>
        <excludes>
            ...
        </excludes>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>prepare-agent</goal>
            </goals>
        </execution>
        <execution>
            <id>report</id>
            <phase>prepare-package</phase>
            <goals>
                <goal>report</goal>
            </goals>
        </execution>
    </executions>
</plugin>
Expected behaviour

Tests to run as they did in JDK 8.

Actual behaviour

[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
AspectJ Internal Error: unable to add stackmap attributes. null
[INFO] 
[INFO] Results:
[INFO] 
[INFO] Tests run: 0, Failures: 0, Errors: 0, Skipped: 0
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 30.903 s
[INFO] Finished at: 2019-07-19T15:04:42+01:00
[INFO] Final Memory: 79M/280M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.22.2:test (default-test) on project ***: There are test failures.
[ERROR] 
[ERROR] Please refer to C:\Users\#\IdeaProjects\#\services\target\surefire-reports for the individual test results.
[ERROR] Please refer to dump files (if any exist) [date].dump, [date]-jvmRun[N].dump and [date].dumpstream.
[ERROR] There was an error in the forked process
[ERROR] Method "$jacocoData" in class #/function/bank/BankFeedRuleFunctionTest has illegal signature "Ljava/lang/Object;"
[ERROR] org.apache.maven.surefire.booter.SurefireBooterForkException: There was an error in the forked process
[ERROR] Method "$jacocoData" in class #/function/bank/BankFeedRuleFunctionTest has illegal signature "Ljava/lang/Object;"
[ERROR] at org.apache.maven.plugin.surefire.booterclient.ForkStarter.fork(ForkStarter.java:656)
[ERROR] at org.apache.maven.plugin.surefire.booterclient.ForkStarter.run(ForkStarter.java:282)
[ERROR] at org.apache.maven.plugin.surefire.booterclient.ForkStarter.run(ForkStarter.java:245)
[ERROR] at org.apache.maven.plugin.surefire.AbstractSurefireMojo.executeProvider(AbstractSurefireMojo.java:1183)
[ERROR] at org.apache.maven.plugin.surefire.AbstractSurefireMojo.executeAfterPreconditionsChecked(AbstractSurefireMojo.java:1011)
[ERROR] at org.apache.maven.plugin.surefire.AbstractSurefireMojo.execute(AbstractSurefireMojo.java:857)
[ERROR] at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:134)
[ERROR] at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:207)
[ERROR] at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
[ERROR] at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
[ERROR] at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:116)
[ERROR] at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:80)
[ERROR] at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51)
[ERROR] at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
[ERROR] at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:307)
[ERROR] at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:193)
[ERROR] at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:106)
[ERROR] at org.apache.maven.cli.MavenCli.execute(MavenCli.java:863)
[ERROR] at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:288)
[ERROR] at org.apache.maven.cli.MavenCli.main(MavenCli.java:199)
[ERROR] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[ERROR] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[ERROR] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[ERROR] at java.base/java.lang.reflect.Method.invoke(Method.java:566)
[ERROR] at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
[ERROR] at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
[ERROR] at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
[ERROR] at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
[ERROR] at org.codehaus.classworlds.Launcher.main(Launcher.java:47)
Pierre-Yves Bigourdan CLA Friend 2020-08-06 08:33:13 EDT
Can confirm, facing the same problem with Java 11, JaCoCo 0.8.5 and AspectJ 1.9.5.
BRANISLAV KALAS CLA Friend 2021-02-03 02:46:57 EST

Confirming same problem , jacoco > 0.8.3 , JDK11, aspectJ >=1.9.5 we are getting error java.lang.ClassFormatError: Method "$jacocoData" in class xxx has illegal signature "Ljava/lang/Object;"

from myself it is reproducible on

  • openjdk 11
  • jacoco 0.8.4 (and later)
  • aspectj 1.9.6 (also tried 1.9.7 milestones)

this issue is pretty well described (with sample project) in jacoco/jacoco#909
see comment jacoco/jacoco#909 (comment)

current workaround: downgrade jacoco to 0.8.3

@kriegaex
Copy link
Contributor

kriegaex commented Jun 8, 2021

I read that before commenting in Bugzilla. There is only the same incomplete POM as here, I see no sample project. I told you in my comment, which information I need. Please read again and edit the question.

@kriegaex
Copy link
Contributor

kriegaex commented Jun 9, 2021

I quickly added an application class + JUnit 4 test to my sample project based on your POM snippet. The build runs fine and creates a correct coverage report with JaCoco 0.8.4 on JDK 8, 11, 16. Same with JaCoCo 0.8.7. So if you want me to reproduce your problem, I need a full example project with classes, AspectJ and JaCoCo configuration.

@kriegaex
Copy link
Contributor

kriegaex commented Jun 9, 2021

OK, I did your job for you and created a sample project:
https://github.com/kriegaex/AJ_LTWJacocoWeavingProblem_549438

Running mvn clean test jacoco:report on branch master reproduces the problem. Did you notice this message in the log (added extra line breaks)?

[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[WARNING] Corrupted STDOUT by directly writing to native stream in forked JVM 1.
  See FAQ web page and the dump file
  ...\target\surefire-reports\2021-06-09T08-36-25_795-jvmRun1.dumpstream

The dump file thing is unrelated to this issue, because Surefire has problems with correctly displaying console output created by the JVM itself or by Java agents in general. Anyway, if you open the *jvmRun1.dumpstream file, you will see lots of joinpoints matched by your aspect, if you use a simple pointcut like execution(* *(..)) && !within(MyAspect). Due to LTW, AspectJ weaves into

  • Surefire,
  • JUnit,
  • JaCoCo (uh-oh),
  • JDK proxies created by JaCoCo.

This in the end is what makes the build fail. Therefore, the root cause of your problem are simply pointcuts which are too broad, there is no problem in JaCoCo or AspectJ as such. The problem sits in front of the keyboard. 😉

There are at least three ways to solve this:

  1. Narrow the scope of your pointcut: Add something like && within(de.scrum_master..*) to your pointcut, see here in the example project.

  2. Narrow the scope of aspect weaving by adding something like <include within="de.scrum_master..*"/> to the <weaver> section of aop.xml, see here in the example project.

  3. If you are in the unfortunate situation that you provide an aspect library used in a big variety of cases and it is impossible to predict target application package names, you can go the other way and explicitly exclude packages known to cause problems from your pointcut or in the LTW configuration, see here in the example project.

BTW, in this specific case, excluding org.apache.maven.surefire..* already kept the build from failing, but the aspect kept printing executions of the other unwanted packages to the console, so you really should exclude all of them - or simply only include what you need, which is always a good idea in AspectJ.

@aclement, I think this one can be closed and categorised as "won't fix", "question" and/or whatever tags you deem appropriate.


Update: Like I said, at least three ways to solve it. One more way would be:

  1. Use an abstract pointcut, e.g. named targetScope(), for the application target package(s) in your aspect and tell your aspect library users to specify it in aop.xml, customising it to their needs. That way you avoid having to exclude all possible known tool packages which could cause problems during testing or running the application. I mean something like this, as described in the AspectJ manual:
    <!-- define a concrete aspect inline -->
    <concrete-aspect name="org.acme.MyAspect" extends="de.scrum_master.app.MyAbstractAspect">
      <pointcut name="targetScope" expression="within(org.acme..*)"/>
    </concrete-aspect>
    The full pointcut would be a combination of the XML-defined one and the original pointcut, something like this in your abstract aspect: execution(* *(..)) && !within(MyAspect) && targetScope()

@kriegaex
Copy link
Contributor

kriegaex commented Jan 5, 2022

@aclement, please reopen this bug. I have reason to believe my assessment was premature and the problem still persists.

While limiting the aspect scope is necessary and should be kept in order to avoid weaving JaCoCo, JUnit and Surefire classes, like I suggested, the problems caused by that were merely covering up another problem. That problem is related to JEP 309 (Dynamic Class-File Constants) being used by JaCoCo and the AspectJ Weaver seemingly to be unable to deal with the generated bytecode, causing Method "$jacocoData" in class ... has illegal signature ... errors.

See my comment here and the reproducer project here. Andy, could you please look into that and implement a fix? If this is really an AspectJ problem, we probably have it since Java 11 (AspectJ 1.9.2). I am not sure which of JaCoCo or AspectJ is doing something wrong there, but chances are that it might be AspectJ, so please take a look.

@kriegaex
Copy link
Contributor

kriegaex commented Jan 5, 2022

Update: When running Maven with debug logging, I see (with added line breaks and comments):

[DEBUG] Forking command line: cmd.exe /X /C "
  "C:\Program Files\Java\jdk-17\bin\java"

    # JaCoCo agent
    -javaagent:C:\\Users\\alexa\\.m2\\repository\\org\\jacoco\\org.jacoco.agent\\0.8.7\\org.jacoco.agent-0.8.7-runtime.jar=destfile=C:\\Users\\alexa\\Documents\\java-src\\AJ_LTWJacocoWeavingProblem_549438\\target\\jacoco.exec

    # AspectJ weaver needs access to java.base/java.lang on JDK 16+
    --add-opens java.base/java.lang=ALL-UNNAMED

    # AspectJ weaving agent
    -javaagent:C:\Users\alexa/.m2/repository/org/aspectj/aspectjweaver/1.9.8.RC3/aspectjweaver-1.9.8.RC3.jar

    # Maven Surefire executable booter
    -jar C:\Users\alexa\AppData\Local\Temp\surefire15834133402369997443\surefirebooter962938972777004100.jar

      # Maven Surefire parameters
      C:\Users\alexa\AppData\Local\Temp\surefire15834133402369997443
      2022-01-05T09-56-23_778-jvmRun1
      surefire11151023191849343689tmp
      surefire_08147447903974074624tmp
"

I.e., the JaCoCo agent is applied first and then the AspectJ weaver needs to deal with JaCoCo-instrumented byte code, whereas it should be the other way around: JaCoCo should create a coverage report for AspectJ-enhanced classes. So I added commit 487552b8, simply reversing the order of agents on the Surefire command line. This fixes the problem. But it would still be interesting to know why AspectJ cannot deal with JaCoCo-generated byte code. @aclement, you can still reproduce the problem by checking out branch reproduce-original-problem.

@aclement
Copy link
Contributor

aclement commented Jan 5, 2022

please reopen this bug
It's still open isn't it?

to know why AspectJ cannot deal with JaCoCo-generated byte code
AspectJ, in places, recognizes (relies upon even...) patterns of how compilers (javac/jdt) produce bytecode for given constructs - if 'something else' modifies bytecode even if in a perfectly valid way it can trip up a part of AspectJ that has never seen that arrangement of code before. It is indeed an AspectJ bug when this happens.

@kriegaex
Copy link
Contributor

kriegaex commented Jan 5, 2022

please reopen this bug

It's still open isn't it?

Screenshot_20220105-130714_Chrome

Yes, of course. I misinterpreted the above as being related to this issue instead of merely mentioning the other one.

@kriegaex
Copy link
Contributor

kriegaex commented Jan 5, 2022

@aclement, I created a branch dump-class-files which configures Maven and aop.xml to dump class files during the weaving process. I also reversed the agent order again in order to apply JaCoCo transformations first, making the AspectJ weaver fail.

Therefore, when running mvn clean test on that Git branch, you should find a file _ajdump/_before/de/scrum_master/app/ShapeTest.class containing the JaCoCo-enhanced byte code which LTW trips over. It looks like this:

$ javap -c -v _ajdump/de/scrum_master/app/ShapeTest.class

Classfile /C:/Users/alexa/Documents/java-src/AJ_LTWJacocoWeavingProblem_549438/_ajdump/de/scrum_master/app/ShapeTest.class
  Last modified 05.01.2022; size 2839 bytes
  SHA-256 checksum 09b92b6d066d035f1be413af7aa69f86b523c51275aae4ec70226f233b7c5b48
  Compiled from "ShapeTest.java"
public class de.scrum_master.app.ShapeTest
  minor version: 0
  major version: 61
  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
  this_class: #37                         // de/scrum_master/app/ShapeTest
  super_class: #2                         // java/lang/Object
  interfaces: 0, fields: 2, methods: 5, attributes: 4
Constant pool:
    #1 = Methodref          #2.#3         // java/lang/Object."<init>":()V
    #2 = Class              #4            // java/lang/Object
    #3 = NameAndType        #5:#6         // "<init>":()V
    #4 = Utf8               java/lang/Object
    #5 = Utf8               <init>
    #6 = Utf8               ()V
    #7 = Class              #8            // java/lang/Math
    #8 = Utf8               java/lang/Math
    #9 = Double             78.53981633974483d
   #11 = Class              #12           // de/scrum_master/app/Circle
   #12 = Utf8               de/scrum_master/app/Circle
   #13 = Double             5.0d
   #15 = Methodref          #11.#16       // de/scrum_master/app/Circle."<init>":(D)V
   #16 = NameAndType        #5:#17        // "<init>":(D)V
   #17 = Utf8               (D)V
   #18 = Methodref          #11.#19       // de/scrum_master/app/Circle.getArea:()D
   #19 = NameAndType        #20:#21       // getArea:()D
   #20 = Utf8               getArea
   #21 = Utf8               ()D
   #22 = Double             1.0E-6d
   #24 = Methodref          #25.#26       // org/junit/Assert.assertEquals:(DDD)V
   #25 = Class              #27           // org/junit/Assert
   #26 = NameAndType        #28:#29       // assertEquals:(DDD)V
   #27 = Utf8               org/junit/Assert
   #28 = Utf8               assertEquals
   #29 = Utf8               (DDD)V
   #30 = Double             43.982297150257104d
   #32 = Double             7.0d
   #34 = Methodref          #11.#35       // de/scrum_master/app/Circle.getCircumference:()D
   #35 = NameAndType        #36:#21       // getCircumference:()D
   #36 = Utf8               getCircumference
   #37 = Class              #38           // de/scrum_master/app/ShapeTest
   #38 = Utf8               de/scrum_master/app/ShapeTest
   #39 = Utf8               Code
   #40 = Utf8               LineNumberTable
   #41 = Utf8               LocalVariableTable
   #42 = Utf8               this
   #43 = Utf8               Lde/scrum_master/app/ShapeTest;
   #44 = Utf8               testCircle
   #45 = Utf8               RuntimeVisibleAnnotations
   #46 = Utf8               Lorg/junit/Test;
   #47 = Utf8               SourceFile
   #48 = Utf8               ShapeTest.java
   #49 = Utf8               $jacocoInit
   #50 = Utf8               (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)[Z
   #51 = NameAndType        #49:#50       // $jacocoInit:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)[Z
   #52 = Methodref          #37.#51       // de/scrum_master/app/ShapeTest.$jacocoInit:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)[Z
   #53 = MethodHandle       6:#52         // REF_invokeStatic de/scrum_master/app/ShapeTest.$jacocoInit:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)[Z
   #54 = Utf8               $jacocoData
   #55 = Utf8               Ljava/lang/Object;
   #56 = NameAndType        #54:#55       // $jacocoData:Ljava/lang/Object;
   #57 = InvokeDynamic      #0:#56        // #0:$jacocoData:Ljava/lang/Object;
   #58 = Utf8               [Z
   #59 = Class              #58           // "[Z"
   #60 = Utf8               java/lang/$JaCoCo
   #61 = Class              #60           // java/lang/$JaCoCo
   #62 = Utf8               data
   #63 = NameAndType        #62:#55       // data:Ljava/lang/Object;
   #64 = Fieldref           #61.#63       // java/lang/$JaCoCo.data:Ljava/lang/Object;
   #65 = Long               6977707943242498764l
   #67 = Utf8               java/lang/Long
   #68 = Class              #67           // java/lang/Long
   #69 = Utf8               valueOf
   #70 = Utf8               (J)Ljava/lang/Long;
   #71 = NameAndType        #69:#70       // valueOf:(J)Ljava/lang/Long;
   #72 = Methodref          #68.#71       // java/lang/Long.valueOf:(J)Ljava/lang/Long;
   #73 = String             #38           // de/scrum_master/app/ShapeTest
   #74 = Utf8               java/lang/Integer
   #75 = Class              #74           // java/lang/Integer
   #76 = Utf8               (I)Ljava/lang/Integer;
   #77 = NameAndType        #69:#76       // valueOf:(I)Ljava/lang/Integer;
   #78 = Methodref          #75.#77       // java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
   #79 = Utf8               equals
   #80 = Utf8               (Ljava/lang/Object;)Z
   #81 = NameAndType        #79:#80       // equals:(Ljava/lang/Object;)Z
   #82 = Methodref          #2.#81        // java/lang/Object.equals:(Ljava/lang/Object;)Z
   #83 = Utf8               BootstrapMethods
   #84 = Utf8               Synthetic
   #85 = Utf8               ajc$tjp_0
   #86 = Utf8               Lorg/aspectj/lang/JoinPoint$StaticPart;
   #87 = NameAndType        #85:#86       // ajc$tjp_0:Lorg/aspectj/lang/JoinPoint$StaticPart;
   #88 = Fieldref           #37.#87       // de/scrum_master/app/ShapeTest.ajc$tjp_0:Lorg/aspectj/lang/JoinPoint$StaticPart;
   #89 = Utf8               makeJP
   #90 = Utf8               (Lorg/aspectj/lang/JoinPoint$StaticPart;Ljava/lang/Object;Ljava/lang/Object;)Lorg/aspectj/lang/JoinPoint;
   #91 = NameAndType        #89:#90       // makeJP:(Lorg/aspectj/lang/JoinPoint$StaticPart;Ljava/lang/Object;Ljava/lang/Object;)Lorg/aspectj/lang/JoinPoint;
   #92 = Utf8               org/aspectj/runtime/reflect/Factory
   #93 = Class              #92           // org/aspectj/runtime/reflect/Factory
   #94 = Methodref          #93.#91       // org/aspectj/runtime/reflect/Factory.makeJP:(Lorg/aspectj/lang/JoinPoint$StaticPart;Ljava/lang/Object;Ljava/lang/Object;)Lorg/aspectj/lang/JoinPoint;
   #95 = Utf8               aspectOf
   #96 = Utf8               ()Lde/scrum_master/app/MyAspect;
   #97 = NameAndType        #95:#96       // aspectOf:()Lde/scrum_master/app/MyAspect;
   #98 = Utf8               de/scrum_master/app/MyAspect
   #99 = Class              #98           // de/scrum_master/app/MyAspect
  #100 = Methodref          #99.#97       // de/scrum_master/app/MyAspect.aspectOf:()Lde/scrum_master/app/MyAspect;
  #101 = Utf8               myAdvice
  #102 = Utf8               (Lorg/aspectj/lang/JoinPoint;)V
  #103 = NameAndType        #101:#102     // myAdvice:(Lorg/aspectj/lang/JoinPoint;)V
  #104 = Methodref          #99.#103      // de/scrum_master/app/MyAspect.myAdvice:(Lorg/aspectj/lang/JoinPoint;)V
  #105 = Utf8               ajc$tjp_1
  #106 = NameAndType        #105:#86      // ajc$tjp_1:Lorg/aspectj/lang/JoinPoint$StaticPart;
  #107 = Fieldref           #37.#106      // de/scrum_master/app/ShapeTest.ajc$tjp_1:Lorg/aspectj/lang/JoinPoint$StaticPart;
  #108 = Utf8               (Lorg/aspectj/lang/JoinPoint$StaticPart;Ljava/lang/Object;Ljava/lang/Object;[Ljava/lang/Object;)Lorg/aspectj/lang/JoinPoint;
  #109 = NameAndType        #89:#108      // makeJP:(Lorg/aspectj/lang/JoinPoint$StaticPart;Ljava/lang/Object;Ljava/lang/Object;[Ljava/lang/Object;)Lorg/aspectj/lang/JoinPoint;
  #110 = Methodref          #93.#109      // org/aspectj/runtime/reflect/Factory.makeJP:(Lorg/aspectj/lang/JoinPoint$StaticPart;Ljava/lang/Object;Ljava/lang/Object;[Ljava/lang/Object;)Lorg/aspectj/lang/JoinPoint;
  #111 = Utf8               org.aspectj.weaver.WeaverVersion
  #112 = Utf8               org.aspectj.weaver.WeaverState
  #113 = String             #48           // ShapeTest.java
  #114 = Utf8               (Ljava/lang/String;Ljava/lang/Class;)V
  #115 = NameAndType        #5:#114       // "<init>":(Ljava/lang/String;Ljava/lang/Class;)V
  #116 = Methodref          #93.#115      // org/aspectj/runtime/reflect/Factory."<init>":(Ljava/lang/String;Ljava/lang/Class;)V
  #117 = Utf8               method-execution
  #118 = String             #117          // method-execution
  #119 = Utf8               1
  #120 = String             #119          // 1
  #121 = String             #44           // testCircle
  #122 = Utf8               de.scrum_master.app.ShapeTest
  #123 = String             #122          // de.scrum_master.app.ShapeTest
  #124 = Utf8
  #125 = String             #124          //
  #126 = Utf8               void
  #127 = String             #126          // void
  #128 = Utf8               makeMethodSig
  #129 = Utf8               (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lorg/aspectj/lang/reflect/MethodSignature;
  #130 = NameAndType        #128:#129     // makeMethodSig:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lorg/aspectj/lang/reflect/MethodSignature;
  #131 = Methodref          #93.#130      // org/aspectj/runtime/reflect/Factory.makeMethodSig:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lorg/aspectj/lang/reflect/MethodSignature;
  #132 = Utf8               makeSJP
  #133 = Utf8               (Ljava/lang/String;Lorg/aspectj/lang/Signature;I)Lorg/aspectj/lang/JoinPoint$StaticPart;
  #134 = NameAndType        #132:#133     // makeSJP:(Ljava/lang/String;Lorg/aspectj/lang/Signature;I)Lorg/aspectj/lang/JoinPoint$StaticPart;
  #135 = Methodref          #93.#134      // org/aspectj/runtime/reflect/Factory.makeSJP:(Ljava/lang/String;Lorg/aspectj/lang/Signature;I)Lorg/aspectj/lang/JoinPoint$StaticPart;
  #136 = Utf8               100a
  #137 = String             #136          // 100a
  #138 = String             #49           // $jacocoInit
  #139 = Utf8               java.lang.invoke.MethodHandles$Lookup:java.lang.String:java.lang.Class
  #140 = String             #139          // java.lang.invoke.MethodHandles$Lookup:java.lang.String:java.lang.Class
  #141 = Utf8               arg0:arg1:arg2
  #142 = String             #141          // arg0:arg1:arg2
  #143 = String             #58           // [Z
  #144 = Utf8               ajc$preClinit
  #145 = NameAndType        #144:#6       // ajc$preClinit:()V
  #146 = Methodref          #37.#145      // de/scrum_master/app/ShapeTest.ajc$preClinit:()V
  #147 = Utf8               arg0
  #148 = Utf8               Ljava/lang/invoke/MethodHandles$Lookup;
  #149 = Utf8               arg1
  #150 = Utf8               Ljava/lang/String;
  #151 = Utf8               arg2
  #152 = Utf8               Ljava/lang/Class;
  #153 = Utf8               <clinit>
{
  public de.scrum_master.app.ShapeTest();
    descriptor: ()V
    flags: (0x0001) ACC_PUBLIC
    Code:
      stack=3, locals=2, args_size=1
         0: ldc           #57                 // InvokeDynamic #0:$jacocoData:Ljava/lang/Object;
         2: checkcast     #59                 // class "[Z"
         5: astore_1
         6: aload_0
         7: invokespecial #1                  // Method java/lang/Object."<init>":()V
        10: aload_1
        11: iconst_0
        12: iconst_1
        13: bastore
        14: return
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      15     0  this   Lde/scrum_master/app/ShapeTest;
      LineNumberTable:
        line 6: 6

  public void testCircle();
    descriptor: ()V
    flags: (0x0001) ACC_PUBLIC
    Code:
      stack=6, locals=3, args_size=1
         0: getstatic     #88                 // Field ajc$tjp_0:Lorg/aspectj/lang/JoinPoint$StaticPart;
         3: aload_0
         4: aload_0
         5: invokestatic  #94                 // Method org/aspectj/runtime/reflect/Factory.makeJP:(Lorg/aspectj/lang/JoinPoint$StaticPart;Ljava/lang/Object;Ljava/lang/Object;)Lorg/aspectj/lang/JoinPoint;
         8: astore_2
         9: invokestatic  #100                // Method de/scrum_master/app/MyAspect.aspectOf:()Lde/scrum_master/app/MyAspect;
        12: aload_2
        13: invokevirtual #104                // Method de/scrum_master/app/MyAspect.myAdvice:(Lorg/aspectj/lang/JoinPoint;)V
        16: ldc           #57                 // InvokeDynamic #0:$jacocoData:Ljava/lang/Object;
        18: checkcast     #59                 // class "[Z"
        21: astore_1
        22: ldc2_w        #9                  // double 78.53981633974483d
        25: new           #11                 // class de/scrum_master/app/Circle
        28: dup
        29: ldc2_w        #13                 // double 5.0d
        32: invokespecial #15                 // Method de/scrum_master/app/Circle."<init>":(D)V
        35: invokevirtual #18                 // Method de/scrum_master/app/Circle.getArea:()D
        38: ldc2_w        #22                 // double 1.0E-6d
        41: invokestatic  #24                 // Method org/junit/Assert.assertEquals:(DDD)V
        44: aload_1
        45: iconst_1
        46: iconst_1
        47: bastore
        48: ldc2_w        #30                 // double 43.982297150257104d
        51: new           #11                 // class de/scrum_master/app/Circle
        54: dup
        55: ldc2_w        #32                 // double 7.0d
        58: invokespecial #15                 // Method de/scrum_master/app/Circle."<init>":(D)V
        61: invokevirtual #34                 // Method de/scrum_master/app/Circle.getCircumference:()D
        64: ldc2_w        #22                 // double 1.0E-6d
        67: invokestatic  #24                 // Method org/junit/Assert.assertEquals:(DDD)V
        70: aload_1
        71: iconst_2
        72: iconst_1
        73: bastore
        74: return
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      75     0  this   Lde/scrum_master/app/ShapeTest;
      LineNumberTable:
        line 9: 9
        line 10: 48
        line 11: 70
    RuntimeVisibleAnnotations:
      0: #46()
        org.junit.Test

  static {};
    descriptor: ()V
    flags: (0x0008) ACC_STATIC
    Code:
      stack=0, locals=0, args_size=0
         0: invokestatic  #146                // Method ajc$preClinit:()V
         3: return
      LineNumberTable:
        line 1: 0
}
SourceFile: "ShapeTest.java"
BootstrapMethods:
  0: #53 REF_invokeStatic de/scrum_master/app/ShapeTest.$jacocoInit:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)[Z
    Method arguments:
  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 = 0x4 (unknown attribute)
   03 00 00 00

@aclement
Copy link
Contributor

aclement commented Jan 7, 2022

I guess that project is missing some repositories that you have locally configured or something:

[INFO] Scanning for projects...
[INFO]
[INFO] -----------< org.example:AJ_LTWJacocoWeavingProblem_549438 >------------
[INFO] Building AJ_LTWJacocoWeavingProblem_549438 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[WARNING] The POM for org.apache.maven.plugins:maven-surefire-plugin:jar:3.0.0-M6-SNAPSHOT is missing, no dependency information available
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  0.171 s
[INFO] Finished at: 2022-01-06T22:00:17-08:00
[INFO] ------------------------------------------------------------------------
[ERROR] Plugin org.apache.maven.plugins:maven-surefire-plugin:3.0.0-M6-SNAPSHOT or one of its dependencies could not be resolved: Could not find artifact org.apache.maven.plugins:maven-surefire-plugin:jar:3.0.0-M6-SNAPSHOT -> [Help 1]

@aclement
Copy link
Contributor

aclement commented Jan 7, 2022

I switched it to M5 instead.

@kriegaex
Copy link
Contributor

kriegaex commented Jan 7, 2022

I switched it to M5 instead.

Ah yes, of course. Well, in M5 there is a bug which makes the console output of Java agents hang. Lucky you, if with M5 that did not happen. Actually, you can also build with a previous release 2.2.x, but then you do not see the agent output on the console, only in a dump file. I helped the Surefire people fix that by testing and providing reproducer projects.

@kriegaex
Copy link
Contributor

kriegaex commented Jan 7, 2022

Thanks for the fix in 92779d0. If I have an idea how to do that, I can add a test for it. @aclement, should I simply build 1.9.8 (or should we call it 1.9.17?) soon and publish it on Maven Central, or is there anything you need to do with regard to the Eclipse website etc.?

@aclement
Copy link
Contributor

aclement commented Jan 7, 2022

I see no reason to delay on 1.9.8 if you are happy. I do the website updates after it is available.

@aclement
Copy link
Contributor

aclement commented Jan 7, 2022

Given that I don't know of a java language construct that would cause the compiler to generate bytecode containing Dynamic, you'll have to construct the bytecode yourself if you want to write a test (at least a test that isn't bringing in jacoco and getting all complicated). Certainly doable, but a bunch of work. The need for a test seems less urgent given this is such a silly mistake and that same thing shouldn't regress in the future.

kriegaex added a commit to kriegaex/aspectj that referenced this issue Jan 8, 2022
Relates to eclipse-aspectj#68.

Signed-off-by: Alexander Kriegisch <Alexander@Kriegisch.name>
@kriegaex
Copy link
Contributor

kriegaex commented Jan 8, 2022

@aclement, I modified code by @raphw found in this blog post, ASM-ified it, stored the generator code beside the actual test classes, but also committed a JAR containing the generated class file, similar to how it was done for the indy (invokedynamic) tests. That is not nice, but I did not want to make a big change in order to be able to refer to ASM from XML test configs via something like $asm, similar to $sandbox.

If we ever see more widespread adoption of condy in JVM languages, we can move the test to its own condy subdirectory and add others, maybe dumping the test classes generated by these Byte Buddy tests and ASM-ifying them in order to have generators without the need to add Byte Buddy itself as a dependency.

BTW, like I thought, this bug has existed ever since Java 11 and condy support were added to AspectJ 1.9.2.

kriegaex added a commit to kriegaex/aspectj that referenced this issue Jan 9, 2022
Relates to eclipse-aspectj#68.

Signed-off-by: Alexander Kriegisch <Alexander@Kriegisch.name>
kriegaex added a commit to kriegaex/aspectj that referenced this issue Jan 9, 2022
Relates to eclipse-aspectj#68.

Signed-off-by: Alexander Kriegisch <Alexander@Kriegisch.name>
@aclement
Copy link
Contributor

Nice test case and nice work on the original maven repro sample, made my life much easier.

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

3 participants