AdviceAdapter onMethodExit从未调用过

时间:2016-10-06 17:37:51

标签: java-bytecode-asm

我正在尝试检测cassandra驱动程序,特别需要修改ResultSet类以挂起一些信息。为了做到这一点,我需要修改分配实例的代码,这是另一个类中的静态方法。代码中包含以下代码段:

return r.metadata.pagingState == null
    ? new SinglePage(columnDefs, tokenFactory, protocolVersion, columnDefs.codecRegistry, r.data, info)
    : new MultiPage(columnDefs, tokenFactory, protocolVersion, columnDefs.codecRegistry, r.data, info, r.metadata.pagingState, session);

该方法中还有其他返回值。所以我的想法是在这个方法上使用AdviceAdapter并使用onMethodExit()。但是,我的方法从未被调用过。这似乎很荒谬......因为这个方法必须要回归!经过一些调试后,我发现AdviceAdapter类中的visitInsn()只被调用一次,操作码为IALOAD(从数组中加载一个int?)。

我想我的问题是......到底是怎么回事?嘿..抱歉,今天在我的办公桌上磕了几次。

编辑:我改变了我的类是一个简单的MethodVisitor只是为了看看是否可以看到更多的操作码,事实上我做到了!我明白了!我再也无法访问dup()了。 :(

1 个答案:

答案 0 :(得分:0)

我在我的一个项目中使用了EmailAdviceAdaptor(用于 javax / mail / Transport ),代码如下。希望此代码有助于解决您的问题。

package com.mail.agent.adapter;

import com.mail.jtm.BTMConstants;
import com.mail.org.objectweb.asm.Label;
import com.mail.org.objectweb.asm.MethodVisitor;
import com.mail.org.objectweb.asm.Opcodes;
import com.mail.org.objectweb.asm.Type;
import com.mail.org.objectweb.asm.commons.AdviceAdapter;

public class MyEmailAdviceAdapter extends AdviceAdapter  {

private String methodName;
private String className;
private String description;

private static final String MAIL_SEND_METHOD1_DESC="(Ljavax/mail/Message;)V";
private static final String MAIL_SEND_METHOD2_DESC="(Ljavax/mail/Message;[Ljavax/mail/Address;)V";
private static final String MAIL_SENDMESSAGE_METHOD_DESC="(Ljavax/mail/Message;[Ljavax/mail/Address;)V"; 

private boolean isSendMethod;

private int okFlag =  newLocal(Type.BOOLEAN_TYPE); 
Label startFinally = new Label();

public MyEmailAdviceAdapter(int access , MethodVisitor mv , String methodName, String description, String className, int classFileVersion){
    super(Opcodes.ASM5 , mv, access, methodName, description);
    this.className = className;
    this.methodName = methodName;
    this.description = description;
    this.isSendMethod = false;

    if(methodName.equals("send")){
        if( description.equals(MAIL_SEND_METHOD1_DESC) || description.equals(MAIL_SEND_METHOD2_DESC)){
            isSendMethod = true;
        }
    }
    else if(methodName.equals("sendMessage") && description.equals(MAIL_SENDMESSAGE_METHOD_DESC)){
        isSendMethod = true;
    }
}

public void visitCode() {
    super.visitCode(); 
    mv.visitLabel(startFinally);
}

protected void onMethodEnter(){
    if(isSendMethod) {
        mv.visitInsn(Opcodes.ICONST_0);
        mv.visitVarInsn(ISTORE, okFlag);

        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitLdcInsn(className);
        mv.visitLdcInsn(methodName);
        mv.visitLdcInsn(description);
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "com/mail/agent/trace/MailTracer", "mailMethodBegin", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z"; , false);
        mv.visitVarInsn(ISTORE, okFlag);
    }
}

protected void onMethodExit(int opcode){
    if(opcode!=ATHROW) {
        onFinally(opcode);
    }
}

public void visitMaxs(int maxStack, int maxLocals){
    Label endFinally = new Label();
    mv.visitTryCatchBlock(startFinally, endFinally, endFinally, null);
    mv.visitLabel(endFinally);
    onFinally(ATHROW);
    mv.visitInsn(ATHROW);
    mv.visitMaxs(maxStack, maxLocals);
}

private void onFinally(int opcode){
    if(isSendMethod){
        // If the method throws any exception
        if(opcode == ATHROW){
            mv.visitInsn(Opcodes.DUP);
            mv.visitLdcInsn(className);
            mv.visitLdcInsn(methodName);
            mv.visitLdcInsn(description);
            mv.visitVarInsn(ILOAD, okFlag);
            mv.visitMethodInsn(Opcodes.INVOKESTATIC, "com/mail/agent/trace/MailTracer", "recordException", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V", false);
        }
        mv.visitLdcInsn(className);
        mv.visitLdcInsn(methodName);
        mv.visitLdcInsn(description);
        mv.visitVarInsn(ILOAD, okFlag);
        mv.visitLdcInsn(opcode);
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "com/mail/agent/trace/MailTracer", "mailMethodEnd", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZI)V", false);
    }
 }

}

相关问题