Closed maginseb closed 2 years ago
Thanks for opening this issue and for the reproducer project (which I have not tried yet). I might be able to take a closer look during the weekend, but cannot promise. I think I might have spotted something which could be an oversight in an older (1.9.0) version of AspectJ, i.e. a possible bug. But I cannot say for sure yet, I only looked at some source code for 3 minutes.
I have looked into the issue briefly. It seems that there is an issue in BCEL, which we use internally in AspectJ. You may want to track the issue BCEL-362, which I have just created. There is a chance that we are doing something wrong in AspectJ, but at the moment I believe that the issue is upstream.
Makes sense, the issue happens in the BCEL-stack. Thank you, I will track the issue, that you have created!
@maginseb, I have some news for you:
Unknown constant type 17
error.@Around
advice. If at the same time you also instrument your aspect code with JaCoCo, the constant-dynamic variables named $jacocoData
and their initialisation methods $jacocoInit
created by JaCoCo in both the aspect and target classes clash with each other because of identical names and types, which causes
ArrayIndexOutOfBoundsException
, if the advice code wants to write coverage data to an index greater than the array size in the target method,In order to fix the issue in no. 4, you have two choices, which surprisingly even work with the current AspectJ release, because luckily they both avoid touching the existing JaCoCo condy code:
-XnoInline
when using the AspectJ compiler or the load-time weaving agent. This enables you to weave aspects into your JaCoCo-instrumented code and get coverage data for both your aspect and application code. This is the recommended solution.<excludes><exclude>**/*Aspect.*</exclude></excludes>
.@kriegaex Thank you very much for your help. I greatly appreciate your effort. I have tried both of your recommendations, they work perfectly.
In case someone else stumbles across this issue:
I have updated my example https://github.com/maginseb/jacoco-aspectj-error It includes the recommended fixes now.
I locally also tested with a modified version of your original reproducer. Thanks for that, it is always easier to fix something reproducible. Besides, I have also provided a BCEL fix both in AspectJ and for BCEL itself, because independently of the solution for this particular problem, both tools had problems parsing condy byte code.
I face the following problem when running tests that use both JaCoCo (0.8.8) and AspectJ LTW (1.9.9.1).
I found two related bugs on this topic: https://github.com/jacoco/jacoco/issues/909 and https://github.com/eclipse/org.aspectj/issues/68
https://github.com/jacoco/jacoco/issues/909 recommends a change of order for the JaCoCo and AspectJ Java agents, so that the AspectJ agent is executed first. This, however, will prevent JaCoCo from correctly calculating the coverage for classes that are touched be the AspectJ agent.
Explanation based on the JaCoCo documentation: Jacoco uses classIds to connect coverage at runtime with the class files (JaCoCo-documentation). ClassIds are calculated based on the byte code of classes. When the bytecode of a class is modified, JaCoCo calculates an incorrect classId and the coverage of this class cannot be determined. Therefore, they recommend in their documentation: "If you use another Java agent make sure the JaCoCo agent is specified at first in the command line. This way the JaCoCo agent should see the original class files."
Example
I have built an example project that easily allows you to reproduce this issue: https://github.com/maginseb/jacoco-aspectj-error
mvn clean verify
Order of the Java agents is as recommended by JaCoCo (JaCoCo first, AspectJ second) The result is the exception regarding the Unknown constant type 17mvn clean verify -P switch-order
Order of the Java agents is as recommended in https://github.com/jacoco/jacoco/issues/909 (AspectJ first, JaCoCo second) The result is a messed up code coverage. No class is covered based on the report even though the coverage should be close to 100%