老炮踩坑录 · 番外篇 · 翻车现场系列
基于「基础企业档案」真实项目代码,复盘一次"命令行构建正常、IDEA 里依赖全红"的排查
关键词:IDEA · Maven · User settings file · override · 本地仓库
👋 欢迎阅读
🏠个人主页:知守观
📘我的专栏: 老炮踩坑录
💻当前内容:Maven 依赖全红排查
前言
上一篇把 CI 的 settings.xml 改对了,mirrorOf 排除了私服,命令行构建恢复正常。
我以为这事算翻篇了,然后打开 IDEA 准备写代码,但是依赖列表却一片红。
现象:命令行一切正常,IDEA 却不认
具体表现:IDEA 右侧 Maven 工具窗口里,base-archives-web 的 Dependencies 下面,base-archives-common 标红,代码里 import 它的类全部报错。
同一个项目,同一份 pom,终端里执行命令 mvn clean package 是 BUILD SUCCESS 的呀。
我按老经验处理:在Maven 工具窗口点 Reload下,没用;File → Invalidate Caches 清缓存重启,也没用;把 .idea 目录删了重新导入,还是标红。
到这里可以排除缓存问题。IDEA 用的 Maven 配置和命令行的不一样,只是我还不知道差在哪里。
排查:让 IDEA 自己交代它用的是哪份配置
命令行的配置我能确认:
mvn -v
输出里 Maven home 是 D:\Maven,settings 用的是 D:\Maven\conf\settings.xml,本地仓库 D:\Maven\repertory。这份 settings 就是上一篇刚改对的那份。
再看 IDEA。File → Settings → Build, Execution, Deployment → Build Tools → Maven,这一页的三个配置:
D:\dev\apache-maven-3.5.4 这个目录已经不存在了。两年前我把 Maven 挪到了 D:\Maven,旧目录整个删掉了。
设置页里那个 Override 勾选还留着,指向一个空路径。
原因:IDEA 的 Maven 配置是独立的一套
命令行的 Maven 用的是自己安装目录下的 conf/settings.xml。IDEA 不读这个,它有自己的三个配置项,Maven home、settings 文件、本地仓库,都可以单独指定。
我当时面对的情况是:
- 命令行:Maven home 在
D:\Maven,settings 是改对的那份,私服配置齐全,构建正常。 - IDEA:Maven home 用的是自带的 Bundled Maven,settings 指向一个不存在的文件。
如果文件不存在,IDEA 会怎么处理呢?它没有任何报错弹窗,设置页安安静静。实际效果是私服配置全没了——公司私服的地址、认证、镜像排除规则都写在那份 settings 里,文件找不到,这些配置全都不生效。内部依赖解析不到,所以都标红。
至于文件缺失时 IDEA 具体回退到哪份配置,我试过几个版本,表现不完全一样,有的版本会在 build 日志里留一行警告,有的版本完全静默。我没有逐版本验证过,能确认的只有两点:它不会明着告诉你文件不存在,也绝不会去用你命令行那份。
这个 Override 是什么时候勾上的,我完全没有印象。大概率是两年前换 Maven 目录之前配的,当时指向的还是真文件。后来目录删了,勾选留着,地雷就埋下了。两年间为什么没爆?因为那两年我没怎么在 IDEA 里跑 Maven 构建,命令行用得更多,冲突没机会出现。这次换电脑迁移环境,两头配置文件都动了,才撞上。
验证方法很简单,看设置页 Local repository 那一栏显示的值。它从 IDEA 认为的 settings 里解析出来,显示的路径和你预期的不一样,配置就有问题。我当时看到的是默认的 C:\Users\xxx.m2\repository,而不是 D:\Maven\repertory,一眼就明白了。
有个细节我没完全确认:IDEA 在 User settings file 指向的文件不存在时,不同版本的回退行为到底有没有差异?我试过几个版本,有的会在build日志里留一行警告,有的完全静默。具体哪些版本会警告,我没逐个验证过,有踩过坑的兄弟评论区指点一下。
修复
三处全部对齐到命令行的配置:
我把
D:\Maven\conf\settings.xml 复制了一份到 C:\Users\xxx.m2\settings.xml,让默认路径也有正确配置。这样命令行、IDEA、以及任何用默认路径的工具,读到的是同一份内容。
改完点 Maven 工具窗口的 Reload,红线就消失了。
也有人选择保留 Override、直接指向 D:\Maven\conf\settings.xml,效果一样。我倾向取消勾选走默认路径,理由是少一个需要记住的自定义项——这台机器上非标准的配置越少,下次换电脑迁移时漏掉的东西越少。
这个坑为什么难排查
IDEA 全程沉默。文件不存在这种明摆着的问题,它不在任何显眼的地方提示。Reload 正常转圈,缓存正常清,导入正常跑,只有依赖解析失败这一个下游症状。
常规操作全部失效,反而强化了误判。Reload、清缓存、重新导入这三件事解决的是索引和缓存问题,对配置路径问题一点用都没有。可大多数人(包括我)遇到 IDE 异常,肌肉记忆就是先按这三下,按完没用,开始怀疑项目本身。
时间跨度抹掉了因果关系。勾选 Override 是两年前的操作,目录删除也是两年前的操作,故障今天才出现。没人会把今天的红线和两年前的一次设置改动联系到一起。
命令行的正常表现掩护了它。上一篇刚改对 settings.xml,命令行验证通过,"settings 是对的"这个结论已经建立了。IDEA 出问题,思维定势是"IDEA 又出毛病了",很少有人回头想:IDEA 用的可能根本不是刚改对的那份。
自查清单
自查打卡:打开IDEA的
Settings → Maven,看看User settings file那一栏,Override勾选了吗?路径存在吗?打在评论区,我看看谁的配置最“干净”。
老炮点评
IDE 和命令行各用各的配置,这种问题排查起来费劲,预防起来倒简单:让两边用同一份配置。Maven home 指同一个,settings 用同一份,本地仓库用同一个。机器上少一份自定义配置,就少一个两年后炸的雷。
环境迁移是这类问题的高发期。换新机、重装系统、升 IDE 大版本之后,构建工具和 IDE 的配置值得花十分钟对一遍——这十分钟能省掉后面好几天的"明明改对了为什么没用的问题"。
最后问一句:你平时构建项目,是命令行用得多,还是IDEA里点得多?有没有遇到过两边行为不一致的情况?评论区聊聊,我看看有多少人被IDEA的配置坑过。
下期预告:《pom 里写的 2.0,跑起来的是 1.5》
依赖里明明声明了新版本,
dependency:tree里它却挂着一行omitted for conflict。启动直接 NoSuchMethodError,方法明明在新版本的源码里。下期讲 Maven 的版本仲裁规则:路径最近优先、声明顺序兜底,以及怎么用
dependencyManagement把版本钉死。
如果本文对你有帮助,欢迎:
👍 点赞 | ⭐ 收藏 | 👤 关注| 💬 留言
我是老炮,Java 老兵,仍在一线。关注「Java老炮踩坑录」,看真实案例,少踩坑。