使用ASM创建新对象

时间:2013-09-05 04:12:52

标签: bytecode java-bytecode-asm bytecode-manipulation

我一直在尝试使用ASM框架在我感兴趣的位置注入字节码,直到现在我一直很成功。目前我正在尝试注入代码,它基本上创建了一个类的新实例/对象,并在阅读了一下之后发现这可以通过INVOKESPECIAL来实现(我希望我的理解是对于私有方法和构造函数的INVOKESPECIAL“INVOKESPECIAL”)。

下面是我用来创建实例的代码片段

visitor.visitLdcInsn(System.currentTimeMillis());
visitor.visitLdcInsn(System.currentTimeMillis());
visitor.visitLdcInsn(_type);
visitor.visitVarInsn(ALOAD, metanamevarindex);

eventObject = newLocal(Type.getType("com/vish/RequestTrackerEvent"));

visitor.visitMethodInsn(Opcodes.INVOKESPECIAL, "com/vish/RequestTrackerEvent", "<init>",
                            "(JJLjava/lang/String;Ljava/lang/String;)V");

visitor.visitVarInsn(ASTORE, eventObject);

该类的构造函数接受4个参数(long,long,String,String) 但每当我这样做时,我会得到如下的异常

java.lang.VerifyError: JVMVRFY036 stack underflow;
    at java.lang.J9VMInternals.verifyImpl(Native Method)
    at java.lang.J9VMInternals.verify(J9VMInternals.java:72)
    at java.lang.J9VMInternals.verify(J9VMInternals.java:70)
    at java.lang.J9VMInternals.initialize(J9VMInternals.java:134)

任何人都可以帮助我理解我对INVOKESPECIAL的使用/理解是否正确,如果正确,我在哪里做错了?

由于

2 个答案:

答案 0 :(得分:2)

我并不完全记得newLocal()的作用,但我知道该方法不会在字节码中插入新指令。它可以在一些ASM内部局部变量处理机制中保留空间。

尝试使用类似

的内容
visitor.visitTypeInst(Opcodes.NEW, "com/vish/RequestTrackerEvent");
祝你好运

答案 1 :(得分:1)

问题如“如何使用ASM生成{某些Java代码}”has been answered in ASM FAQ

  

如果您想知道如何生成同步块,请尝试捕获   block,finally语句或任何其他Java构造,编写   要在临时类中生成的Java代码,使用它进行编译   javac,然后使用ASMifier获取将要的ASM代码   生成此类(请参阅“10. How do I get the bytecode of an existing class?”)。

您可以更进一步,通过比较this article中描述的转换前后ASMifier的输出。