奇怪的JVM验证错误:堆栈类型不匹配

时间:2014-08-01 18:30:02

标签: java jvm

我正在尝试使用asm-framework来检测类文件,以便在运行时基于布尔标志,对于某些类,我可以切换基类或其子类是否被实例化(所有这些都是透明地发生的用户的知识)。这是我的程序到目前为止生成的一个示例准asm。

  public void createInstance();
    flags: ACC_PUBLIC
        aload_1 //load the string flag
        ifnull label_0
        new com.example.BaseClass
        goto label_1
       label_0:
        new com.example.SubClass
       label_1:
        dup
        ldc "a"
        aload_1   //load the string flag
        ifnull label_2:
        invokespecial com.example.BaseClass.<init>(java.lang.String)
        goto label_3
       label_2:
        invokespecial com.example.SubClass.<init>(java.lang.String)
       label_3:
        astore_1
        return

问题是ASM没有抱怨生成类文件。但是,当我尝试使用以下错误运行此代码时JVM失败(此处显示的部分堆栈跟踪):

 Exception in thread "main" java.lang.VerifyError:  Mismatched stack types
    at java.lang.Class.getDeclaredConstructors0(Native Method)
    at java.lang.Class.privateGetDeclaredConstructors(Class.java:2446)
    at java.lang.Class.getConstructor0(Class.java:2756)
    at java.lang.Class.newInstance0(Class.java:328)
    at java.lang.Class.newInstance(Class.java:310)

我正在用JVM完成一项不可能完成的任务吗?如果没有,我如何纠正我的错误?

我在网上发现的类似错误:

任何帮助都非常感谢!

1 个答案:

答案 0 :(得分:1)

字节码验证器对基本块(字节码的线性段,不带分支指令或内部分支目标)进行操作。因此,有关label_1的确切课程的信息将丢失:它可能是BaseClassSubClass。这就是为什么JVM无法验证您是否正在调用正确的构造函数。

修改代码流,以便在BaseClass.<init>之后立即调用new BaseClass,在SubClass.<init>之后调用new SubClass,而无需跳转。