我试图将Openclover用于一个使用AspectJ并将仪器方面纳入其代码的项目。
pom.xml
具有与AspectJ相关的依赖关系:
...
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.9</version>
<scope>provided</scope>
</dependency>
</dependencies>
...
这些插件:
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.openclover</groupId>
<artifactId>clover-aspectj-compiler</artifactId>
<version>1.0.0</version>
</plugin>
<plugin>
<groupId>org.openclover</groupId>
<artifactId>clover-maven-plugin</artifactId>
<version>4.2.0</version>
<executions>
<execution>
<id>clover</id>
<phase>verify</phase>
<goals>
<goal>instrument</goal>
<goal>clover</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
我使用两个插件来执行此操作:clover-maven-plugin
这是一个代码覆盖率工具,clover-aspectj-compiler
是AspectJ编译器的包装器,允许使用OpenClover进行代码检测。
我得到的错误如下:
[ERROR] QueryAspect.java:48:0::0 The type QueryAspect is already defined
[ERROR] LogAspect.java:35:0::0 The type LogAspect is already defined
关于这个的文档太少(或更好,没有),我似乎无法使AspectJ与OpenClover一起工作,并且在网络上没有太多帮助。
谢谢
答案 0 :(得分:1)
如我们的评论中所述,您只能使用AspectJ Maven而不是Clover AspectJ。您只需采取一些预防措施即可使其正常工作:
我喜欢将AspectJ Maven执行置于process-sources
阶段,以确保AspectJ编译器在Maven Compiler插件启动的普通Java编译器之前启动。您也可以停用Maven编译器,因为Ajc可以完全替代Javac。实际上,该阶段曾经是较早的插件版本中的默认阶段,但它一直是changed long ago,在answer on SO中也提到过。
Maven编译器存在问题,即开关useIncrementalCompilation
似乎逻辑相反。这就是为什么您需要将其设置为false
使其起作用的原因。否则,它将尝试重新编译AspectJ已编译的内容,从而破坏Aspect编织。参见MCOMPILER-209和MCOMPILER-194,我在帖子中解释了该问题及其解决方案。
现在唯一真正与OpenClover(OC)有关的问题:AspectJ(AJ)对OC向每种方法添加源代码以实现代码覆盖方面一无所知。不幸的是,OC还不了解AJ,并且还在注释样式的切入点中添加了代码,这些切入点定义为带有@Pointcut
注释的空方法。由于OC需要在AJ编译之前尽其所能,AJ编译器会抱怨切入点中发现了意外的代码,并因错误而停止了编译。至少有两种方法可以避免这种情况:
您可以将所有切入点内联到各自的@Before
,@After
,@Around
等中。使用它们的建议通常有效,但在某些情况下并不总是一种选择您需要在切入点中进行参数绑定以实现诸如execution(pointcutA()) && cflow(execution(pointcutB(myArgument)))
之类的虫洞模式。
或者您可以从OC工具中排除所有方面,如果它们驻留在一个不需要其他Java类的程序包中,这是最简单的。然后,您可以使用简单的排除方式,例如<exclude>codeaspects/**</exclude>
。这是我在修复项目时在pull request中所做的事情。
最简单的方法是将所有方面从*.java
重命名为*.aj
,这是无论如何命名它们的规范方法。我刚刚在您的项目中尝试过,并且效果很好。 AspectJ Maven仍然会寻找那些文件,但是OC会忽略它们,甚至不会为缺少覆盖范围而计算它们的代码行。您也可以摆脱上面提到的<exclude>
,请参见this commit。
也许所有这些都是Clover AspectJ自动处理的,我从未尝试过。也许那个编译器包装的作者应该在文档中实际解释它的功能以及它的工作方式,尤其是如何在Maven中使用它。否则,使用它就没有太大意义。