
Gradle 默认不支持在定义注解处理器的同一模块中直接使用该处理器处理自身源码;需通过分离模块(如 lib + test)并配置 testAnnotationProcessor project(':lib') 实现自测。
gradle 默认不支持在定义注解处理器的同一模块中直接使用该处理器处理自身源码;需通过分离模块(如 `lib` + `test`)并配置 `testannotationprocessor project(':lib')` 实现自测。
在构建注解处理器类库时,一个常见且关键的需求是:验证处理器能否正确响应其自身定义的注解。但默认情况下,Gradle 的 java-library 插件不会对 src/main 中的代码启用本模块声明的 annotationProcessor —— 因为编译期注解处理发生在 javac 的独立阶段,而 Gradle 将 annotationProcessor 依赖仅应用于当前项目的编译任务输入,并不包含本模块自身的源码路径(否则会引发循环依赖风险)。
因此,直接在 lib/src/test/java/... 中使用 @MyAnnotation 并期望 MyAnnotationProcessor.process() 被调用,是无效的。Gradle 的 test 任务默认只编译测试源码,且其 annotation processing classpath 不自动包含本模块的 processor 类(即使它已编译完成),除非显式声明。
✅ 正确方案:采用多模块结构,实现“处理器定义”与“处理器使用”的逻辑隔离:
-
lib模块(纯处理器定义)- 仅含
MyAnnotation.java和MyAnnotationProcessor.java -
build.gradle中声明implementation和annotationProcessor依赖(如auto-service) - 不包含任何测试代码,也不配置
test相关逻辑
- 仅含
-
test模块(专用测试消费者)
Miller CSV TSV JSON 数据处理器下载Miller (mlr) 是一个命令行工具,用于查询、整形和重新格式化名称索引数据,如 CSV、TSV、JSON 和 JSON Lines。它将 awk、sed、cut、join 和 sort 的功能整合到一个专为结构化数据处理而构建的单一工具中。
- 仅含测试类(如
MyAnnotationProcessorTest.java),并在其中使用@MyAnnotation -
build.gradle中声明:testImplementation project(':lib') // 提供注解类与处理器类 testAnnotationProcessor project(':lib') // 显式启用本模块作为测试期注解处理器 - 注意:
testAnnotationProcessor是 Gradle 7.4+ 原生支持的配置,专为测试阶段的注解处理设计,等价于为compileTestJava任务配置 annotation processor path。
- 仅含测试类(如
-
settings.gradle必须包含:include 'lib', 'test'
? 关键原理说明:
-
testAnnotationProcessor project(':lib')会将lib模块编译输出的classes(含MyAnnotationProcessor.class)和runtimeClasspath(含auto-service等)注入到compileTestJava编译器的-processorpath中; - 同时,
testImplementation project(':lib')确保MyAnnotation类型在测试编译期可见; - 因此,当
MyAnnotationProcessorTest.java被编译时,javac会扫描其源码中的@MyAnnotation,匹配@SupportedAnnotationTypes,并触发process()方法 —— 控制台即可看到">>>>> process called 输出。
⚠️ 注意事项:
-
test模块不会被打包进lib的最终 JAR(如demo.jar),它仅用于开发期验证,符合发布规范; - 避免在
lib的dependencies中错误添加annotationProcessor project(path: ':lib', configuration: 'default')—— 这会导致非法循环依赖,Gradle 将拒绝构建; - 若需更严格的模块边界,可将
lib发布为本地 Maven 仓库(maven-publish),再由test模块以testAnnotationProcessor "com.example:lib:1.0"形式引用,但多项目依赖更轻量、更推荐。
总结:注解处理器的“自测”不是 Gradle 的开箱即用场景,而是工程实践中的标准模式 —— 通过职责分离(定义 vs 使用)、显式配置 testAnnotationProcessor,既保证了构建稳定性,又提供了可靠的验证闭环。










