我正在按照本教程here进行操作,特别是第3部分:呼叫跟踪检测遇到了麻烦。我仍在尝试绕过访客模式,也许我在尝试运行此方法时出现一些错误。我的代码如下。
import java.io.FileInputStream;
import java.io.FileOutputStream;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
public class Copy {
public static void main(final String args[]) throws Exception {
FileInputStream is = new FileInputStream(args[0]);
ClassReader cr = new ClassReader(is);
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
cr.accept(cw, 0);
FileOutputStream fos = new FileOutputStream(args[1]);
fos.write(cw.toByteArray());
fos.close();
}
class ClassAdapter extends ClassVisitor implements Opcodes {
public ClassAdapter(final ClassVisitor cv) {
super(ASM5, cv);
}
@Override
public MethodVisitor visitMethod(final int access, final String name,
final String desc, final String signature, final String[] exceptions) {
MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions);
return mv == null ? null : new MethodAdapter(mv);
}
}
class MethodAdapter extends MethodVisitor implements Opcodes {
public MethodAdapter(final MethodVisitor mv) {
super(ASM5, mv);
}
@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
/* System.err.println("CALL" + name); */
mv.visitFieldInsn(GETSTATIC, "java/lang/System", "err", "Ljava/io/PrintStream;");
mv.visitLdcInsn("CALL " + name);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
/* do call */
mv.visitMethodInsn(opcode, owner, name, desc, itf);
/* System.err.println("RETURN" + name); */
mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "err", "Ljava/io/PrintStream;");
mv.visitLdcInsn("RETURN " + name);
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
}
}
}
我正在像本教程的上一个示例中那样运行
javac -cp asm-all-5.0.3.jar Copy.java
我似乎无法弄清我做错了什么,也无法将错误的结果here放到更干净的外观中。