楼主: 熊哒哒
107 0

[作业] Java静态分析与调用链工具java-all-call-graph使用说明 [推广有奖]

  • 0关注
  • 0粉丝

等待验证会员

学前班

40%

还不是VIP/贵宾

-

威望
0
论坛币
0 个
通用积分
0
学术水平
0 点
热心指数
0 点
信用等级
0 点
经验
20 点
帖子
1
精华
0
在线时间
0 小时
注册时间
2018-3-21
最后登录
2018-3-21

楼主
熊哒哒 发表于 2025-12-9 18:47:34 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币

1. 项目 GitHub 地址

https://github.com/Adrninistrator/java-all-call-graph

2. 使用案例展示

以下内容整理自通过微信公众号、搜索引擎等公开渠道获取的技术文章,其中明确提到了对 java-all-call-graphjava-callgraph2 的实际应用。若作者不希望相关信息被列出,可联系进行移除。

2.1 vivo 千镜 —— 调用图构建及其在代码安全扫描中的实践

链接:https://mp.weixin.qq.com/s/pNhYzGoeCqp_zkOcNf0xgg

使用工具:java-all-call-graph、java-callgraph2

2.2 自如技术团队 —— 探索代码瘦身的设计理念与实现细节

链接:https://mp.weixin.qq.com/s/ovzhSasR6QL7L5vlFILDgw

使用工具:java-callgraph2

2.3 携程技术 —— 实现精准测试和应用瘦身的代码分析平台揭秘

链接:https://mp.weixin.qq.com/s/p9BcfNqLk2ZDUNcXukqXpg

使用工具:java-callgraph2

3. 项目核心功能概述

3.1 总体目标定位

本项目致力于利用 Java 技术对 Java 应用进行自动化静态分析,将原本非结构化的代码信息转化为结构化数据,并存储至关系型数据库中,为开发、测试、安全审计等多个环节提供可靠的数据支持。

3.2 支持 SQL 查询的静态代码分析能力

系统可对编译后的 Java 字节码执行静态解析,提取关键元素并写入数据库表,用户可通过标准 SQL 进行灵活查询。

支持识别的数据类型包括但不限于:

  • 类、方法、字段
  • 注解、泛型定义
  • 方法调用关系
  • 枚举类型

同时兼容部分主流框架的信息提取,例如:

  • MyBatis 映射操作
  • Spring AOP 切面逻辑
  • Spring Bean 管理
  • Controller 接口映射
  • Scheduled Task 定时任务

具体使用方式详见文档:

对 Java 代码静态分析并支持 SQL 查询

3.3 方法完整调用链生成

支持从指定入口方法出发,向上追溯调用者或向下追踪被调用者,生成完整的正向或反向调用路径。

详细说明及使用方法见:

静态分析生成 Java 代码方法完整调用链

3.4 方法调用堆栈路径生成

在生成完整调用链的基础上,进一步筛选出从起始方法到包含特定关键字方法之间的调用路径,模拟运行时堆栈行为,便于问题排查与流程理解。

详细说明及使用方法见:

静态分析生成 Java 代码方法调用堆栈

3.5 从调用堆栈文件中提取关键信息

系统可在生成调用堆栈的同时,附加展示具有业务意义的上下文信息,如:

  • 方法调用中传入的常量值
  • 参数的具体类型
  • 泛型参数或返回值的实际类型
  • MyBatis 操作涉及的数据库表名

并支持基于这些信息从堆栈文件中提取关注点。

详细说明及使用方法见:

从方法调用堆栈文件提取关注的信息

3.6 解析 MyBatis 数据库表操作(MySQL 兼容)

当分析调用链或调用堆栈时,能够自动识别 MyBatis Mapper 方法所操作的 MySQL 数据库表名称,并将其作为上下文信息一并呈现。

3.7 JarDiff:对比 JAR 包版本差异与影响范围分析

支持对不同版本的 JAR 文件进行比对,识别出发生变更的方法集合,并基于此生成向上/向下的完整调用链,从而评估代码修改的影响边界。

此外,还可根据 MyBatis Mapper XML 中 SQL 语句的变化,定位到关联的 Mapper 方法,进而构建调用路径,辅助评估变更影响。

详细说明及使用方法见:

JarDiff 比较 jar 文件版本差异及代码影响范围

3.8 JDK 与依赖库兼容性问题检测

针对 Java 应用在升级 JDK 版本或第三方依赖库后可能出现的类、方法、字段缺失等问题,提供扫描机制以提前发现潜在的运行时异常风险。同时也支持检查命名高度相似但可能引发混淆的类。

详细说明及使用方法见:

Java 应用 JDK 及依赖库兼容问题扫描工具

3.9 获取方法调用时的参数类型与常量值

能够在静态分析过程中,提取方法调用时传递的对象实例或参数所使用的具体常量值,以及参数的类型信息,增强调用上下文的理解能力。

详细说明及使用方法见:

静态分析获取 Java 代码方法调用参数类型或值

3.10 字符串拼接逻辑解析

支持对由字符串常量、枚举常量、方法返回值等参与的字符串拼接表达式进行拆解,还原拼接前的各项输入内容,并推断最终拼接结果。

详细说明及使用方法见:

静态分析解析 Java 代码字符串拼接

建议先在 GitHub 上提交 issue 再展开讨论,以便更好地整理相关议题内容。后续具有参考价值且不重复的讨论内容将被汇总至正式文档中。

5. 利用大模型对项目进行问答分析

5.1 DeepWiki

支持无需注册即可提问,但系统不会自动检索项目的最新代码内容。

网址:
https://deepwiki.com/Adrninistrator/java-all-call-graph

该平台通过大模型对项目源码进行深度解析,用户可就项目相关问题进行咨询,包括但不限于功能使用方式、调用逻辑等。

5.2 zread.ai

使用前需完成注册流程。

网址:
https://zread.ai/Adrninistrator/java-all-call-graph

功能与 DeepWiki 类似,均基于大模型实现对项目代码的理解与问答支持。

6. 核心概念定义

6.1 方法调用关系

指一个方法(调用方)对另一个方法(被调方)的调用行为,包含以下信息:调用方法和被调方法的包名、类名、方法名、参数类型、返回值类型以及调用类型(如静态调用或实例调用)。

示例:
a.b.c.Caller:f1() 调用 a.b.c.Callee:f2(int, java.lang.String)

此类关系可视为由调用方法与被调方法构成的二元组,对应存储于数据库中的 method_call 表中。

6.2 方法调用信息

描述在方法调用过程中涉及的具体上下文数据,例如:被调用对象或参数所使用的常量值、变量类型、变量对应的方法参数索引、其他方法调用的返回结果、类成员变量等。

这些信息写入数据库的 method_call_info 表。

6.3 所有方法的调用图

针对某一 Java 项目,其全部方法之间形成的调用网络构成一个高度复杂的图结构。下图展示了一个简化的调用图示例:

6.4 方法完整调用链

从某个指定方法出发,向下延伸至所有直接或间接被其调用的方法,直到末端无进一步调用的方法为止,称为“向下完整调用链”;反之,从该方法向上追溯所有可能调用它的方法路径,直至没有上级调用者的方法,称为“向上完整调用链”。

完整调用链呈现树状结构,例如:

com.example.Main:main(String[])
├─ com.example.service.UserService:getUserById(Long)
│   ├─ com.example.repository.UserRepository:findById(Long)
│   │   ├─ com.example.mapper.UserMapper:toEntity(ResultSet)
│   │   └─ com.example.validator.IdValidator:validate(Long)
│   └─ com.example.cache.UserCache:get(String)
└─ com.example.util.Logger:info(String)

如下图所示:

无论是向上还是向下的完整调用链,均可视为整个项目调用图中的一个子图(虽以树形呈现,但由于可能存在循环调用,实际为图结构)。

6.5 方法调用堆栈

在方法完整调用链的基础上,提取从起始方法到某一特定调用/被调方法之间的具体执行路径,即为方法调用堆栈。

调用堆栈为线性链表结构,例如:

com.example.Main:main(String[])
└─ com.example.service.UserService:getUserById(Long)
└─ com.example.repository.UserRepository:findById(Long)
└─ com.example.mapper.UserMapper:toEntity(ResultSet)

com.example.Main:main(String[])
└─ com.example.util.Logger:info(String)

如下图中红色路径所示:

可以理解为,方法调用堆栈是完整调用链中的一条具体路径分支。

7. 项目依赖关系说明

各组件之间的依赖结构如下:

  • java-all-call-graph 依赖 java-callgraph2,用于对 Java 源码或字节码进行静态分析;
  • java-callgraph2 依赖 bcel,用于解析 Java 字节码信息;
  • java-all-call-graph 依赖 druid,作为数据源管理工具;
  • java-all-call-graph 依赖 mybatis-mysql-table-parser,用于解析 MyBatis XML 文件中的 MySQL SQL 语句;
  • mybatis-mysql-table-parser 依赖 druid,用于 SQL 语句的语法解析;
  • mybatis-mysql-table-parser 依赖 jdom2,用于 XML 文件的读取与解析;
  • java-all-call-graph 依赖 java-text-to-excel,用于将文本格式的内容转换生成 Excel 文件。

本项目基于 java-text-to-excel 工具,并依赖 fastexcel 实现 Excel 文件的生成功能。

8. 核心处理流程

8.1 代码解析与数据库写入

该阶段主要完成对 Java 字节码文件(如 JAR 包)的静态分析,并将分析结果持久化至数据库中。具体步骤如下:

  • 通过 java-all-call-graph 模块中的 RunnerWriteDb 类调用 java-callgraph2 库进行底层操作;
  • java-callgraph2 负责读取待分析的 JAR 等二进制文件,执行静态代码分析,输出中间结果到文本文件;
  • 随后,RunnerWriteDb 类读取上述生成的文本数据,并将其结构化地写入数据库。

关于 RunnerWriteDb 的详细使用说明,请参见“当前项目能够做什么”章节中“对代码静态分析并支持 SQL 查询”的相关内容。

当前项目在执行时,首先需要解析代码并写入数据库
当被解析的代码发生变化时,需要重新执行当前步骤,使数据库中写入最新代码对应的数据

8.2 数据读取与结果生成

在完成数据入库后,系统进入第二阶段:从数据库提取所需信息,并按需生成各类分析报告或数据文件。

  • java-all-call-graph 中的不同类负责从数据库查询相关信息;
  • 根据业务需求,可生成包括完整方法调用链、方法调用堆栈等在内的多种输出文件。

9. 使用指南

9.1 运行环境要求

  • 需使用 JDK 8 或更高版本;
  • 若计划通过 IDE 打开并运行项目源码,建议配置 Gradle 构建工具以管理依赖项。

9.2 参数配置机制

9.2.1 配置方式支持情况

项目支持两种参数设定途径:通过外部配置文件定义,或直接在代码中编程式指定。两种方式效果一致,且所有配置项均在代码中有明确映射。

通过配置文件指定
通过代码指定
9.2.2 配置参数格式类型
9.2.2.1 Map 格式 — 键值对参数

适用于单值配置项,分为两类:

  • 与数据库无关的通用配置;
  • 涉及数据库连接或操作的相关参数。

每项配置由枚举常量表示,对应唯一的键值对,且每个参数仅允许设置一个确定值。

com.adrninistrator.jacg.conf.enums.ConfigKeyEnum
com.adrninistrator.jacg.conf.enums.ConfigDbKeyEnum
_jacg_config/config.properties
_jacg_config/config_db.properties
9.2.2.2 List 格式 — 有序列表参数

用于需要保持顺序的多值参数。对应的枚举类为:
com.adrninistrator.jacg.conf.enums.OtherConfigFileUseListEnum
每个枚举实例代表一个参数,关联一个独立的配置文件,其值可包含多个条目,并严格保留输入顺序。

9.2.2.3 Set 格式 — 无序集合参数

适用于不关心顺序的多值参数。对应枚举类为:
com.adrninistrator.jacg.conf.enums.OtherConfigFileUseSetEnum
每个枚举常量标识一个参数,对应一个配置文件,允许设置多个值,但不保证顺序。

9.2.2.4 EL 表达式参数

用于动态逻辑判断的表达式配置。对应枚举类为:
com.adrninistrator.jacg.el.enums.ElConfigEnum
每个参数值为一条完整的 EL 表达式字符串,用于条件计算或规则匹配。

9.2.3 配置参数示例参考

详见“配置参数示例”文档部分。

9.2.4 EL 表达式通用使用说明

详情请查阅“EL 表达式使用通用说明文档”。

9.2.5 EL 表达式中字符串比较说明

具体规则见“EL 表达式字符串比较说明文档”。

9.2.6 通过代码设置配置参数

可通过 com.adrninistrator.jacg.conf.ConfigureWrapper 类在程序中动态设置各类参数。常用方法如下:

方法名称 功能描述
setMainConfig 设置键值对形式的主配置参数(Map 格式)
setOtherConfigList 设置有序的多值参数(List 格式)
setOtherConfigSet 设置无序的多值参数(Set 格式)
setElConfigText 设置 EL 表达式内容

9.3 运行模式说明

9.3.1 支持的运行方式概览
通过 IDE 打开项目源码运行
在其他项目中引用当前项目的库运行
使用项目源码构建后运行
9.3.2 不同运行方式下的参数配置支持
运行方式 支持的参数配置方式
通过 IDE 打开项目源码运行 支持通过配置文件指定、也支持通过代码指定
在其他项目中引用当前项目的库运行 支持通过配置文件指定、也支持通过代码指定
使用项目源码构建后运行 仅支持通过配置文件指定
9.3.3 在 IDE 中打开并运行项目
9.3.3.1 使用配置文件传参

若选择通过配置文件设定参数,可修改项目中相关配置文件内容,然后运行对应场景的入口类。这些入口类位于 test 模块下的 test.jacg 包内。

注意:应将运行模块设为 test,以便使 test 模块中的 log4j2 配置生效。

9.3.3.2 使用代码传参

若希望在代码中直接指定参数,可直接调用各使用场景提供的示例方法,或以其为基础进行自定义修改。

9.3.4 在其他项目中作为依赖库引入运行

可在第三方项目中使用 Maven 或 Gradle 引入本项目作为依赖库。

Maven 依赖配置示例如下:

<dependency>
<groupId>com.github.adrninistrator</groupId>

使用 Gradle 进行依赖管理时,可参考以下配置:

<artifactId>java-all-call-graph</artifactId>
<version>版本号</version>
<type>pom</type>
implementation("com.github.adrninistrator:java-all-call-graph: 版本号")

最新版本信息可通过以下链接查看:

https://mvnrepository.com/artifact/com.github.adrninistrator/java-all-call-graph

本工具仅引入了 slf4j-api 组件,在引入本工具组件的项目中,还需要引入 log4j2、logback 等日志组件,且保证配置正确,能够在本地正常运行
由于 Maven 间接依赖的组件版本不会自动使用最大的版本号,因此可能需要在项目中手工指定 java-all-call-graph 依赖组件的版本号,避免因为依赖组件版本不一致导致问题,可通过 java-all-call-graph 与 java-callgraph2 的 pom 文件的 dependencies 元素查看依赖组件版本

9.3.4.1 通过配置文件设置参数并运行

运行 java-all-call-graph 库中提供的类 com.adrninistrator.jacg.unzip.UnzipFile,执行时请选择当前项目中引入该库的模块。

此步骤仅需执行一次即可完成初始化。

但假如 java-all-call-graph 升级后,若对配置文件有新增或修改,则需要再执行当前步骤,否则可能会因为缺少配置文件导致执行失败

该类的作用是将 java-all-call-graph 项目的入口类和相关配置文件,以及 java-callgraph2 项目的配置文件解压释放到指定目录。

释放根目录的选择遵循以下优先级顺序:

  • src/test:当该目录存在时,作为首选路径;
  • src/unit.test:若 src/test 不存在而 src/unit.test 存在,则使用此目录;
  • _jacg-{时间戳}:当前两者均不存在时,自动创建以 _jacg- 开头并附加时间戳的目录作为根路径。

java-all-call-graph 的入口类会被写入释放根目录下的 java/test/jacg 路径中,其配置文件则保存至根目录下的 resources/ 目录,子目录名称为:

_el_example

或以以下形式命名的子目录:

_jacg_

而 java-callgraph2 项目的配置文件同样存放在 resources/ 目录下,子目录名为:

_el_example

或以如下前缀开头的目录:

_javacg2_

完成配置文件的参数修改后,即可运行相应的入口类来启动程序。

9.3.4.2 通过代码方式设定参数运行

此方式的操作说明与“通过 IDE 打开项目源码运行”部分一致,可参照相同流程进行处理。

9.3.5 使用项目源码构建后再运行

9.3.5.1 构建方法

进入项目根目录,并执行如下命令进行构建:

gradlew gen_run_jar

9.3.5.2 构建输出内容

构建成功后,将在项目根目录生成名为 jar_output_dir 的文件夹,其中包含以下子目录与文件:

目录/文件名 用途说明
_el_example 存放表达式相关的示例及说明文档
_javacg2_xxx 用于保存当前项目所使用的配置文件
config log4j2 日志框架的配置文件存储位置
jar 存放项目编译后生成的 jar 文件
lib 项目依赖的第三方库 jar 文件所在目录
log 日志文件存储目录,运行后会自动生成日志内容
xxx.bat 适用于不同场景的 Windows 执行脚本
xxx.sh 适用于不同场景的 Linux/Unix 执行脚本

9.3.5.3 通过配置文件设定参数运行

在完成对配置文件中的各项参数调整后,可通过执行对应的 xxx.bat(Windows)或 xxx.sh(Linux/Unix)脚本来调用指定的入口类,从而启动应用。

9.3.6 通过代码调用的其他使用示例

更多关于通过编码方式调用的使用案例,请参见:

通过代码执行的其他示例

10. 更新日志

更新说明

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:GRAPH Java 静态分析 GRAP 使用说明

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
jg-xs1
拉您进交流群
GMT+8, 2025-12-22 18:28