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

3072                                                       软件学报  2025  年第  36  卷第  7  期


                 版本会被遮蔽, 但     mod  在源码中试图调用仅存在于        1.0.0  版本中的方法   methodV1, 这导致模块构建错误.


                                 (a) 危害 1  import lib.Dup
                                     包含    Dup classDup=new Dup ();           构建错误
                                           classDup.methodLib2 ();
                                                                 lib.Dup
                                        依赖于         包含类       public class Dup{
                                                               void methodLib1 ();
                                                              }
                                              依赖库 lib1
                                       依赖于
                                  模块 mod                         lib.Dup
                                                    包含类       public class Dup{  被忽略!
                                                               void methodLib2 ();
                                                              }
                                              依赖库 lib2
                                           import lib.RunDup
                                 (b) 危害 3
                                           RunDup runner=new RunDup ();
                                     包含    runner.runMtdLib ();
                                                                              运行时错误
                                                                  lib.Dup
                                        依赖于         包含类       public class Dup{
                                                               void methodLib1 ();
                                                              }
                                              依赖库 lib1                      被忽略!
                                       依赖于
                                  模块 mod                          lib.Dup
                                                    包含类       public class Dup{
                                                               void methodLib2 ();
                                                              }
                                                     包含类
                                              依赖库 lib2              lib.RunDup
                                                              import lib.Dup;
                                                              public class RunDup{
                                                               public void runMtdLib (){
                                                                Dup classDup= new Dup ();
                                                                classDup.methodLib2 ();
                                                              }
                                                              }
                                 (c) 危害 4  import lib.Dup
                                     包含    Dup classDup= new Dup ();          运行时语义冲突
                                           System.out.println (classDup.methodDup ());
                                                                    lib.Dup
                                        依赖于         包含类        public class Dup{
                                                                String methodDup (){
                                                                  return “Lib1”
                                  模块 mod 依赖于  依赖库 lib1         }
                                                    包含类        }
                                                                    lib.Dup
                                                               public class Dup{
                                              依赖库 lib2
                                                                String methodDup (){
                                                                  return “Lib2”
                                                               }
                                                               }
                                            图 A4 异味   1.2  可能危害与对应触发场景

                    (2) 运行时错误: 其触发场景为模块运行时调用了仅存在于被遮蔽的库中的特性. 以图                         A5(b) 为例, 模块  mod
                 直接依赖于    lib1:2.0.0  和  lib2, lib2  又依赖于  lib1:1.0.0, 并且在  runMtdLib  中调用了仅存在于  lib1:1.0.0  中的方法
                 methodV1. 当  mod  试图调用  runMtdLib  时, 由于  lib1:1.0.0  被遮蔽, 最终出现运行时错误.
                    (3) 运行时语义冲突: 其触发场景为模块运行时调用了被遮蔽库中签名相同但实现不同的方法. 以图                              A5(c) 为
                 例, 模块  mod  的依赖树中同时存在      lib1  的  1.0.0  和  2.0.0  版本, 两个版本的  lib1  中都包含签名相同的  methodDup  方
                 法, 但其具体实现不同. 当      mod  调用  methodDup  时就会出现语义冲突, 预期调用的是         2.0.0  版本中的  methodDup,
                 应返回“V2”, 而实际调用的是       1.0.0  版本中的方法, 返回的是“V1”.
                    4) 类别  1.4  未声明依赖
                    未声明依赖可能引发一系列严重的后果, 包括但不限于模块构建错误、运行时错误以及运行时语义冲突. 以
                 下将详细阐述这些危害的具体触发场景.
                    (1) 构建错误: 其触发场景为模块源码中使用但未声明的依赖库未在依赖树中出现. 以图                            A6(a) 为例, 模块
                 mod  中引用依赖库    lib2  中的类  A, 但并未在配置文件中声明       lib2, 而是通过依赖库   lib1:4.0.0  引入  lib2  作为传递依
                 赖. 然而  lib1 升级到  4.0.1  后不再依赖于  lib2, mod  的依赖树中不再存在   lib2, 无法找到对应类, 导致构建错误.
                    (2) 运行时错误: 其触发场景为模块运行时使用但未声明的依赖库未在依赖树中出现. 以图                           A6(b) 为例, mod
                 利用反射特性引用依赖库          lib2  中的类  A, 但并未在配置文件中声明. 和上例类似, 在            mod  依赖树中不再存在
   146   147   148   149   150   151   152   153   154   155   156