如何让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
相关产品推荐
相关产品推荐

