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


当前回答

在Android上,当你试图加载一个根据Oracle的JDK编译的库时,就会发生这种情况。

这里是Ning异步HTTP客户端的问题。

其他回答

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

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

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

生成错误的最小示例

一种简单的方法是使用Jasmin,或者使用二进制文件编辑器手动编辑字节码。

让我们创建一个没有return指令的void方法(由return生成;语句),jvm认为这是非法的。

在Jasmin中我们可以这样写:

.class public Main
.super java/lang/Object

.method public static main([Ljava/lang/String;)V
   aload_0 ; Just so that we won't get another verify error for empty code.
.end method

然后我们使用javac Main。javap -v Main表示我们已经编译了:

public static void main(java.lang.String[]);
  descriptor: ([Ljava/lang/String;)V
  flags: ACC_PUBLIC, ACC_STATIC
  Code:
    stack=1, locals=1, args_size=1
       0: aload_0

所以实际上没有返回指令。

现在如果我们尝试运行java Main,我们得到:

Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.VerifyError: (class: NoReturn, method: main signature: ([Ljava/lang/String;)V) Falling off the end of the code
        at java.lang.Class.getDeclaredMethods0(Native Method)
        at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
        at java.lang.Class.privateGetMethodRecursive(Class.java:3048)
        at java.lang.Class.getMethod0(Class.java:3018)
        at java.lang.Class.getMethod(Class.java:1784)
        at sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:544)
        at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:526)

这种错误在Java中通常不会发生,因为Java编译器为我们添加了一个隐式返回void方法。这就是为什么我们不需要在主方法中添加return。你可以用javap检查。

JVMS

当您尝试运行JVMS 7第4.5章指定的某些类型的非法类文件时,将发生VerifyError

jvm说,当Java加载一个文件时,它必须在运行类文件之前运行一系列检查,以确定类文件是OK的。

这样的错误不能在Java代码的一次编译和运行周期中产生,因为JVMS 7 4.10说:

尽管Java编程语言的编译器必须只生成满足所有静态和结构约束的类文件[…] ]

因此,为了查看最小失败示例,我们需要在不使用javac的情况下生成源代码。

在我的情况下,我的Android项目依赖于另一个为Java 7编译的Java项目。Java .lang. verifyerror在我将Java项目的编译器遵从级别更改为6.0后消失了

后来我发现这是一个Dalvik问题:https://groups.google.com/forum/?fromgroups#!主题/ android开发者/ sKsMTZ42pwE

java.lang.VerifyError是最差的。

如果方法的字节码大小超过64kb限制,就会得到这个错误;但你可能已经注意到了。

您是否100%确定这个类不存在于应用程序的类路径中,比如在另一个jar中?

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

在Android Studio 3.6.1中更新Gradle后,在发布版本的API 19上发生了崩溃。

有一个格莱德库错误。解决方法是重写proguard-rules.txt。

降级Gradle也可以(类路径为'com.android.tools.build: Gradle:3.5.3'),但这是一个过时的解决方案,不要使用它。