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  以反射
   149   150   151   152   153   154   155   156   157   158   159