构建插件(如maven-compiler-plugin)仅认pom.xml中显式配置的source/target/release或Gradle中的toolchain,不依赖JAVA_HOME或终端java版本;JDK 17最低支持Java 8字节码,需统一设为17或兼容值8,并在IDEA中同步模块Language level,Gradle项目须明确配置java.toolchain。

构建插件(比如 maven-compiler-plugin)用的还是旧 JDK,不是你本地装的新 JDK——它压根不看 JAVA_HOME 或终端里的 java -version,只认自己配置的 source 和 target,或者更隐蔽的 release 参数。只要这些值低于当前 JDK 支持下限(JDK 17 最低只认 8),就会直接报错,比如 “不支持发行版本 6” 或 “JVM target 5”。
检查 pom.xml 里 maven-compiler-plugin 的 source/target 配置
这是最常见、也最容易被忽略的源头。很多老项目在 pom.xml 里硬编码了过时版本:
-
或1.6 → JDK 17 已彻底移除对 Java 5/6 的支持5 -
→ 同样不被接受,javac 直接拒绝执行1.6 - 如果用了
,注意它比source/target更严格:JDK 17 支持到8 ,但17 就会失败7
修复方式很简单:统一改成与你实际 JDK 主版本一致的值,例如 JDK 17 就写 17;若需兼容旧 JVM 运行环境,最低只能设为 8。
确认 Maven 是否加载了插件默认配置而非你的显式声明
有些项目没显式声明 maven-compiler-plugin,但依然报错——那是因为 Maven 3.8+ 自带的默认插件版本(如 3.10.1)会根据 Maven 自身运行的 JDK 推断 source/target。如果你用 JDK 17 运行 Maven,它可能自动设成 17;但如果你用 JDK 8 运行 Maven(哪怕项目里写了 ),插件会降级适配,导致构建产物字节码版本不一致,后续在 JDK 17 环境运行时报 Unsupported class file major version 61。
验证方法:
- 执行
mvn -v,看输出的Java version:是不是你预期的 JDK 版本 - 执行
mvn help:effective-pom | grep -A 5 "maven-compiler-plugin",确认最终生效的source/target值 - 若发现是默认值作祟,必须在
pom.xml中显式声明插件并锁定参数,不能依赖推断
IDEA 里模块 Language level 覆盖了 Maven 配置
IntelliJ IDEA 的模块设置(.iml 文件或 Project Structure → Modules)有独立的 Language level,它会覆盖 pom.xml 的声明——尤其是当你右键模块 → “Reload project” 后,IDEA 可能按旧缓存重置该值。
典型表现:
- Maven 命令行构建成功,但 IDEA 编译报
Cannot compile module 'xxx' configured for JVM target 5 - 你在 Project Structure → Project 里改了 Language level,但某个模块仍显示灰色不可编辑,说明它被单独设置了
- 修改后重启 IDEA 无效,因为
.idea/modules.xml或xxx.iml里还存着旧值
解决办法:
- 进 Project Structure → Modules → 选中对应模块 → 右侧 Language level 下拉选正确版本(如
17) - 勾选 “Inherit project settings”(如果想统一用 Project 级别)
- 删掉
.idea/modules.xml和对应.iml文件,再 Reload project(慎用,会丢自定义模块依赖)
Gradle 项目要同步检查 compileOptions 和 JVM Toolchain
Gradle 的行为和 Maven 不同:从 Gradle 6.7 开始,推荐用 java-toolchain 指定编译器 JDK,而不是只靠 sourceCompatibility。如果只改了 sourceCompatibility = JavaVersion.VERSION_17,但没配 toolchain,Gradle 仍可能调用系统默认 JDK(比如旧版 JDK 8)来跑编译任务,导致生成的 class 文件版本错乱。
正确写法示例:
java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
关键点:
-
toolchain决定用哪个 JDK 的javac,优先级高于JAVA_HOME - 如果 CI 上报
Unsupported class file major version 61,大概率是这里没配 toolchain,导致用了 JDK 11 编译却声称产出 17 字节码 - Android 项目还要额外检查
android.compileOptions,它和顶层java块是两套逻辑,必须同时对齐
真正容易被忽略的是:构建插件的 JDK 和你“以为它在用”的 JDK 完全是两回事。它不读环境变量,不继承 IDE 设置,甚至不关心你终端里敲的是哪个 java。唯一可信的,只有配置文件里白纸黑字写的 source、target、release 或 toolchain —— 其他全是幻觉。











