我正在调查以下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出了问题。 知道去哪里找会很有帮助。


当前回答

使用JRE > 6的CGLIB < 2.2可能会触发类似的错误,请参见“我应该升级到CGLIB 3.0吗?”和Spring sprr -9669上的一些评论。

当在JRE 6上一切工作正常,而仅仅切换到JRE7就会出现问题时,这一点尤其正确。

其他回答

我得到这个问题,由于pack200 manging一个类文件。稍微搜索一下就找到了这个java错误。基本上,设置——effort=4可以解决问题。

使用java 1.5.0_17(尽管它出现在我尝试的每一个java 1.5变体中)。

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

例如,当我试图运行一个针对Xerces 1编译的程序时,就发生了这种情况,但在类路径中找到了Xerces 2。必需的类(在org.apache中)。* namespace)在运行时被发现,所以ClassNotFoundException不是结果。对类和方法进行了更改,因此在运行时发现的方法签名与编译时的方法签名不匹配。

通常,编译器会在方法签名不匹配的地方标记问题。当类加载时,JVM将再次验证字节码,并在字节码试图做一些不应该被允许的事情时抛出VerifyError——例如,调用一个返回String的方法,然后将返回值存储在一个包含List的字段中。

您可以尝试使用-Xverify:all,它将在加载时验证字节码,如果字节码无效,有时会给出有用的错误消息。

在我的情况下,我必须删除这个块:

compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_7
    targetCompatibility JavaVersion.VERSION_1_7
}

在Fragment.showDialog()方法调用附近显示错误。

VerifyError意味着类文件包含的字节码在语法上是正确的,但违反了一些语义限制,例如跨越方法边界的跳转目标。

基本上,VerifyError只会发生在有编译器错误时,或者当类文件以其他方式损坏时(例如通过错误的RAM或失败的HD)。

尝试在不同的机器上使用不同的JDK版本进行编译。