如何在Gradle项目中使用自身定义的注解处理器处理测试代码?
问题
我正在开发一个包含注解处理器的Java库,项目结构如下:
. ├── lib │ ├── build.gradle │ └── src │ ├── main │ │ ├── java │ │ │ └── demo │ │ │ ├── MyAnnotation.java │ │ │ └── MyAnnotationProcessor.java │ │ └── resources │ └── test │ ├── java │ │ └── demo │ │ └── MyAnnotationProcessorTest.java │ └── resources └── settings.gradle
我希望在MyAnnotationProcessorTest.java中使用@MyAnnotation,但执行gradle build或gradle test时,Gradle完全没有处理该注解。
注解类代码:
package demo; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.MODULE, ElementType.PACKAGE, ElementType.TYPE_USE, ElementType.PARAMETER, ElementType.CONSTRUCTOR, ElementType.LOCAL_VARIABLE, ElementType.TYPE_PARAMETER, ElementType.ANNOTATION_TYPE, ElementType.RECORD_COMPONENT}) @Retention(RetentionPolicy.SOURCE) public @interface MyAnnotation { }
注解处理器类代码:
package demo; import java.util.Set; import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.Processor; import javax.annotation.processing.RoundEnvironment; import javax.annotation.processing.SupportedAnnotationTypes; import javax.lang.model.SourceVersion; import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.TypeElement; import javax.lang.model.element.VariableElement; import javax.tools.Diagnostic; import com.google.auto.service.AutoService; @SupportedAnnotationTypes("demo.MyAnnotation") @AutoService(Processor.class) public class MyAnnotationProcessor extends AbstractProcessor { @Override public SourceVersion getSupportedSourceVersion() { return SourceVersion.latest(); } @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, ">>>>>> process called <<<<<<"); return true; } }
当前build.gradle配置:
plugins { id 'java-library' } repositories { mavenCentral() } dependencies { testImplementation 'org.junit.jupiter:junit-jupiter:5.9.1' implementation 'com.google.auto.service:auto-service:1.1.1' annotationProcessor 'com.google.auto.service:auto-service:1.1.1' } // Apply a specific Java toolchain to ease working on different environments. java { toolchain { languageVersion = JavaLanguageVersion.of(17) } } tasks.named('test') { // Use JUnit Platform for unit tests. useJUnitPlatform() }
执行gradle build或gradle test时,注解处理器没有输出任何信息。但将该项目作为注解处理器引入其他项目时,能正常输出日志。现在需要在定义注解处理器的同一项目中测试并使用该编译时注解处理器。
解决方案
Gradle默认不会在test源码编译阶段自动应用本项目main源码中的注解处理器,需要手动配置让test编译任务依赖本项目的注解处理器输出,具体有两种方式:
方式一:直接配置test的annotationProcessor依赖
在dependencies块中添加以下配置,让test编译阶段使用本项目main源码编译后的产物作为注解处理器:
dependencies { // 保留原有配置 testImplementation 'org.junit.jupiter:junit-jupiter:5.9.1' implementation 'com.google.auto.service:auto-service:1.1.1' annotationProcessor 'com.google.auto.service:auto-service:1.1.1' // 新增:让test编译阶段加载本项目的注解处理器 testAnnotationProcessor sourceSets.main.output }
方式二:拆分源码集(适合复杂场景)
如果注解处理器逻辑复杂,希望清晰分离代码结构,可以将注解处理器单独放在一个自定义源码集(比如processor),然后让main和test分别依赖该源码集的输出:
- 定义新的源码集:
sourceSets { processor { java { srcDir 'src/processor/java' } } }
- 调整依赖配置:
dependencies { // main模块依赖注解定义 implementation sourceSets.processor.output // test模块依赖main代码,并加载注解处理器 testImplementation sourceSets.main.output testAnnotationProcessor sourceSets.processor.output // 给processor源码集配置auto-service依赖 processorImplementation 'com.google.auto.service:auto-service:1.1.1' processorAnnotationProcessor 'com.google.auto.service:auto-service:1.1.1' testImplementation 'org.junit.jupiter:junit-jupiter:5.9.1' }
这种方式能避免源码依赖混乱,适合大型注解处理器项目。
验证配置
配置完成后,执行gradle test,就能在控制台看到注解处理器输出的>>>>>> process called <<<<<<日志了。
内容的提问来源于stack exchange,提问作者user3310334
相关产品推荐
相关产品推荐

