简体   繁体   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?

I am using ASM 5.0.3 bytecode modification library with Tomcat 8 and JDK 8. 我正在将ASM 5.0.3字节码修改库与Tomcat 8和JDK 8一起使用。

My intention is to inject bytecode successfully into all the classes. 我的意图是将字节码成功注入所有类中。 However, I encountered the following error: 但是,我遇到以下错误:

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)

The key parts of the code that I used in order to call ASM's methods are as follows: 我用来调用ASM方法的代码的关键部分如下:

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

classReader.accept(myClassVisitor, ClassReader.EXPAND_FRAMES);

The above code works perfectly well with bytecode modification of a JDK 6 application. 上面的代码与JDK 6应用程序的字节码修改完美配合。 The error shows up only for JDK 7 and JDK 8 applications. 该错误仅针对JDK 7和JDK 8应用程序显示。

Various blog posts and stackoverflow posts point to using the -XX:-UseSplitVerifier or the -noverify flags. 各种博客文章和stackoverflow文章都指向使用-XX:-UseSplitVerifier或-noverify标志。 However this seems like a short-term workaround especially given that the -XX:-UseSplitVerifier flag is deprecated in JDK 8. I would like to achieve a permanent solution rather than rely on a flag that would eventually be unsupported in future Java releases. 但是,这似乎是一个短期解决方法,特别是考虑到JDK 8中不推荐使用-XX:-UseSplitVerifier标志。我想实现一个永久解决方案,而不是依赖将来在Java发行版中最终不支持的标志。

Thank you in advance. 先感谢您。

Edit: In reference to Adam's kind suggestion of using COMPUTE_FRAMES instead of COMPUTE_MAXS , this link ASM - java.lang.VerifyError: Operand stack overflow Exception summarizes the errors so far with COMPUTE_FRAMES . 编辑:关于Adam使用COMPUTE_FRAMES而不是COMPUTE_MAXS建议,此链接ASM-java.lang.VerifyError:操作数堆栈溢出Exception总结了到目前为止COMPUTE_FRAMES的错误。 Currently, I am unable to progress on JDK 7/8 with either of COMPUTE_MAXS or COMPUTE_FRAMES . 目前,我无法使用COMPUTE_MAXSCOMPUTE_FRAMES在JDK 7/8上进行COMPUTE_FRAMES

Use the ClassWriter#COMPUTE_FRAMES flag for the stack map frames to be recomputed. ClassWriter#COMPUTE_FRAMES标志用于要重新计算的堆栈映射帧。 The bytecode verifier uses typechecker (stack map) from JDK 7 on , so that's why your code works on JDK 6. 字节码验证程序使用JDK 7 on上的 typechecker(堆栈映射),因此这就是您的代码可在JDK 6上运行的原因。

Note that (from COMPUTE_FRAMES JavaDoc): 请注意(来自COMPUTE_FRAMES JavaDoc):

computeFrames implies computeMaxs computeFrames暗含computeMaxs

I fixed the issue, after extending ClassWriter class and override the method getCommonSuperClass. 在扩展ClassWriter类并覆盖方法getCommonSuperClass之后,我解决了该问题。

Please check this ASM 5.0.3 With Java 1.8 incorrect maxStack with Java.lang.VerifyError: Operand stack overflow 使用Java 1.8检查此ASM 5.0.3与Java.lang.VerifyError的不正确的maxStack:操作数堆栈溢出

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在java 7中运行单元测试:java.lang.VerifyError:在分支目标处期望一个stackmap帧 - How do I get unit test to run in java 7: java.lang.VerifyError: Expecting a stackmap frame at branch target java.lang.VerifyError:期望一个stackmap框架 - java.lang.VerifyError: Expecting a stackmap frame java.lang.VerifyError:在分支目标 JDK 1.7 处需要堆栈图帧 - java.lang.VerifyError: Expecting a stackmap frame at branch target JDK 1.7 java.lang.VerifyError:期望分支目标上的stackmap帧 - java.lang.VerifyError: Expecting a stackmap frame at branch target java.lang.VerifyError:期望分支目标73处的堆栈图帧 - java.lang.VerifyError: Expecting a stackmap frame at branch target 73 使用Play Framework和Google App Engine的“ VerifyError:期待堆栈图框架” - “VerifyError: Expecting a stackmap frame” using Play Framework and Google App Engine java.lang.VerifyError:在分支目标29处期待一个堆栈映射框架 - java.lang.VerifyError: Expecting a stackmap frame at branch target 29 java.lang.VerifyError:在分支目标 5 处期望堆栈图帧 - java.lang.VerifyError: Expecting a stackmap frame at branch target 5 期待一个堆栈映射框架-Java 8 - Expecting a stackmap frame - Java 8 线程“ main”中的异常java.lang.VerifyError:在分支目标118处期望一个堆栈映射框架 - Exception in thread “main” java.lang.VerifyError: Expecting a stackmap frame at branch target 118
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM