Spring Boot项目Maven compile无详细报错编译失败排查
执行Spring Boot项目构建命令mvn clean install -DskipTests=true时构建失败,仅提示org.apache.maven.plugins:maven-compiler-plugin:3.8.0:compile (default-compile)阶段Compilation failure,无任何具体错误细节。
追加-e参数重跑命令打印异常栈,仅输出org.apache.maven.lifecycle.LifecycleExecutionException、org.apache.maven.plugin.compiler.CompilationFailureException两类异常,依然没有具体编译错误信息。
临时解决方案:在maven-compiler-plugin配置中添加如下配置后项目可正常构建:
<executable>${env.JAVA_11_HOME}/bin/javac</executable>
但存在两个核心疑问:
- 同一份代码,其他同事不需要添加上述
executable配置即可正常构建,仅本地设备出现该问题 - 本地其他代码库也不需要在maven-compiler-plugin中添加该配置就能正常编译
需要定位问题根因,给出本地环境修复方案,实现无需额外添加配置即可正常构建。
本地已完成排查操作
- 所有Maven命令均通过系统控制台执行,未使用IDE内置终端
- 已尝试切换Oracle JDK、Redhat Open JDK 11.0.5版本,问题依然复现
- 已尝试Maven 3.8.5、3.8.1两个版本,均按照Windows官方安装指南部署,问题依然复现
- 尝试使用IntelliJ IDEA内置Maven插件构建,未添加
executable配置时仍报相同错误
该问题本质是本地环境异常导致Maven编译器插件无法捕获JDK内置编译API的输出流:maven-compiler-plugin 3.8.0默认不调用本地javac.exe可执行文件,而是通过JDK提供的javax.tools.JavaCompiler接口执行编译操作,当该接口的输出流因为本地环境问题被截断、无法被Maven进程读取时,就会只返回编译失败的笼统提示,不输出具体错误内容。
添加executable配置后,插件会跳过内置API调用逻辑,直接拉起独立的javac.exe进程执行编译,绕过了输出流捕获的异常环节,因此可以正常构建。
仅本地设备触发该问题,是因为需要同时满足本地独有的触发条件:
- Windows系统默认的Oracle Java软链接路径优先级高于自定义的JDK配置,导致Maven启动时加载的JVM版本和
JAVA_HOME指向的JDK11版本不一致,调用内置编译API时出现版本冲突,输出流直接中断 - 系统默认编码和Maven、JDK使用的编码不匹配,读取编译输出内容时触发解码异常,Maven无法拿到具体错误文本
- 本地安装的杀毒软件、Java监控Agent、老旧Java补丁程序注入了Java进程,干扰了内置编译API的正常输出逻辑
按顺序操作,每一步完成后可直接测试构建是否恢复:
- 清理PATH环境变量优先级冲突
打开系统环境变量配置面板,在系统PATH列表中删除C:\Program Files\Common Files\Oracle\Java\javapath、C:\ProgramData\Oracle\Java\javapath这类Oracle默认生成的软链接路径,或者将自定义的%JAVA_HOME%\bin路径移动到PATH列表的最顶端。
配置完成后打开新的控制台,分别执行where java和where javac,确认两个命令返回的第一个路径都是目标JDK11的bin目录下的可执行文件,无其他版本的Java相关程序排在前面。 - 配置Maven全局编译参数
打开本地Maven安装目录下的conf/settings.xml,在<profiles>节点下添加全局JDK11配置,强制所有项目默认使用JDK11和UTF-8编码编译,避免插件默认参数和本地环境不兼容:<profile> <id>jdk-11</id> <activation> <activeByDefault>true</activeByDefault> <jdk>11</jdk> </activation> <properties> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> <maven.compiler.encoding>UTF-8</maven.compiler.encoding> </properties> </profile> - 修复编码匹配问题
如果不想修改系统全局配置,可以在每次执行Maven命令前先执行set MAVEN_OPTS=-Dfile.encoding=UTF-8,临时指定Maven进程使用UTF-8编码;也可以打开Windows系统区域设置,勾选「Beta版:使用Unicode UTF-8提供全球语言支持」后重启设备,一劳永逸解决编码不匹配问题。 - 排查进程干扰
临时关闭杀毒软件、Java性能监控工具、第三方Java补丁类程序后测试构建,如果恢复正常,将JDK安装目录、Maven安装目录、项目代码目录加入对应程序的白名单即可。
内容的提问来源于stack exchange,提问作者Vishnu

