第3章 依赖树分析工具
3.1 gradle dependencies 命令详解
gradle dependencies 是 Gradle 内置的依赖树命令,以树形结构展示项目所有配置(compileClasspath、runtimeClasspath、testCompileClasspath 等)下的直接与传递依赖。在大型多模块项目中,该命令是发现冲突、冗余和循环依赖的首选入口。
提示:在
build.gradle 或 settings.gradle 中添加 --scan 参数可生成在线构建扫描报告,包含更多依赖分析维度。常用变体命令
| 命令 | 作用域 | 输出内容 |
|---|---|---|
gradle dependencies | 默认配置 | 列出所有配置(compile、runtime、test 等)的完整树 |
gradle dependencies --configuration runtimeClasspath | 指定配置 | 仅输出 runtimeClasspath 的依赖树 |
gradle :subproject:dependencies | 子项目 | 只打印指定子项目的依赖树 |
gradle dependencies --offline | 离线模式 | 使用本地缓存输出,跳过网络解析 |
输出格式解读
+--- com.example:lib-core:1.0.0
| | +--- com.example:lib-utils:1.2.0
| | | \--- org.slf4j:slf4j-api:1.7.30
| | \--- com.fasterxml.jackson:jackson-core:2.12.3
| | \--- (c) com.fasterxml.jackson:jackson-annotations:2.12.3
| \--- (x) com.example:lib-deprecated:0.9.0 -> 1.0.0
\--- junit:junit:4.13.2 (testRuntimeClasspath)
符号含义:+--- 表示第一个直接依赖,\--- 表示最后一个直接依赖,| 表示延续父级分支。括号标识:(c) 表示冲突被解决(显示实际使用的版本),(x) 表示动态版本被解析。
3.2 在线依赖报告
Gradle 提供两种在线依赖报告方式:构建扫描(Build Scan) 和 Gradle Enterprise 依赖面板。构建扫描通过 --scan 参数上传至 scans.gradle.com,生成包含依赖树、模块版本、冲突统计的交互式 Web 页面。
gradle build --scan
# 终端输出:Publishing build scan...
# 点击链接:https://scans.gradle.com/s/abcd1234
在线报告优势:支持按模块搜索、展开/折叠、版本对比和冲突定位;可分享给团队成员,无需本地日志。Gradle Enterprise 还提供“依赖洞察”板块,自动标记冗余依赖和违规版本。
3.3 过滤冗余依赖
冗余依赖指同一个模块在依赖树中出现多次(不同版本)或强制被提升到更高版本后不再被使用的低版本分支。过滤冗余的流程包括:
- 使用
gradle dependencies --configuration compileClasspath > deps.txt导出完整树 - 通过
grep "->"或findstr "->"(Windows)筛选出有版本提升的依赖 - 使用
gradle dependencyInsight --dependency <模块名>分析单个库的版本选定原因 - 在
build.gradle中通过constraints或force消除无用的低版本分支
实际命令组合
# 列出所有被提升的依赖(版本冲突解决结果)
gradle dependencies | grep "->"
# 或使用 --scan 后在线查看 "Dependency versions" 面板
# 检查特定模块为何被选择 2.0.0 而不是 1.8.0
gradle dependencyInsight --dependency com.fasterxml.jackson:jackson-databind --configuration runtimeClasspath
关键指标:冗余依赖每消除一个,可减少构建解析阶段约 5%–15% 的元数据处理开销,并在多模块中降低插件冲突风险。
3.4 常见错误与调试
| 错误现象 | 可能原因 | 解决办法 |
|---|---|---|
| 依赖树输出为空 | 配置名称拼写错误或项目无该配置 | 检查 --configuration 参数是否正确,或先运行 gradle projects 确认模块路径 |
大量 -> 提升但构建失败 | 多个子模块声明了冲突版本,且存在不兼容的 API 变化 | 使用 dependencyInsight 定位冲突源,统一使用 constraints 锁定版本 |
| 在线扫描链接无法打开 | 企业环境禁止外网连接或 Gradle Enterprise 未配置 | 使用 --offline 本地分析,或在 gradle.properties 中设置代理 |
| 依赖树过大导致控制台截断 | 子模块过多或传递依赖深度过大 | 重定向到文件:gradle dependencies > full_tree.txt,再用编辑器搜索 |
注意:在 CI 环境中执行
gradle dependencies 可能因依赖解析超时(默认 30 分钟)而失败。建议设置 dependencyResolutionManagement.repositories 为本地镜像,并增加 org.gradle.internal.dependency.resolution.timeout=600000。