Java 方法开始和结束时的仪器

Java 方法开始和结束时的仪器,java,java-bytecode-asm,Java,Java Bytecode Asm,我试图在jar中方法的开头和结尾添加某些指令。 下面是我在SampleJar类中的目标 SampleJar.java Sender.java 下面是我在EntityModifier类中尝试的内容 EntityModifier.java 从STARTIME\u索引检索值时似乎出现问题 这种方法有什么问题吗?1)您是否知道Long与Long和Integer不同于int?不必要时不要使用包装器类型。2) 为什么在第一个示例中定义三个变量?3) 由于您假设变量索引未使用(这本身就有问题),您是否确保新的

我试图在jar中方法的开头和结尾添加某些指令。 下面是我在
SampleJar
类中的目标

SampleJar.java
Sender.java
下面是我在
EntityModifier
类中尝试的内容

EntityModifier.java
STARTIME\u索引
检索值时似乎出现问题


这种方法有什么问题吗?

1)您是否知道
Long
Long
Integer
不同于
int
?不必要时不要使用包装器类型。2) 为什么在第一个示例中定义三个变量?3) 由于您假设变量索引未使用(这本身就有问题),您是否确保新的max变量反映在类文件中(即,您是否使用
COMPUTE\u max
COMPUTE\u FRAMES
)?展示真实的课堂访客会有所帮助。4) 关于如何使用
LocalVariablesSorter
,可能会有所帮助。如果您不想自己使用ASM执行此操作,Byte Buddy
Advice
可以为您更改此字节码。Byte Buddy既不需要使用
COMPUTE_FRAMES
这是一个相当麻烦且昂贵的选项。Byte Buddy让您可以在普通Java中实现这一点,并且可能具有更好的运行时性能。(公开声明:我是Byte Buddy的作者)我支持Rafael的建议,并想提及另一个选项:AspectJ。我已经用了很多年了,对它很满意。如果你也需要低层次的东西并且不怕的话,ByteBuddy也很棒。但是您可能并不害怕,否则您现在就不会使用ASM了。1)您是否意识到
Long
Long
Integer
不同于
int
?不必要时不要使用包装器类型。2) 为什么在第一个示例中定义三个变量?3) 由于您假设变量索引未使用(这本身就有问题),您是否确保新的max变量反映在类文件中(即,您是否使用
COMPUTE\u max
COMPUTE\u FRAMES
)?展示真实的课堂访客会有所帮助。4) 关于如何使用
LocalVariablesSorter
,可能会有所帮助。如果您不想自己使用ASM执行此操作,Byte Buddy
Advice
可以为您更改此字节码。Byte Buddy既不需要使用
COMPUTE_FRAMES
这是一个相当麻烦且昂贵的选项。Byte Buddy让您可以在普通Java中实现这一点,并且可能具有更好的运行时性能。(公开声明:我是Byte Buddy的作者)我支持Rafael的建议,并想提及另一个选项:AspectJ。我已经用了很多年了,对它很满意。如果你也需要低层次的东西并且不怕的话,ByteBuddy也很棒。但可能您并不害怕,否则您现在就不会使用ASM。
package sample;
import snd_pkg.Sender;

public class SampleJar {

public static void func(){
    long l1=System.nanoTime(); //Instruction to be inserted
    /*
     * Existing instructions
     */
    long l2=System.nanoTime();  //Instruction to be inserted
    (new Sender()).send(l1,l2); //Instruction to be inserted
   }
}
package snd_pkg;

public class Sender {
 public  void send(long start,long stop)
   {
       //do something
   }
}
public class EtityModifier extends AdviceAdapter {


protected EtityModifier(int api, MethodVisitor methodVisitor, int access, String name, String descriptor) {
    super(api, methodVisitor, access, name, descriptor);
    
}

private final static int STARTIME_INDEX = 100;
private final static int STOPTIME_INDEX = 102;


@Override
protected void onMethodEnter() { 
    // Invoking the nanoTime method
    mv.visitMethodInsn(INVOKESTATIC, "java/lang/System", "nanoTime", "()J", false);
    // Storing long type value at STARTIME_INDEX
    mv.visitVarInsn(LSTORE, STARTIME_INDEX);
}

@Override
protected void onMethodExit(final int opcode) {
    if (opcode == RETURN || opcode == ARETURN || opcode == DRETURN || opcode == FRETURN || opcode == IRETURN
            || opcode == LRETURN) {
        // Invoking the nanoTime method
        mv.visitMethodInsn(INVOKESTATIC, "java/lang/System", "nanoTime", "()J", false);
        // Storing long type value in a local variable at STOPTIME_INDEX
        mv.visitVarInsn(LSTORE, STOPTIME_INDEX);
        // create Sender object
        mv.visitTypeInsn(NEW, "snd_pkg/Sender");
        // dup
        mv.visitInsn(DUP);
        // call Sender Constructor
        mv.visitMethodInsn(INVOKESPECIAL, "snd_pkg/Sender", "<init>", "()V", false);
        // Loading startTime from STARTIME_INDEX
        mv.visitVarInsn(LLOAD, STARTIME_INDEX);
        // Loading stopTime from STOPTIME_INDEX
        mv.visitVarInsn(LLOAD, STOPTIME_INDEX);
        // call send Method
        mv.visitMethodInsn(INVOKEVIRTUAL, "snd_pkg/Sender", "send", "(JJ)V", false);
    }
  }
}
java.lang.VerifyError: Bad local variable type
Type top (current frame, locals[100]) is not assignable to long