获取 java.lang.VerifyError 的原因

2022-08-31 06:12:07

我正在调查以下内容java.lang.VerifyError

java.lang.VerifyError: (class: be/post/ehr/wfm/application/serviceorganization/report/DisplayReportServlet, method: getMonthData signature: (IILjava/util/Collection;Ljava/util/Collection;Ljava/util/HashMap;Ljava/util/Collection;Ljava/util/Locale;Lorg/apache/struts/util/MessageRe˜̴Mt̴MÚw€mçw€mp:”MŒŒ
                at java.lang.Class.getDeclaredConstructors0(Native Method)
                at java.lang.Class.privateGetDeclaredConstructors(Class.java:2357)
                at java.lang.Class.getConstructor0(Class.java:2671)

当部署了 servlet 的 jboss 服务器启动时,就会发生这种情况。它是用jdk-1.5.0_11编译的,我试图用jdk-1.5.0_15重新编译它,但没有成功。也就是说,编译运行良好,但在部署时,会发生java.lang.VerifyError。

当我更改方法名称并得到以下错误时:

java.lang.VerifyError: (class: be/post/ehr/wfm/application/serviceorganization/report/DisplayReportServlet, method: getMD signature: (IILjava/util/Collection;Lj    ava/util/Collection;Ljava/util/HashMap;Ljava/util/Collection;Ljava/util/Locale;Lorg/apache/struts/util/MessageResources ØÅN|ØÅNÚw€mçw€mX#ÖM|XÔM
            at java.lang.Class.getDeclaredConstructors0(Native Method)
            at java.lang.Class.privateGetDeclaredConstructors(Class.java:2357
            at java.lang.Class.getConstructor0(Class.java:2671)
            at java.lang.Class.newInstance0(Class.java:321)
            at java.lang.Class.newInstance(Class.java:303)

您可以看到显示了更多的方法签名。

实际的方法签名是

  private PgasePdfTable getMonthData(int month, int year, Collection dayTypes,
                          Collection calendarDays,
                          HashMap bcSpecialDays,
                          Collection activityPeriods,
                          Locale locale, MessageResources resources) throws   Exception {

我已经尝试过用它来查看它,这给出了应有的方法签名。javap

当我的其他同事检查代码,编译并部署它时,他们遇到了同样的问题。当生成服务器选取代码并将其部署到开发或测试环境 (HPUX) 上时,会发生相同的错误。此外,运行 Ubuntu 的自动测试机在服务器启动期间显示相同的错误。

应用程序的其余部分运行正常,只有一个 servlet 是无序的。任何寻找的想法都会有所帮助。


答案 1

java.lang.VerifyError可能是针对与运行时使用不同的库进行编译时的结果。

例如,当我尝试运行针对 Xerces 1 编译的程序时,我遇到了这种情况,但是在类路径上发现了 Xerces 2。所需的类(在命名空间中)是在运行时找到的,因此不是结果。对类和方法进行了更改,因此在运行时找到的方法签名与编译时存在的方法签名不匹配。org.apache.*ClassNotFoundException

通常,编译器将标记方法签名不匹配的问题。JVM 将在加载类时再次验证字节码,并在字节码尝试执行不应允许的操作时抛出 - 例如,调用返回的方法,然后将返回值存储在保存 .VerifyErrorStringList


答案 2

java.lang.VerifyError是最糟糕的。

如果方法的字节码大小超过64kb限制,则会出现此错误;但你可能已经注意到了这一点。

您是否 100% 确定此类不存在于应用程序其他位置的类路径中,可能存在于另一个 jar 中?

此外,从堆栈跟踪中,源文件的字符编码是 (?)这是对的吗?utf-8