jdeps 扫描 jar 包最可靠,需加 --multi-release 和 --ignore-missing-deps 参数;输出模块列表反映字节码真实依赖,非 pom.xml 或 import 所示;运行验证才是最终依据。

用 jdeps 扫描 jar 包,识别实际依赖模块
直接运行 jdeps 是最可靠的第一步,它不依赖项目是否模块化,也不需要改代码或加配置。关键在于传对参数——尤其要指定 --multi-release 和 --ignore-missing-deps,否则容易漏模块或报一堆“找不到类”的干扰错误。
-
jdeps --multi-release 17 --ignore-missing-deps --print-module-deps your-app.jar:输出一行逗号分隔的模块名,比如java.base,java.logging,java.net.http - 如果应用依赖多个 jar(如 lib/ 下一堆第三方包),把它们全列进去:
jdeps ... lib/*.jar your-app.jar;路径通配符在 Windows PowerShell 或 Linux/macOS shell 中都有效 - 若输出为空或只有
java.base,大概率是没加--multi-release,导致 jdeps 忽略了 Java 9+ 的多版本 class 文件逻辑
为什么不能只看 pom.xml 或 import 语句
Spring、Jackson、Logback 这类框架大量使用反射和动态类加载,import 看不到它们内部调用的模块(比如 java.desktop 里的 java.beans,或 jdk.unsupported 里的 Unsafe)。pom.xml 声明的是编译期依赖,而 jdeps 分析的是字节码里真实触发的模块引用——这才是 jlink 能打包的依据。
- 常见“隐形依赖”:
java.management(Spring Boot Actuator)、jdk.unsupported(Netty、Lombok)、java.sql(即使你用 HikariCP,jdeps 也能抓到 JDBC 驱动的模块链) - 加
--jdk-internals可额外标出用了哪些 JDK 内部 API,这类模块必须显式加入--add-modules,否则运行时报NoClassDefFoundError
jdeps 输出结果不准?补救方法
输出的模块列表只是“静态扫描结果”,不代表 100% 覆盖所有运行时路径。比如条件反射、SPI 加载、测试代码残留等,jdeps 不会执行代码,只能靠后续验证兜底。
- 先按 jdeps 结果生成最小 jre:
jlink --module-path $JAVA_HOME/jmods --add-modules java.base,java.logging,java.net.http --output myjre - 用新 jre 启动应用:
myjre/bin/java -jar your-app.jar - 启动失败时,错误信息里明确提示缺哪个类 → 查这个类属于哪个模块(查 Java 17 Javadoc 或用
jdeps -s -v *.jar | grep 类名)→ 把对应模块加进--add-modules重试 - 别试图用
--exclude-files或手动删 jmods 目录,jlink 的闭包计算是原子的,破坏结构会导致无法启动
非模块化项目特别注意的坑
没有 module-info.class 的传统项目,jdeps 默认不会递归分析传递依赖,必须强制开启 --recursive 或组合使用 --list-deps 多轮探测。
- 推荐流程:
jdeps --list-deps your-app.jar看基础依赖 → 把输出的模块代入jdeps --print-module-deps --multi-release 17 lib/*.jar再扫一遍第三方库 - 避免用
--class-path指向整个lib/目录:某些旧版 jar(如 log4j 1.x)含无效 manifest 或损坏 class,会让 jdeps 崩溃;逐个或分批处理更稳 - Windows 用户注意路径分隔符:
--module-path %JAVA_HOME%\jmods,别写成正斜杠,否则 jlink 会静默忽略模块路径


















