Java基础、中级、高级、架构面试资料

AI 写了大量代码,却从不清理所有僵尸依赖

JAVA herman 13浏览
公告:“业余草”微信公众号 AI 中转站提供免费体验,点击链接 https://unity2.ai/register?ref=3XTnndN2 进行访问,支持 Claude、ChatGPT、Gemini 等最新模型!关注业余草微信公众号,添加作者微信:xttblog2!
本博客日IP超过2000,PV 3000 左右,急需赞助商。
极客时间所有课程通过我的二维码购买后返现24元微信红包,请加博主新的微信号:xttblog2,之前的微信号好友位已满,备注:返现
受密码保护的文章请关注“业余草”公众号,回复关键字“0”获得密码
所有面试题(java、前端、数据库、springboot等)一网打尽,请关注文末小程序
视频教程免费领
【腾讯云】1核2G5M轻量应用服务器50元首年,高性价比,助您轻松上云

最近有个项目的依赖版本太低了,运维说有漏洞,让升级一下。其实是包太大了,编译太慢了。

我看了邮件,发行是一个很早的漏洞了,但这并不重要,因为这个邮件发了好几次了,没啥人关注。后来,我追问了一下,其实是包太大了,编译太慢了。

回想以前,我是习惯性的使用 dependency:tree 来搞定目标问题,现在有了 AI 真的是太方便了,以至于某些命令和插件都忘记了,这其中就包括 maven-dependency-plugin,年轻的同事们已经不认识它了。

要知道,现在的 Java 项目,Maven 依赖治理不再是可选项,而是每个 Java 项目的必修课。而 Maven 官方提供的 maven-dependency-plugin,正是这场治理战役中最基础、也最锋利的手术刀。接下来,我们就来看看这个 maven-dependency-plugin 深度实战指南吧。

文章配图参见 https://mp.weixin.qq.com/s/I4Vkrw2sZcb8gqSZglyzNw

冷门插件

在 Java 开发中,我们习惯了在 pom.xml 里写下几行坐标,Maven 就会自动从中央仓库拉取依赖。这种“开箱即用”的便利背后,隐藏着一个巨大的盲区,你真正引入的依赖,可能比你声明的多出十倍不止

根据这几年 OWASP 软件成分分析报告显示,92% 的 Java 应用包含至少 1 个有漏洞的第三方依赖,其中 38% 存在高危及以上漏洞。更可怕的是,这些漏洞有相当一部分并非来自你直接引入的依赖,而是来自传递依赖(Transitive Dependencies),你引入的 A 依赖了 B,B 又依赖了 C,而 C 恰好是一个存在 CVE 漏洞的旧版本。

这就是 maven-dependency-plugin 存在的意义,它不提供漏洞扫描,但它提供“透视能力”,让你看清依赖树的全貌,找到问题的根因。

更何况现在很多项目的多数代码都是 AI 写的,它只管写,不管治理,稍不注意,他们引入了一个 opencv 的包,导致编译后整个项目体积巨增。

三个命令解决 80% 的依赖问题

遇到这种情况,maven-dependency-plugin 就可以派上用场了。

它是 Maven 官方插件,无需额外安装,直接在命令行或 pom.xml 中配置即可使用。下面说三个最常用、也最有价值的命令。

dependency:tree

这是最常用的命令。当你收到安全团队的告警,说项目中存在某个漏洞依赖,但你在 pom.xml 里根本找不到它时,这个命令就是你的救命稻草。它能透视依赖树,定位漏洞来源

# 查看完整依赖树
mvn dependency:tree

# 过滤特定依赖(如查找 log4j-core 的引入路径)
mvn dependency:tree -Dincludes=org.apache.logging.log4j:log4j-core

# 调试模式,显示更详细的解析过程
mvn dependency:tree -Dincludes=org.springframework:spring-web -X

比如,一个老项目被扫描出 spring-web:5.3.13 存在 CVE-2022-22947 漏洞。我们只需在 pom.xml 中并未直接引入 spring-web,通过执行 mvn dependency:tree 命令就可以发现问题所在。

[INFO] +- org.springframework.boot:spring-boot-starter-web:jar:2.6.0:compile
[INFO] |  \- org.springframework:spring-web:jar:5.3.13:compile

原来漏洞是通过 spring-boot-starter-web 传递引入的。定位问题后,只需升级 starter 版本,或在 dependencyManagement 中强制指定安全版本即可修复。

dependency:analyze

一些项目经过长期迭代,往往会积累大量不再使用的依赖。这些“僵尸依赖”不仅增加构建时间,还可能引入不必要的安全风险。而 dependency:analyze 命令则能发现“僵尸依赖”,精简项目。

# 分析未使用的依赖
mvn dependency:analyze

输出示例:

[WARNING] Unused declared dependencies found:
[WARNING]    org.apache.commons:commons-lang3:jar:3.12.0:compile

在 CI/CD 流水线中定期执行此命令,结合 dependency:analyze-dep-mgt 检查依赖管理中的冗余声明,保持 pom.xml 的整洁。尤其是现在 AI 写了大量的代码,它几乎从来不移除无用的依赖。

copy-dependencies

在某些场景下,你需要将依赖的 JAR 包复制到特定目录,或生成 classpath 文件用于脚本启动,这是就可以使用copy-dependenciesbuild-classpath 构建产物管理了。

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>3.6.1</version>
    <executions>
        <execution>
            <id>copy-dependencies</id>
            <phase>package</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
                <outputDirectory>${project.build.directory}/lib</outputDirectory>
                <includeScope>runtime</includeScope>
            </configuration>
        </execution>
    </executions>
</plugin>

这在构建 Docker 镜像、制作可分发包或排查类加载问题时非常有用。

使用场景

maven-dependency-plugin 也不是非用不可的,它主要能解决以下四类问题。

首先是传递依赖漏洞的“精准手术”。当扫描工具(如 OWASP Dependency-Check)报告漏洞时,我们需要知道这个依赖是从哪条路径引入的?能否通过升级直接依赖来间接修复?如果无法升级,如何精确排除漏洞依赖?

其次是,版本冲突的“仲裁庭”。当项目中出现 ClassNotFoundExceptionNoSuchMethodError,往往是依赖版本冲突导致。dependency:tree 配合 analyze-duplicate 能快速定位。

接着是依赖锁定与构建一致性。尤其是在团队协作中,防止“在我机器上能跑”的问题。通过 dependency:resolvedependency:go-offline 可以预下载所有依赖,确保构建环境一致。

最后是与漏洞扫描工具的“协同作战”。maven-dependency-plugin 本身不扫描漏洞,但它是 OWASP Dependency-Check、Snyk 等工具的完美搭档,三者形成“发现 → 定位 → 修复”的闭环。

总结

maven-dependency-plugin 不是银弹,它不会告诉你哪个依赖有漏洞,但它赋予你看清依赖结构的能力。在软件供应链攻击频发的今天(如 2024 年初的 MavenGate 攻击通过废弃库劫持依赖),这种能力至关重要。

从“被动修复”到“主动防御”,没有银弹。没有绝对安全的依赖,只有不断完善的安全体系

业余草公众号

最后,欢迎关注我的个人微信公众号:业余草(yyucao)!可加作者微信号:xttblog2。备注:“1”,添加博主微信拉你进微信群。备注错误不会同意好友申请。再次感谢您的关注!后续有精彩内容会第一时间发给您!原创文章投稿请发送至532009913@qq.com邮箱。商务合作也可添加作者微信进行联系!

本文原文出处:业余草: » AI 写了大量代码,却从不清理所有僵尸依赖