OpenClover - 开始使用 AspectJ

OpenClover - Getting to work with AspectJ

我正在尝试将 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

关于这方面的文档太少(或更好,none),我似乎无法使 AspectJ 与 OpenClover 一起工作,而且网络上也没有太多帮助。

谢谢

正如我们评论中所讨论的,您可以只使用 AspectJ Maven instead of Clover AspectJ。您只需要采取一些预防措施即可使其正常工作:

  • 我喜欢将 AspectJ Maven 执行置于 process-sources 阶段,以确保 AspectJ 编译器在正常的 Java 编译器由 Maven 编译器插件启动之前启动.您也可以停用 Maven 编译器,因为 Ajc 是 Javac 的完全替代品。实际上,该阶段曾经是旧插件版本中的默认阶段,但是 changed long ago, which is also mentioned in an answer on SO. See also MASPECTJ-13 for why it was changed and MASPECTJ-92 为什么更改不是一个好主意。

  • Maven Compiler 有一个问题,即开关useIncrementalCompilation 似乎逻辑颠倒了。这就是为什么您需要将其设置为 false 才能使其正常工作。否则它会尝试重新编译已经由 AspectJ 编译的内容,从而破坏方面编织。请参阅 MCOMPILER-209 and 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 一起使用。不然用起来意义不大