Page 152 - 《软件学报》2025年第7期
P. 152

孙伟杰 等: Java 依赖异味的实证研究与统一检测技术                                                    3073


                 lib2  后, 由于  mod  并未在源码中而是利用反射特性动态引入类            A, 所以  mod  不会出现构建错误, 但在运行时则会
                 因为无法找到类      A  而出现运行时错误.


                                             import lib1.Dup
                                 (a) 危害 1
                                       包含    Dup classDup= new Dup ();
                                             classDup.methodV1 ();
                                                                  lib1.Dup       构建错误
                                         依赖于          包含类      public class Dup{
                                                                void methodV2 ();
                                                               }
                                                依赖库 lib1: v2.0.0
                                         依赖于
                                    模块 mod                                  lib1.Dup
                                                     依赖于        包含类      public class Dup{
                                                                           void method V1 ();
                                                                         }
                                                依赖库 lib2  依赖库 lib1: v1.0.0
                                 (b) 危害 3  import lib1.RunDup
                                           RunDup runner=new RunDup ();
                                     包含    runner. runMtdLib ();
                                                                                运行时错误
                                                                 lib1.Dup
                                       依赖于          包含类      public class Dup{
                                                              void methodV2 ();
                                                             }
                                              依赖库 lib1: v2.0.0
                                       依赖于
                                  模块 mod                                   lib1.Dup
                                                   依赖于        包含类      public class Dup{
                                                                        void methodV1 ();
                                                                       }
                                             依赖库 lib2  依赖库 lib1: v1.0.0
                                                                  lib2.RunDup
                                                  包含类
                                                            import lib1.Dup;
                                                            public class RunDup{
                                                             public void runMtdLib (){
                                                               Dup classDup=new Dup ();
                                                               classDup.methodV1 ();
                                                            }
                                                            }
                                 (c) 危害 4  import lib2.RunDup
                                          RunDup runner=new RunDup ();
                                          System.out.println (runner.runDupMtd ());
                                     包含
                                                                  lib1.Dup
                                                             public class Dup{  运行时语义冲突
                                       依赖于          包含类       String methodDup (){
                                                                return “V2”
                                                              }
                                              依赖库 lib1:v2.0.0  }
                                       依赖于
                                  模块 mod                                   lib1.Dup
                                                   依赖于        包含类      public class Dup{
                                                                        String methodDup (){
                                                                          return “V1”
                                             依赖库 lib2  依赖库 lib1: v1.0.0  }
                                                                       }
                                                  包含类
                                                                       lib2.RunDup
                                                            import lib1.Dup;
                                                            public class RunDup{
                                                             public String runDupMtd (){
                                                               Dup classDup= new Dup ();
                                                               return classDup.methodDup ()
                                                             }
                                                            }
                                            图 A5 异味   1.3  可能危害与对应触发场景

                    (3) 运行时语义冲突: 其触发场景为模块直接使用但未声明的依赖库版本升级后出现签名相同但实现不同的
                 情况. 以图  A6(c) 为例, 模块  mod  中直接使用   lib2:1.0.0  中的方法  getVersion, 但并未在配置文件中声明    lib2, 而是
                 通过依赖库    lib1:4.0.0  引入  lib2:1.0.0  作为传递依赖. 然而  lib1  升级到  4.0.1  时同时升级  lib2  版本, 引入传递依赖
                 lib2:2.0.0, 其中方法  getVersion  的签名并未改变, 但其具体实现不同. 当     mod  调用  version  时就会出现语义冲突, 预
                 期调用的是    1.0.0  版本中的  getVersion, 应返回“V1”, 而实际调用的是   2.0.0  版本中的方法, 返回的是“V2”.
                    5) 类别  1.5  未使用依赖
                    未使用依赖不会如前述异味一般造成构建错误等破坏性的危害, 但会造成构建时间增加、构建产物冗余等危
                 害. 以下将详细阐述这些危害的具体触发场景.
                    (1) 构建时间增加: 这类危害在出现依赖未使用时始终存在. 以图                 A7(a) 为例, 模块  mod  并未使用依赖库    lib  中
                 的特性, 但却在配置文件中进行声明, 导致在构建时该依赖会被引入, 需要从中央存储仓库获取对应依赖库, 进而
                 导致构建时间增加, 即增加构建成本.
                    (2) 构建产物冗余: 其触发场景为模块可执行            JAR  的打包. 以图   A7(b) 为例, 模块  mod  并未使用依赖库    lib  中
   147   148   149   150   151   152   153   154   155   156   157