You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让ASM ClassWriter保留常量池表的条目顺序?

ASM ClassWriter保留常量池顺序的解决方案

ASM的ClassWriter默认不会保留原class文件的常量池条目顺序——它会按照自身逻辑重新生成常量池,哪怕只是读取原文件后直接写出,生成的字节码哈希也会和原文件不一致。要解决这个问题,最直接的方法是利用ClassWriter的特定构造方法,让它复用原ClassReader的常量池信息:

核心解决步骤

修改ClassWriter的初始化代码,传入原ClassReader对象作为第一个参数:

// 替换原来的ClassWriter创建逻辑
ClassWriter writer = new ClassWriter(reader, ClassWriter.COMPUTE_MAXS);

这个构造方法的作用是让ClassWriter尽可能复用原class文件的常量池条目和顺序,避免因重新组织常量池导致的字节码差异。

修改后的完整测试代码

@Test
void hashShouldBeSame() throws IOException, NoSuchAlgorithmException {
    Path A = CLASSFILE.resolve("A.class");
    String originalHash = HashComputer.computeHash(Files.readAllBytes(A), "SHA-256");

    ClassReader reader = new ClassReader(Files.readAllBytes(A));
    // 关键修改:传入reader给ClassWriter
    ClassWriter writer = new ClassWriter(reader, ClassWriter.COMPUTE_MAXS);
    reader.accept(writer, 0);

    String hashFromRewrittenModel = HashComputer.computeHash(writer.toByteArray(), "SHA-256");

    assertThat(originalHash).isEqualTo(hashFromRewrittenModel);
}

补充说明

如果需要更精细化的常量池控制,也可以自定义ClassVisitor手动维护常量池顺序,但上述方法已经能覆盖绝大多数场景,是最简单高效的解决方案。

内容的提问来源于stack exchange,提问作者AMAN SHARMA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 08:32:39