0

我有时会摆弄ASM框架。我只想捕捉异常。

到目前为止,我能够try-catch在字节码中插入块并捕获异常。

这就是我现在正在做的事情。

public void visitMaxs(int maxStack, int maxLocals)
    {
        // visit try block end label
        this.visitLabel(lblTryBlockEnd);
        // visit normal execution exit block
        //this.visitJumpInsn(Opcodes.GOTO, exitBlock);

        // visit catch exception block
        this.visitLabel(lblCatchExceptionBlockStart);
        // store the exception
        this.visitVarInsn(Opcodes.ASTORE, 1);
        super.visitTypeInsn(Opcodes.NEW, "java/lang/Exception");
        super.visitInsn(Opcodes.DUP);

        // load the exception
        this.visitVarInsn(Opcodes.ALOAD, 1);
        // Initializing the exception object with the throwable cause
        super.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Exception", "<init>", "(Ljava/lang/Throwable;)V");

        // calling jensor method to write
        super.visitMethodInsn(Opcodes.INVOKESTATIC, 
                "test/ExceptionHandleTest", 
                "exceptionHandler", 
        "(Ljava/lang/Exception;)V");
                // call printStackTrace()
       this.visitInsn(Opcodes.ATHROW);



        // exit from this dynamic block
        this.visitLabel(exitBlock);

        super.visitMaxs(maxStack+2, maxLocals);

    }
`

现在,我不想抛出每个捕获的异常(就像我现在athrow每次都在做的那样),而是只想在它与exception方法签名的参数匹配时抛出MethodVisitor

我试图这样做,但得到Falling off the end of the code类验证错误。

可以使用 ASM 吗?

提前致谢。

4

2 回答 2

2

你可以这样做,我建议你用 Java 和 ASMifier 编写你想要的字节码,看看它是如何结构的。

有一个适用于 IDE 的 ASM 插件使这更容易。

于 2013-10-03T17:18:34.930 回答
0

您的代码片段提供的有关您实际操作的信息太少。您说您只想在特定条件下(重新)抛出异常,但您没有说您想要做什么。这与验证器错误完全匹配:如果您在某些条件下跳过 throw 指令并且没有提供方法的替代结束,您的代码就会脱离方法的结束。您必须为这种情况提供代码,例如受控返回。另一种方法是不捕获不符合您的标准的异常,但最终会导致与重新抛出所有异常相同的行为。

于 2013-11-07T11:50:38.190 回答