Page 154 - 《软件学报》2025年第7期
P. 154
孙伟杰 等: Java 依赖异味的实证研究与统一检测技术 3075
赖范围设置为 compile, 代表其在构建、运行和测试时都被使用, 但其预期依赖范围是 test, 代表其不应该在构建时
出现. 因此在 mod 进行构建时, 需要从中央存储仓库获取事实上不必要的 lib, 导致构建时间增加, 即增加构建成本.
(a) 危害 2
mod 声明了依赖库 lib, 但事实上未使用
依赖于
构建成本增加
模块 mod 依赖库 lib
构建时
构建时依赖库
在 mod 构建时,即使 lib 未被使用, 也会被引入
包括
依赖库 lib1
(b) 危害 5 mod 声明了依赖库 lib, 但事实上未使用
依赖于
构建产物冗余
模块 mod 依赖库 lib
被打包成可执行构件时
在 mod 打包成可执行构件时,
可执行构件 尽管 lib 未被使用, 也会被包括
包括 包括
模块 mod 依赖库 lib
(c) 危害 7 mod 声明了依赖库 lib, 但事实上未使用
依赖于 依赖于
下游模块构建成本增加
下游模块 client 模块 mod 依赖库 lib
构建时
构建时依赖库 在 client 构建时, 未使用的传递依赖 lib 被下载
包括
依赖库 lib
(d) 危害 9 mod 声明了依赖库 lib, 但事实上未使用
依赖于 依赖于
下游模块构建产物冗余
下游模块 client 模块 mod 依赖库 lib
被打包成可执行构件时
下游模块的构建产物引入了事实上
可执行构件 未使用的依赖库 lib
包括
包括 包括
模块 client 模块 mod 依赖库 lib
图 A7 异味 1.5 可能危害与对应触发场景
(3) 构建产物冗余: 以预期范围为 test, 实际范围为 compile 为例, 在图 A8(d) 中, 模块 mod 将直接依赖 lib 的依
赖范围设置为 compile, 但其实际上仅在测试时被使用, 预期依赖范围应为 test. 在 mod 打包为可执行 JAR 时, 所
有依赖范围为 compile 的依赖库都会被涵盖, 而会忽略依赖范围为 test 的依赖库, 这就导致 lib 被错误地包括进构
建产物中, 最终导致构建产物冗余.
(4) 下游模块构建时间增加: 以预期依赖范围为 implementation, 实际范围为 api 为例, 在图 A9(b) 中, 模块
mod 将依赖库 lib 的依赖范围设置为 api, 此范围意味着下游模块 client 在构建时引入 mod 就会同时引入 lib, 但
lib 仅用于 mod 内部实现, 其预期范围是 implementation, 不应该出现在 client 的构建时. 因此 client 在构建时需要
从中央存储仓库获取事实上不必要的 lib, 导致构建时间增加, 即增加构建成本.
(5) 下游模块运行时错误: 以预期依赖范围为 runtime, 实际范围为 test 为例, 在图 A9(c) 中, 模块 mod 将依赖
库 lib 的依赖范围设置为 test, 此范围意味着 test 不会在运行时被引入, 但事实上 mod 中的方法 runMtdLib 以反射

