学习ASM框架时遇ArrayIndexOutOfBoundsException异常求助
ASM框架ClassReader报ArrayIndexOutOfBoundsException的解决方法
问题根源
你用new byte[1024]创建的是全0填充的空数组,这根本不是合法的Java类字节码。ASM的ClassReader需要接收符合Java类文件格式的字节数组(比如从.class文件读取的内容),当它尝试解析全0的数组时,找不到类文件必需的魔数(0xCAFEBABE)等核心结构,就会抛出数组越界异常。
你发现数组长度≥14触发异常,是因为ASM解析类字节码时,会尝试读取前几个固定长度的字段(魔数4字节+版本号8字节,共12字节),当数组长度足够时,它会继续读取后续的类结构,但全0数组完全不符合格式,最终导致索引越界。
解决方案
给ClassReader传入真实有效的类字节码,以下是几种可行的实现方式:
方式1:读取当前类的字节码文件
直接读取当前类编译后的.class文件内容:
import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassWriter; import java.io.IOException; public class ModifyClassExample { public static void main(String[] args) throws IOException { // 读取当前类的.class文件字节码 byte[] b1 = ModifyClassExample.class.getResourceAsStream("ModifyClassExample.class").readAllBytes(); ClassWriter classWriter = new ClassWriter(0); ClassReader classReader = new ClassReader(b1); classReader.accept(classWriter, 0); byte[] b2 = classWriter.toByteArray(); } }
方式2:直接通过类名加载字节码
利用ClassReader的构造方法,直接传入类的全限定名,让ASM自动加载对应类的字节码:
import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassWriter; public class ModifyClassExample { public static void main(String[] args) { // 加载java.lang.String的字节码,也可以替换成你自己的类名 ClassReader classReader = new ClassReader("java.lang.String"); ClassWriter classWriter = new ClassWriter(0); classReader.accept(classWriter, 0); byte[] b2 = classWriter.toByteArray(); } }
方式3:先用ClassWriter生成一个简单类的字节码
如果只是想测试ASM的基础流程,也可以先通过ClassWriter生成一个极简的类字节码,再传给ClassReader:
import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.Opcodes; public class ModifyClassExample { public static void main(String[] args) { // 生成一个简单的空类的字节码 ClassWriter cw = new ClassWriter(0); cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, "TestClass", null, "java/lang/Object", null); cw.visitEnd(); byte[] b1 = cw.toByteArray(); // 用生成的字节码初始化ClassReader ClassReader classReader = new ClassReader(b1); ClassWriter classWriter = new ClassWriter(0); classReader.accept(classWriter, 0); byte[] b2 = classWriter.toByteArray(); } }
内容的提问来源于stack exchange,提问作者Bimi124
相关产品推荐
相关产品推荐

