Page 131 - 《软件学报》2025年第7期
P. 131
3052 软件学报 2025 年第 36 卷第 7 期
3 依赖异味检测
根据我们在 RQ2 中的发现, Java 项目中存在多种依赖异味, 它们可能在特定条件下被触发, 对项目造成各种
危害. 因此, 及时发现项目中潜藏的依赖异味显得格外重要. 尽管现有工具可用于部分依赖异味的检测, 但它们主
要针对单一构建工具中的几类依赖异味, 缺乏全面而综合的检测能力. 这促使我们设计并实现一个能够检测我们
在 RQ1 中观察到的所有异味, 并且适用于 Maven 和 Gradle 项目的检测工具 JDepAna.
我们结合 RQ1 中识别的各类依赖异味及其特征, 以及 RQ2 中总结的不同触发场景, 为每种异味设计了相应
的检测算法. 这些检测算法依赖于类似的数据输入, 因此能够将这些共同的数据特征抽象为构建工具无关的依赖
模型. 依赖模型使得统一的检测算法能够在该模型上进行操作, 而无须关心底层构建工具的细节差异所带来的检
测逻辑差异. 由于 Maven 与 Gradle 在依赖管理机制上存在显著差异, 若不合理隔离这些差异, 依赖异味的检测逻
辑将需在两种构建工具中分别实现. 例如, 在处理依赖树的冲突时, Maven 优先使用距离目标模块路径最近的依赖
版本; 而 Gradle 则倾向于选择最高版本来解决冲突. 此时如果没有依赖模型, 异味 1.8 依赖树冲突的检测逻辑需要
根据两者特性分别实现. 此外, 依赖模型的抽象设计进一步提升了可扩展性, 它解耦了检测逻辑与具体构建工具,
使得在出现新的依赖异味时, 能够基于依赖模型提供的丰富信息高效实现检测算法, 并将其集成进 JDepAna 中,
而无须考虑构建工具复杂的底层机制.
最终基于依赖模型, 我们设计并实现了用于 Java 项目依赖异味检测的统一算法, 并开发了适配 Maven 和 Gradle
的检测工具 JDepAna, 将各类异味检测功能集成在一个可扩展的框架之下. 接下来, 我们将详细介绍 JDepAna 的
依赖异味检测流程和实现细节.
3.1 依赖异味检测流程
我们将依赖异味检测流程展示在图 5 中, 主要可以分为两步: 首先对项目或模块的信息进行解析以构建依赖
模型, 其次在构建好的依赖模型上运行各类异味对应的算法以进行依赖异味分析. 我们将从依赖模型构建和依赖
异味分析两个方面进行介绍.
JDepAna
步骤 1: 依赖模型构建 步骤 2: 依赖异味检测
输入: 1 2 6 7 输出:
提取
信息 解析配置文件 执行检测算法 解析结果
目标模块 基本信息 5 依赖树 算法执行器 结果解析器 检测结果
解析代码 解析依赖树节点
4 依赖模型 3
解析依赖包调用
调用图 依赖包集合
图 5 依赖异味检测流程
3.1.1 依赖模型构建
各类依赖异味检测算法主要以项目中 4 类依赖管理相关数据作为输入, 包括基本信息、依赖树、依赖包集合
和调用图, 我们将它们抽象为依赖模型. 接下来我们分别介绍这 4 类数据和它们的作用.
1) 基本信息. 这类信息包括项目或模块的配置文件以及组织结构等原始数据. 其中包括源代码路径、测试代
码路径、编译产出路径和依赖库缓存等信息. 这些数据为我们提供了项目或模块的基础信息, 为后续数据的获取
提供了支持.
2) 依赖树. 依赖树是包含目标模块对应所有依赖库信息的树形结构. 在依赖树中, 包括了目标模块的直接依赖
和传递依赖, 每个依赖库在依赖树中对应一个节点. 通过依赖树, 我们能够准确地定位依赖库及其出现的次序和深

