I want to keep track of all method calls. I have an additional class which is named writerTest. So I want to add method call for writerTest.print(FullMethodName) at the beginning of each method. I worked on it. Found some tutorials about it but I could not handle. Here is the code I have. In this particular example I could add method call at the first line. But I could not get method name with ALOAD 0 or etc. ALOAD 0 gets this. If I used visitMethodInsn instead of visitcode, result is wrong
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
public class MyInstrumenter {
public static void main(final String args[]) throws Exception {
FileInputStream is = new FileInputStream(args[0]);
byte[] b;
ClassReader cr = new ClassReader(is);
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
ClassVisitor cv = new ClassAdapter(cw);
cr.accept(cv, 0);
b = cw.toByteArray();
FileOutputStream fos = new FileOutputStream(args[1]);
fos.write(b);
fos.close();
}
}
Class Adapter Class
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,
String signature,
String[] exceptions) {
MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions);
return new MethodAdapter(mv) ;
}
}
Method Adapter class
class MethodAdapter extends MethodVisitor implements Opcodes {
public MethodAdapter(final MethodVisitor mv) {
super(ASM5, mv);
}
@Override
public void visitCode() {
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "com/yunus/test", "print", " (Ljava/lang/Object;)V",false);
super.visitCode();
}
}
You did not describe what was went wrong... Can you please add the details?
Two pointers: 1. in
visitCode()
callsuper.visitCode()
before you execute your own code.