如何克服JDK 7/8应用程序的“VerifyError:Expecting stackmap frame”?(How do I overcome the “VerifyError:Expecting

编程入门 行业动态 更新时间:2024-10-17 12:32:16
如何克服JDK 7/8应用程序的“VerifyError:Expecting stackmap frame”?(How do I overcome the “VerifyError:Expecting a stackmap frame” for a JDK 7/8 application?) java

我正在使用带有Tomcat 8和JDK 8的ASM 5.0.3字节码修改库。

我的目的是将字节码成功注入所有类。 但是,我遇到以下错误:

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:操作数堆栈溢出异常使用COMPUTE_FRAMES汇总了到目前为止的错误。 目前,我无法使用COMPUTE_MAXS或COMPUTE_FRAMES进行JDK 7/8。

I am using ASM 5.0.3 bytecode modification library with Tomcat 8 and 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:

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. The error shows up only for JDK 7 and JDK 8 applications.

Various blog posts and stackoverflow posts point to using the -XX:-UseSplitVerifier or the -noverify flags. 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.

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. Currently, I am unable to progress on JDK 7/8 with either of COMPUTE_MAXS or COMPUTE_FRAMES.

最满意答案

使用ClassWriter#COMPUTE_FRAMES标志重新计算堆栈映射帧。 字节码验证器使用来自JDK 7的 typechecker(堆栈映射),这就是为什么你的代码在JDK 6上工作的原因。

注意(来自COMPUTE_FRAMES JavaDoc):

computeFrames意味着computeMaxs

I fixed the issue, after extending ClassWriter class and override the method getCommonSuperClass.

Please check this ASM 5.0.3 With Java 1.8 incorrect maxStack with Java.lang.VerifyError: Operand stack overflow

更多推荐

本文发布于:2023-07-15 05:43:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1110754.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:应用程序   Expecting   VerifyError   JDK   overcome

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!