When Code Coverage and Load-Time Weaving Clash
Join the DZone community and get the full member experience.Join For Free
Our cassandra-triggers implementation uses AOP. Virgil also uses it for connection pooling and retries. More specifically, each of these projects uses load-time weaving, where the byte code of the classes is changed at runtime. For testing purposes, we have the following added to our pom file:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.9</version> <configuration> <argLine>-javaagent:lib/aspectjweaver.jar</argLine> </configuration> </plugin>This adds the aspectjweaver agent to the jvm runtime, which enables and performs the load-time weaving. When we went to gather code coverage information on the projects, we ended up with the following exception out of aspectj.
[IsolatedClassLoader@1342ba4] warning register definition failed -- (BCException) malformed class file malformed class file org.aspectj.weaver.BCException: malformed class file at org.aspectj.weaver.bcel.Utility.makeJavaClass(Utility.java:466) at org.aspectj.weaver.bcel.BcelWeaver.addLibraryAspect(BcelWeaver.java:189)Evidently, aspectj doesn't like cobertura instrumented classes. After much googling, I couldn't find a good solution. There appeared to be a lot of back and forth between cobertura and aspectj. To avoid the situation entirely, I simply decided to maintain to pom files. I swapped out the plugin above that adds the agent jvm, for the snippet below that enables compile-time weaving:
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>aspectj-maven-plugin</artifactId> <version>1.4</version> <configuration> <complianceLevel>1.5</complianceLevel> <weaveDependencies> <weaveDependency> <groupId>org.apache.cassandra</groupId> <artifactId>cassandra-thrift</artifactId> </weaveDependency> <weaveDependency> <groupId>org.apache.cassandra</groupId> <artifactId>cassandra-all</artifactId> </weaveDependency> </weaveDependencies> </configuration> <executions> <execution> <goals> <goal>compile</goal> </goals> </execution> </executions> </plugin>This swaps from load-time weaving during testing to the compile-time weaving, which allows cobertura and aspectj to play well together, which means you'll get accurate code coverage numbers in Sonar.
Opinions expressed by DZone contributors are their own.