Java 方法开始和结束时的仪器
我试图在jar中方法的开头和结尾添加某些指令。 下面是我在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) 由于您假设变量索引未使用(这本身就有问题),您是否确保新的
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 BuddyAdvice
可以为您更改此字节码。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 BuddyAdvice
可以为您更改此字节码。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