必须显式声明 maven-compiler-plugin 版本,因默认版本可能不支持所设 Java source/target;推荐用 <release> 统一约束语法、字节码和类路径,并配合 <pluginManagement> 实现多模块正确继承。

为什么 maven-compiler-plugin 版本必须显式声明
不写版本,Maven 会按生命周期绑定默认版本(比如 Maven 3.8+ 默认用 maven-compiler-plugin:3.8.1),但这个默认值不保证支持你写的 source 和 target。比如你设了 source="17",却没指定插件版本,老插件直接报错:Unsupported target release: 17。
根本原因是:Java 语言级别和插件能力是解耦的。插件得自己实现对新语法、新字节码版本的支持。
- Java 11+ 项目必须用
maven-compiler-plugin≥ 3.8.0 - Java 17+ 推荐用 ≥ 3.11.0(修复了 record、sealed class 的编译问题)
- Maven 3.9.0+ 自带插件是 3.12.1,但旧项目可能仍继承父 POM 的低版本
maven-compiler-plugin 的 source 和 target 到底填什么
这两个参数不是“你想用啥就填啥”,它们受插件版本和 JDK 安装限制。填错最常见现象是:编译通过但运行时报 java.lang.UnsupportedClassVersionError。
正确做法是让三者对齐:
- 本地
JAVA_HOME指向的 JDK 版本 -
<source>和<target>值(推荐统一用<release>) -
maven-compiler-plugin版本是否支持该release
更安全的写法是用 <release> 替代 source/target:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.12.1</version>
<configuration>
<release>17</release>
</configuration>
</plugin><release> 会自动约束源码语法 + 字节码版本 + 启动类路径,避免跨 JDK 编译时的隐性兼容问题。
IDE(IntelliJ / Eclipse)不认 pom.xml 里的 compiler 配置
IDE 不会自动同步 maven-compiler-plugin 的 source/target 设置,尤其当你只改了插件配置但没更新项目 SDK 时,IDE 仍用默认 1.5 或 1.8 编译,导致「Maven 能编,IDE 报红」。
必须手动同步两处:
- 在 IntelliJ:File → Project Structure → Project → Project SDK 和 Project language level 保持一致
- 在 Eclipse:右键项目 → Properties → Java Build Path → Libraries → 双击 JRE System Library → 选对应 JDK;再进 Java Compiler 页面勾选「Enable project specific settings」并设 Compiler compliance level
- 执行
mvn clean compile后,再刷新 IDE 项目(IntelliJ 用 Maven → Reload,Eclipse 用 Maven → Update Project)
多模块项目里子模块编译失败,但父 pom 已配 plugin
父 pom 中的 maven-compiler-plugin 配置默认不会继承给子模块——除非你把它放在 <build><pluginManagement> 里,且子模块显式声明 <plugins> 引用它。
典型错误写法(父 pom):
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.12.1</version>
<configuration><release>17</release></configuration>
</plugin>
</plugins>
</build>这样只作用于父模块本身。子模块要生效,必须:
- 把插件移到父 pom 的
<build><pluginManagement>下 - 每个子模块的
<build><plugins>里加一个无配置的引用:<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> </plugin>
最常被忽略的是 <release> 和 <pluginManagement> 的配合关系:不放 pluginManagement,多模块里一半模块编译成功、一半失败,查半天才发现只是继承没做对。










