导致此错误的原因:java.lang.VerifyError:堆栈高度不一致2!=1.

导致此错误的原因:java.lang.VerifyError:堆栈高度不一致2!=1.,java,java-bytecode-asm,Java,Java Bytecode Asm,我使用ASM为while()语句生成字节码。但eclipse报告: Exception in thread "main" java.lang.VerifyError: (class: show_cise_image, method: main signature: ([Ljava/lang/String;)V) Inconsistent stack height 2 != 1 at java.lang.Class.getDeclaredMethods0(Native Method)

我使用ASM为while()语句生成字节码。但eclipse报告:

Exception in thread "main" java.lang.VerifyError: (class: show_cise_image, method: main signature: ([Ljava/lang/String;)V) Inconsistent stack height 2 != 1
    at java.lang.Class.getDeclaredMethods0(Native Method)
          ..................
我的字节码源代码:

show_cise_image {
    boolean flag;
    flag =  true;
    while(flag){
        flag = false;   
    }    
}
为上述代码生成的字节码:

/ class version 51.0 (51)
// access flags 0x21
public class show_cise_image {


  // access flags 0x8
  static int v = 0

  // access flags 0x8
  static boolean flag = 0

  // access flags 0x9
  public static main(String[]) : void
   L0
    LINENUMBER 6 L0
    GETSTATIC show_cise_image.flag : boolean
    LDC 1
    PUTSTATIC show_cise_image.flag : boolean
    GOTO L1
   L2
    GETSTATIC show_cise_image.flag : boolean
    LDC 0
    PUTSTATIC show_cise_image.flag : boolean
   L1
    GETSTATIC show_cise_image.flag : boolean
    IFNE L2
    RETURN
   L3
    LOCALVARIABLE args String[] L0 L3 2
    LOCALVARIABLE x int L0 L3 0
    LOCALVARIABLE y int L0 L3 1
    MAXSTACK = 3
    MAXLOCALS = 3
}
我的java代码生成字节码(我认为这个错误是由while()语句引起的,所以我只发布这部分):


让我们手动分析字节码:

L0                     ; on entry stack is empty
  LINENUMBER 6 L0
  GETSTATIC show_cise_image.flag : boolean ; pushes a value, stack height is 1
  LDC 1                                    ; pushes a value, stack heighe is 2  
  PUTSTATIC show_cise_image.flag : boolean ; pop 1 value, stack height is 1
  GOTO L1           ; stack height 1 on going to L1...

L1                  ; stack height 1 from previous goto
  GETSTATIC show_cise_image.flag : boolean ; pushes a value, stack height is 2
  IFNE L2           ; pops 1 value for test, stack height 1 on branch

L2                  ; stack height 1 from previous branch
  GETSTATIC show_cise_image.flag : boolean ; pushes a value, stack height is 2
  LDC 0                                    ; pushes a value, stack height is 3
  PUTSTATIC show_cise_image.flag : boolean ; pops a value, stack height is 2
  ; fall through to L1 with stack height 2
因此,到
L1
的两条路径上的堆栈深度不一致,导致出现验证错误


在我看来,您的错误是
L0
L2
块中无用的“GETSTATIC”字节码——您在堆栈上推送
标志的值,但从未对其进行任何处理。

这是因为内置的tomcat编译器

Eclipse JDT中的Java编译器作为默认编译器包括在内。它是一个高级Java编译器,将从Tomcat类加载器加载所有依赖项,这将在使用数十个JAR的大型安装上进行编译时大有帮助。在快速服务器上,即使是大型JSP页面,这也将允许亚秒级的重新编译周期

如果发现任何此类问题,请遵循以下解决方法


ApacheAnt在以前的Tomcat版本中使用过,只需删除lib/ecj-*.jar文件,就可以用它代替新编译器,并将最新ant发行版中的ant.jar和ant-launcher.jar文件放在lib文件夹中。

您知道:到达路径之间连接点的所有路径的堆栈高度必须相同。每次从L1块跳到L2块时,堆栈会更深两个元素。(虽然我不太明白为什么说他们只相隔1。)@HotLicks,谢谢你的回答。我是个新手,不熟悉字节码。请你提供更多细节好吗?谢谢!简单的要求是,在给定的标签条目上,堆栈深度必须始终相同,无论您是如何到达的。(对jsb条目的限制稍微放宽了一点。)阅读JVM规范中关于字节码验证的部分。@HotLicks,感谢您的解释。我发现在每个生成字节码指令的语句之前/之后添加注释非常有用,说明此时字节码堆栈包含的内容。这使得调试这个常见错误变得更加容易。非常感谢!!!现在可以了。我在处理任务陈述时犯了一个错误。我花了一整天的时间。你帮了我很多忙!
L0                     ; on entry stack is empty
  LINENUMBER 6 L0
  GETSTATIC show_cise_image.flag : boolean ; pushes a value, stack height is 1
  LDC 1                                    ; pushes a value, stack heighe is 2  
  PUTSTATIC show_cise_image.flag : boolean ; pop 1 value, stack height is 1
  GOTO L1           ; stack height 1 on going to L1...

L1                  ; stack height 1 from previous goto
  GETSTATIC show_cise_image.flag : boolean ; pushes a value, stack height is 2
  IFNE L2           ; pops 1 value for test, stack height 1 on branch

L2                  ; stack height 1 from previous branch
  GETSTATIC show_cise_image.flag : boolean ; pushes a value, stack height is 2
  LDC 0                                    ; pushes a value, stack height is 3
  PUTSTATIC show_cise_image.flag : boolean ; pops a value, stack height is 2
  ; fall through to L1 with stack height 2