簡體   English   中英

如何克服JDK 7/8應用程序的“ VerifyError:Expecting a stackmap frame”?

[英]How do I overcome the “VerifyError:Expecting a stackmap frame” for a JDK 7/8 application?

我正在將ASM 5.0.3字節碼修改庫與Tomcat 8和JDK 8一起使用。

我的意圖是將字節碼成功注入所有類中。 但是,我遇到以下錯誤:

java.lang.VerifyError: Expecting a stackmap frame at branch target 18
Exception Details:
  Location:
    com/sun/crypto/provider/SunJCE.getInstance()Lcom/sun/crypto/provider/SunJCE; @0: getstatic
  Reason:
    Expected stackmap frame at this location.
  Bytecode:
    0x0000000: b200 0bc7 000b bb00 3659 b700 0cb0 b200
    0x0000010: 0bb0 bf                                
  Exception Handler Table:
    bci [0, 18] => handler: 18
  Stackmap Table:
    append_frame(@14,Integer)

            at java.lang.Class.getDeclaredConstructors0(Native Method)
            at java.lang.Class.privateGetDeclaredConstructors(Unknown Source)
            at java.lang.Class.getConstructor0(Unknown Source)
            at java.lang.Class.newInstance(Unknown Source)
            at sun.security.jca.ProviderConfig$2.run(Unknown Source)
            at sun.security.jca.ProviderConfig$2.run(Unknown Source)
           ......Some more uninteresting lines in the stack trace.......
            at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
            at java.lang.reflect.Method.invoke(Unknown Source)
            at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:310)
            at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:484)

我用來調用ASM方法的代碼的關鍵部分如下:

ClassWriter classWriter = new  ClassWriter(classReader, ClassWriter.COMPUTE_MAXS);

classReader.accept(myClassVisitor, ClassReader.EXPAND_FRAMES);

上面的代碼與JDK 6應用程序的字節碼修改完美配合。 該錯誤僅針對JDK 7和JDK 8應用程序顯示。

各種博客文章和stackoverflow文章都指向使用-XX:-UseSplitVerifier或-noverify標志。 但是,這似乎是一個短期解決方法,特別是考慮到JDK 8中不推薦使用-XX:-UseSplitVerifier標志。我想實現一個永久解決方案,而不是依賴將來在Java發行版中最終不支持的標志。

先感謝您。

編輯:關於Adam使用COMPUTE_FRAMES而不是COMPUTE_MAXS建議,此鏈接ASM-java.lang.VerifyError:操作數堆棧溢出Exception總結了到目前為止COMPUTE_FRAMES的錯誤。 目前,我無法使用COMPUTE_MAXSCOMPUTE_FRAMES在JDK 7/8上進行COMPUTE_FRAMES

ClassWriter#COMPUTE_FRAMES標志用於要重新計算的堆棧映射幀。 字節碼驗證程序使用JDK 7 on上的 typechecker(堆棧映射),因此這就是您的代碼可在JDK 6上運行的原因。

請注意(來自COMPUTE_FRAMES JavaDoc):

computeFrames暗含computeMaxs

在擴展ClassWriter類並覆蓋方法getCommonSuperClass之后,我解決了該問題。

使用Java 1.8檢查此ASM 5.0.3與Java.lang.VerifyError的不正確的maxStack:操作數堆棧溢出

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM