JDK21 升级后编译错误:JCImport 缺少 qualid 字段的解决方法
关键问题
升级到 JDK 21 后遇到 NoSuchFieldError: Class com.sun.tools.javac.tree.JCTree$JCImport does not have member field 'com.sun.tools.javac.tree.JCTree qualid
编译错误?根本原因是 Lombok 版本与 JDK 21 不兼容,需要升级相关依赖。
问题分析
当 Spring Boot 项目从低版本 JDK 升级到 JDK 21 时,可能遇到以下编译错误:
Fatal error compiling: java.lang.NoSuchFieldError:
Class com.sun.tools.javac.tree.JCTree$JCImport does not have member field 'com.sun.tools.javac.tree.JCTree qualid'
此错误由以下因素触发:
- Lombok 依赖版本过低(< 1.18.30)
- 项目使用了过时的 Spring Boot 版本(< 3.1.4)
- 编译器配置未正确指向 JDK 21
- Maven/Gradle 未正确同步依赖
根本原因是 JDK 21 修改了内部 API 结构,旧版 Lombok 依赖的 JCImport.qualid
字段在新版 JDK 中已被移除。
解决方案一览
✅ 推荐方案:升级 Lombok 和 Spring Boot
更新 Lombok 至 1.18.30+ 并同步升级 Spring Boot 至 3.1.4+
<properties>
<java.version>21</java.version>
<spring-boot.version>3.2.3</spring-boot.version> <!-- 推荐使用最新稳定版 -->
<lombok.version>1.18.32</lombok.version> <!-- 必须 ≥1.18.30 -->
</properties>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
<!-- 父模块 -->
<properties>
<java.version>21</java.version>
<spring-boot.version>3.4.3</spring-boot.version>
</properties>
<!-- 子模块 -->
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<spring-boot.version>3.4.3</spring-boot.version> <!-- 与父模块一致 -->
</properties>
🔧 修复 Spring Boot Maven 插件
在插件中显式排除 Lombok 依赖:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
⚡ 快速修复(不推荐)
仅升级 Lombok 版本(适合无法升级 Spring Boot 的项目):
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version> <!-- 最小兼容版本 -->
<scope>provided</scope>
</dependency>
警告
此方案可能导致 Spring Boot 管理依赖冲突,仅作为临时解决方案
完整解决方案步骤
1. 升级核心依赖
在 pom.xml
中进行三处关键修改:
<!-- 设置JDK版本 -->
<properties>
<java.version>21</java.version>
<!-- [推荐]使用Spring Boot 3.2.x+ -->
<spring-boot.version>3.2.3</spring-boot.version>
<!-- [必须]Lombok ≥1.18.30 -->
<lombok.version>1.18.32</lombok.version>
</properties>
<!-- Lombok依赖声明 -->
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
<!-- Maven编译器配置 -->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>21</source>
<target>21</target>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
2. 多模块项目特殊处理
确保所有子模块使用相同的 Spring Boot 和 Lombok 版本:
<!-- 父模块定义 -->
<properties>
<spring-boot.version>3.4.3</spring-boot.version>
<lombok.version>1.18.32</lombok.version>
</properties>
<!-- 子模块覆盖 -->
<properties>
<!-- 显式继承父级版本 -->
<spring-boot.version>${parent.spring-boot.version}</spring-boot.version>
<lombok.version>${parent.lombok.version}</lombok.version>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
</properties>
3. IDE 同步与清理
执行以下操作彻底更新依赖:
- Maven:执行
mvn clean install -U
- IntelliJ:
- 右键点击
pom.xml
→ Maven → Reload Project - 菜单 → File → Invalidate Caches → 清除缓存
- 右键点击
- Eclipse:右键项目 → Maven → Update Project
原理说明
此问题的核心是 JDK 21 的 API 变动破坏了旧版 Lombok (≤1.18.28) 的兼容性:
- Lombok 内部调用了
JCImport.qualid
字段 - JDK 21 移除了该字段(Lombok Issue #3393)
- Lombok 1.18.30+ 修改实现以适应新API
最佳实践
- 优先升级 Spring Boot 至最新稳定版(当前推荐3.2.x+)
- 同步升级 Lombok 到 ≥1.18.30
- 避免手动覆盖版本(除非有特殊兼容需求)
问题排查清单
若问题仍未解决,请检查:
- [ ]
mvn dependency:tree | find "lombok"
确认实际使用版本 - [ ] IDE 中项目结构设置(确认JDK 21被正确选用)
- [ ] 所有模块的Java编译器版本一致性
- [ ] Lombok注解处理器是否启用
升级后测试建议:由于Spring Boot各版本行为差异,建议执行完整集成测试,特别关注依赖注入和Bean加载行为。