不能只靠 classpath 加载注解处理器,因为 javac 从 JDK 8 起强制要求通过 -processorpath 显式指定处理器路径,否则忽略 META-INF/services 配置并报错;Maven 需用 annotationProcessorPaths、Gradle 用 annotationProcessor,IDEA 还需禁用“Obtain processors from project classpath”。

为什么不能只靠 classpath 加载注解处理器
注解处理器(如 Lombok、MapStruct)在编译期运行,但 JVM 并不直接加载它们——javac 会通过独立的“注解处理器类路径”(-processorpath)去查找和实例化 javax.annotation.processing.Processor 实现类。如果只把处理器 JAR 放进普通 classpath 或 compile 依赖里,javac 会忽略它,甚至报错:Error: Annotation processors must be explicitly declared now。
根本原因在于:Java 编译器从 JDK 8 起强制要求显式声明处理器路径,不再自动扫描 classpath 中的 META-INF/services/javax.annotation.processing.Processor(除非你加了 -proc:only 或 -proc:full 且 -processorpath 已设)。
maven-compiler-plugin 中用 annotationProcessorPaths 隔离路径
Maven 项目必须用 annotationProcessorPaths,而不是 dependencies 的 compile 或 provided 范围——否则处理器会被打进最终包,污染运行时 classpath。
- 正确写法(Maven
pom.xml):
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>17</source>
<target>17</target>
<!-- 关键:单独指定处理器路径,不混入 compile 依赖 -->
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.34</version>
</path>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.5.5.Final</version>
</path>
</annotationProcessorPaths>
<!-- 确保没禁用注解处理 -->
<compilerArgs>
<arg>-proc:full</arg>
</compilerArgs>
</configuration>
</plugin>- 错误做法:
<dependency>声明为compile或漏掉<annotationProcessorPaths>; - 后果:IDE(如 IntelliJ)可能因 Maven 导入逻辑误判而“看起来能用”,但命令行
mvn compile会静默跳过处理器; - 注意:
annotationProcessorPaths中的 JAR 不会参与编译期类型检查,仅用于执行process()方法。
IntelliJ IDEA 中手动配置 Processor Path 的位置
即使 Maven 配置正确,IntelliJ 默认仍可能用自己的注解处理器机制覆盖它——尤其当你改过模块设置或用了多配置文件时。
- 打开
Settings (Ctrl+Alt+S)→Build, Execution, Deployment→Compiler→Annotation Processors; - 勾选
Enable annotation processing; - 取消勾选
Obtain processors from project classpath(这是关键!否则 IDEA 会忽略你写的annotationProcessorPaths); - 勾选
Processor path,点击右侧...,添加你实际使用的处理器 JAR(例如lombok-1.18.34.jar); - 路径必须指向本地磁盘上的 JAR 文件,不能是 Maven 仓库坐标;
- 若使用多个模块,确认当前模块关联的是你刚创建的注解处理器配置文件,而非默认配置文件。
常见坑:Processor path 设了但没取消 Obtain processors from project classpath,导致 IDEA 仍从 lib/ 或 target/classes 扫描,结果加载了旧版或冲突的处理器。
Gradle 项目中用 annotationProcessor 配置块
Android 或纯 Java Gradle 项目必须用 annotationProcessor 配置,它本质是把依赖加到 -processorpath,同时排除运行时传递依赖。
- Kotlin DSL(
build.gradle.kts)示例:
dependencies {
// 注解定义(如 @Loggable)可放 compileOnly
compileOnly("org.projectlombok:lombok:1.18.34")
<p>// 处理器实现必须用 annotationProcessor
annotationProcessor("org.projectlombok:lombok:1.18.34")</p><p>// MapStruct 同理
compileOnly("org.mapstruct:mapstruct:1.5.5.Final")
annotationProcessor("org.mapstruct:mapstruct-processor:1.5.5.Final")
}- 不要用
implementation或api引入处理器,否则会出现在 runtime classpath; - 若需传参数(如
mapstruct.defaultComponentModel=spring),必须用options块,且值必须是字符串字面量(不能是变量); - Gradle 8.0+ 对
annotationProcessor的依赖解析更严格,若提示Could not resolve processor,先检查仓库是否包含该 JAR(有些私有仓库会过滤-processor后缀的 artifact)。
最易被忽略的一点:OpenJDK 自身不提供任何注解处理器,所有路径都得你手动指定——哪怕只是 lombok 这种看似“内置”的工具,它的 JAR 必须真实存在并被 -processorpath 显式引用,否则编译器连 @Getter 都看不到。


















