如何从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
相关产品推荐
相关产品推荐

