我正在尝试检测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()了。 :(答案 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);
}
}
}