Kiro 中反编译 JAR 包并分析字节码的流程指南
适用场景
当你的项目依赖了内部库(没有源码),需要确认某个配置项/属性是否被该库使用、以及具体如何使用时,可以通过以下流程进行字节码分析。
前置准备
1. 解压 JAR 包到工作区
将目标依赖 JAR 包解压后,添加为 Kiro 的工作区文件夹:
bash
# 在项目外创建一个目录,将 jar 解压到其中
mkdir d:\test\my-lib-1.0.0
cd d:\test\my-lib-1.0.0
jar -xf path/to/my-lib-1.0.0.jar
然后在 Kiro 中将解压目录添加到工作区(File → Add Folder to Workspace)。
然后就可询问kiro:
我已经把反编译解压后的jar,添加到了工作区jsh-mgt-lib-rocket-3.0.0中,验证下xxx
2. 确认 javap 可用
确保系统 PATH 中有 JDK 的 javap 命令。
注:
博客:
https://blog.csdn.net/badao_liumang_qizhi
分析流程
第一步:探索库的目录结构
使用 listDirectory 查看包结构,定位关键类文件:
listDirectory path="my-lib-1.0.0" depth=5
重点关注:
META-INF/spring/--- Spring Boot 自动配置注册**/properties/--- 配置属性绑定类**/config/--- 配置类
第二步:查看自动配置入口
读取自动配置注册文件,确认入口类:
readFile path="my-lib-1.0.0/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports"
或旧版 Spring Boot:
readFile path="my-lib-1.0.0/META-INF/spring.factories"
第三步:查看类签名(javap -p)
用 javap -p 查看类的所有字段和方法声明:
powershell
javap -p "com/example/lib/properties/MyProperties.class"
注意:
javap的 cwd 需设为解压后的根目录(包含com/目录的那一级)。路径使用/分隔。
示例输出:
public class com.example.lib.properties.MyProperties {
private java.lang.String endpoint;
private java.lang.String instanceId;
private java.lang.String groupId;
public java.lang.String getInstanceId();
public void setInstanceId(java.lang.String);
...
}
第四步:查看字节码实现(javap -c -p)
当需要确认某个字段/方法在逻辑中是否被调用时,使用 -c 输出字节码指令:
powershell
javap -c -p "com/example/lib/config/MyConfig.class"
第五步:过滤关键调用
由于字节码输出冗长,用 Select-String(Windows)或 grep(Linux/Mac)过滤关键方法调用:
Windows PowerShell:
powershell
javap -c -p "com/example/lib/config/MyConfig.class" 2>$null | Select-String -Pattern "getInstanceId|INSTANCE_ID|PropertyKeyConst" -Context 3,3
Linux/Mac Bash:
bash
javap -c -p "com/example/lib/config/MyConfig.class" 2>/dev/null | grep -E "getInstanceId|INSTANCE_ID|PropertyKeyConst" -B 3 -A 3
第六步:查看常量池确认字符串引用(javap -c -p -verbose)
当需要确认具体的常量字符串(如 Property Key 名称)时,使用 -verbose:
powershell
javap -c -p -verbose "com/example/lib/config/MyConfig.class" 2>$null | Select-String -Pattern "getInstanceId|put|setProperty" -Context 2,5
常量池会显示类似:
#40 = String "AccessKey"
#57 = String "NAMESRV_ADDR"
#201 = String "GROUP_ID"
通用示例:验证配置属性是否被库使用
场景
项目 application.yml 中配置了:
yaml
mylib:
client:
connection-timeout: 5000
retry-count: 3
需要确认 retry-count 是否真的被库代码使用。
操作步骤
1. 解压 JAR,添加工作区
2. 查看属性类结构
> javap -p "com/example/lib/properties/ClientProperties.class"
→ 确认存在 private int retryCount 字段和 getRetryCount() 方法
3. 查看配置类结构
> javap -p "com/example/lib/config/AutoConfig.class"
→ 找到可能使用该属性的方法,如 createClient()
4. 搜索字节码中的调用
> javap -c -p "com/example/lib/config/AutoConfig.class" | Select-String "getRetryCount" -Context 3,3
若有输出 → 属性被使用,查看上下文确认用法
若无输出 → 属性在该类中未被使用,继续搜索其他类
5. 若有多个类需要检查,批量搜索
> Get-ChildItem -Recurse -Filter "*.class" | ForEach-Object {
$result = javap -c -p $_.FullName 2>$null | Select-String "getRetryCount"
if ($result) { Write-Host $_.Name; $result }
}
常用 javap 参数速查
| 参数 | 用途 |
|---|---|
-p |
显示所有成员(含 private) |
-c |
输出字节码指令 |
-verbose |
输出常量池、注解等完整信息 |
-s |
输出内部类型签名 |
-l |
输出行号和局部变量表 |
注意事项
- 路径格式 :
javap接受的是类文件的相对路径(从包根目录开始),使用/分隔 - cwd 设置 :命令的工作目录必须是包含顶层包目录(如
com/)的那一级 .class无法被 grep/ripgrep 搜索 :二进制文件不能用文本搜索工具直接扫描,必须通过javap先转为文本- 字节码阅读技巧:
invokevirtual= 调用实例方法invokestatic= 调用静态方法getfield/putfield= 读写实例字段ldc= 加载常量(字符串、数字等)- 注释中的
// Method和// String直接告诉你调用了什么