You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从Jacoco覆盖率统计中排除AspectJ生成的AjcClosure类

解决AspectJ织入导致Jacoco覆盖率减半的问题

1. 确保Jacoco排除规则覆盖所有AspectJ辅助类并在报告阶段生效

你的现有配置仅在全局层面定义了排除规则,但可能report阶段未正确继承这些规则。修改Jacoco插件配置,明确在report执行阶段也添加排除,并扩展范围覆盖所有AspectJ生成的辅助类:

<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.8.5</version>
    <configuration>
        <excludes>
            <!-- 排除Aspect类本身 -->
            <exclude>**/*Aspect*.class</exclude>
            <!-- 排除所有Ajc开头的辅助类 -->
            <exclude>**/Ajc*.class</exclude>
            <exclude>**/*AjcClosure*.class</exclude>
        </excludes>
    </configuration>
    <executions>
        <execution>
            <id>prepare-agent</id>
            <goals>
                <goal>prepare-agent</goal>
            </goals>
        </execution>
        <execution>
            <id>jacoco-report</id>
            <phase>test</phase>
            <goals>
                <goal>report</goal>
            </goals>
            <!-- 单独在report阶段配置排除,确保规则生效 -->
            <configuration>
                <excludes>
                    <exclude>**/*Aspect*.class</exclude>
                    <exclude>**/Ajc*.class</exclude>
                    <exclude>**/*AjcClosure*.class</exclude>
                </excludes>
            </configuration>
        </execution>
    </executions>
</plugin>

2. 排除AspectJ织入到原有类中的Advice代码

如果原有类的覆盖率仍未恢复,说明Jacoco统计了AspectJ直接嵌入到业务类字节码中的Advice逻辑(这些代码不在AjcClosure类内)。解决方法是给Aspect的Advice方法添加@Generated注解,让Jacoco忽略这些代码:

步骤1:给Aspect类的Advice添加@Generated注解

import javax.annotation.Generated;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class BusinessAspect {
    // 标记该Advice为生成代码,让Jacoco排除统计
    @Generated("AspectJ")
    @Around("execution(* com.yourpackage.business..*(..))")
    public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
        // AspectJ的Advice逻辑
        long start = System.currentTimeMillis();
        Object proceed = joinPoint.proceed();
        long executionTime = System.currentTimeMillis() - start;
        System.out.println(joinPoint.getSignature() + " executed in " + executionTime + "ms");
        return proceed;
    }
}

步骤2:在Jacoco配置中排除带@Generated注解的代码

修改Jacoco插件的configuration,添加filter规则排除指定注解的代码:

<configuration>
    <excludes>
        <exclude>**/*Aspect*.class</exclude>
        <exclude>**/Ajc*.class</exclude>
        <exclude>**/*AjcClosure*.class</exclude>
    </excludes>
    <!-- 排除所有带@Generated注解的代码 -->
    <filter>
        <excludeAnnotation>javax.annotation.Generated</excludeAnnotation>
        <!-- 如果使用其他Generated注解,比如Spring的 -->
        <excludeAnnotation>org.springframework.stereotype.Generated</excludeAnnotation>
    </filter>
</configuration>

3. 确保AspectJ与Jacoco的执行顺序正确

如果你的项目使用aspectj-maven-plugin进行编译时织入,需要确保它在Jacoco插桩之前执行(即AspectJ先完成织入,Jacoco再对织入后的类进行插桩)。配置aspectj-maven-plugin绑定到compile阶段:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>aspectj-maven-plugin</artifactId>
    <version>1.14.0</version>
    <executions>
        <execution>
            <phase>compile</phase>
            <goals>
                <goal>compile</goal>
            </goals>
        </execution>
    </executions>
</plugin>

这个配置会让AspectJ在Maven的compile阶段完成织入,而Jacoco的prepare-agent会在test阶段前执行插桩,确保顺序正确。

内容的提问来源于stack exchange,提问作者tarini sunil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 09:27:49