我正试图使用ASM框架向类添加一个新方法public void create(){}
,但它引发了如下异常:
线程中的异常"主";java.lang.IollegalArgumentException:执行可能会从代码create((V 的末尾脱落
网址:org.objectweb.asm.util.CheckMethodAdapter$1.sthrowError(CheckMethodAdapter.java:474(网址:org.objectweb.asm.util.CheckMethodAdapter$1.visitEnd(CheckMethodAdapter.java:462(网址:org.objectweb.asm.MethodVisitor.visitEnd(MethodVisitor.java:783(位于org.objectweb.asm.util.CheckMethodAdapter.visitEnd(CheckMethodAdapter.java:1036(访问我.xx2ab.asmdemo.Waver01AddRemoveFieldAndMethod$onProcess$classVisitor$1.visitEnd(Weaver01AddRemoveFieldAndMethod.kt:41(网址:org.objectweb.asm.ClassReader.accept(ClassReader.java:715(网址:org.objectweb.asm.ClassReader.accept(ClassReader.java:394(
这里是代码:
val classReader = ClassReader(inputStream)
val classWriter = ClassWriter(classReader, COMPUTE_FRAMES or COMPUTE_MAXS)
val classVisitor = object : ClassVisitor(ASM9, CheckClassAdapter(classWriter, true)) {
override fun visitEnd() {
// visitField(
// Opcodes.ACC_PUBLIC,
// "newFieldName",
// "Ljava/lang/String;",
// null,
// null
// ).visitEnd()
visitMethod(
Opcodes.ACC_PUBLIC,
"create",
"()V",
null,
null
)?.visitEnd() // This is where exception throws
super.visitEnd()
}
}
classReader.accept(classVisitor, 0)
我试着把super.visitEnd()
移到visitMethod
前面;调用visitEnd后无法访问成员"然而,类似的操作也适用于visitField
,就像我注释掉的片段一样。
不确定实现这一要求的真正方法是什么。。
根据@Holger在注释中的指示,我最终通过添加一个方法体来解决这个问题:
// Add a new method
val mv = classWriter.visitMethod(
Opcodes.ACC_PUBLIC,
"create",
"()V",
null,
null
)
mv.visitFieldInsn(
GETSTATIC,
"java/lang/System",
"out",
"Ljava/io/PrintStream;"
)
mv.visitLdcInsn("this is add method print!")
mv.visitMethodInsn(
INVOKEVIRTUAL,
"java/io/PrintStream",
"println",
"(Ljava/lang/String;)V",
false
)
mv.visitInsn(RETURN)
// this code uses a maximum of two stack elements and two local
// variables
mv.visitMaxs(0, 0)
mv.visitEnd()
return classWriter.toByteArray()