Page 124 - 《软件学报》2025年第7期
P. 124
孙伟杰 等: Java 依赖异味的实证研究与统一检测技术 3045
GitHub [30] 中的项目与问题报告. 这样的选择出于以下考虑: 首先, 官方文档是深入探究 Java 依赖管理的权威途径.
Maven、Gradle 的依赖管理手册会帮助我们全面理解 Java 项目依赖管理的核心概念和最佳实践. 其次, 学术论文
有助于我们了解现有研究的边界. 依赖管理相关的论文使我们的研究能够包括最新的学术进展. 最后, 开源社区的
采用能够有效提供实际问题的案例支持, GitHub 提供了丰富的 Java 代码仓库和相应问题报告供我们开展研究.
我们综合 3 类调研对象, 从而深入探讨 Java 项目依赖管理中的潜藏问题. 首先, 我们调研官方手册和科研论
文, 总结出如表 1 中依赖管理相关的关键词, 由于直接以关键词进行搜索则会包含许多无关信息, 例如项目中常规
对依赖版本升级的工作, 所以我们根据论文中描述的问题和依赖管理规范, 围绕关键词组织出表 1 中适合于搜索
的 7 个搜索子句, 其中 4 个子句来源于官方文档, 3 个来源于相关学术论文. 为了解决 GitHub 搜索对逻辑符数量
的限制, 我们将搜索子句分为两组, 分别包含 3 个和 4 个子句, 将这些搜索子句组合成符合 GitHub REST API 的形
式在 GitHub 中进行搜索, 返回结果按 GitHub 中的匹配度指标排序, 并分别从中选取前 200 个问题报告. 较高的匹
配度能够确保我们所分析的问题报告具有较高的相关性和代表性, 排名 200 之后的问题报告在匹配度指标上相对
较低, 也更可能包含无关内容 (例如常规的依赖库版本升级). 这种筛选方法帮助我们聚焦于最具代表性的问题报
告, 从而提升研究的有效性. 随后, 我们对两次搜索的结果进行了去重处理, 最终获得了 397 个独立的问题报告.
表 2 中展示这些问题报告对应的项目数据, 可以看到所考察项目具有明显的差异性: (1) 有一定规模 (平均代码行
数 519.8k, 小至 200 行, 大至 1 200 万行); (2) 维护良好 (平均 5.5k 次提交); (3) 有一定关注度 (平均有 1k 个 Star).
表 1 依赖异味相关关键词
关键词 搜索子句
“Maven”; “Gradle”; “dependencies”;
“dependency scope” ∧ (“override” ∨ “change”); “conflict” ∧ ((“library” ∧ “class”)
“dependency”; “dependency scope”;
∨ “dependency version”); “modules” ∧ “dependency” ∧ “same”; “dependency” ∧
“dependency tree”; “dependency version”;
((“undeclared” ∧ “used”) ∨ (“unused” ∧ “declared”)); “Maven” ∧ “Gradle” ∧
“module”; “class”; “library”;
“dependency”; (“wrapper.jar” ∨ “wrapper.properties”) ∧ “add”; “wrapper.jar” ∧
“wrapper.properties”; “wrapper.jar”;
“checksum” ∧ “correct”
“checksum”
表 2 目标项目信息 (k)
统计指标 Star数目 Commit数目 代码行数
平均值 1 5.5 519.8
最大值 13.7 77 12 067
最小值 0.002 0.025 0.2
步骤 2: 数据分析. 为了回答 RQ1 和 RQ2, 我们深入分析每个问题报告中的开发者讨论以及对应的修复方案.
我们首先排除与依赖异味无关的问题报告, 并对剩余问题报告中反映的问题特征进行总结与分类. 具体来说, 我们
排除了与项目日常维护相关的问题报告共 74 个, 例如依赖库的常规版本升级. 接着我们排除了那些缺少明确解决
方案, 或仅涉及功能代码修改而不涉及依赖配置文件 (如 pom.xml) 的问题报告共 276 个. 最终, 我们筛选出 47 个
与依赖异味相关的问题报告. 对于这些问题报告, 我们通过关键词分析识别其所对应的危害类型. 例如, 增加构建
成本的相关关键词包括“Performance regression”; 而运行时错误则涉及“NoSuchMethodError”或“ClassNotFound-
Exception”等. 为判断危害的来源是当前模块还是下游模块, 我们分析了问题报告中是否提及下游模块. 如果问题
源于当前模块作为独立应用程序运行时引发, 则视为对当前模块的危害; 反之, 如果问题发生在下游模块使用当前
模块作为依赖库时, 则视为对下游模块的危害. 在分析过程中, 我们采用了开放编码 (open coding) 过程 [31] , 这是一
种广泛应用于定性研究的方法, 用于对问题报告中讨论的问题进行分类. 在初始阶段, 本文的两位作者独立分析
了 199 个问题报告的修复方案和开发者讨论. 第 1 轮分析和分类后, 两位作者汇总比较并讨论他们的结果, 以调整
分类方法, 并在第 3 位作者的协助下解决冲突. 通过这种方式, 我们建立了初步的分类法. 接下来, 前两位作者继续
对剩余 198 个问题报告的修复方案或讨论进行分类, 并迭代地完善结果和分类策略. 分类中的冲突再次在会议期
间讨论, 并由第 3 位作者解决. 我们调整了初步的分类法, 并最终得到了结果.

