【问题标题】:Causes of getting a java.lang.VerifyError获取 java.lang.VerifyError 的原因
【发布时间】:2010-09-11 03:15:54
【问题描述】:

我正在调查以下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 出现故障。 任何可以查看的想法都会有所帮助。

【问题讨论】:

  • 我是因为使用了错误版本的比较失败。花了 FOREVER 才找到……那很痛苦
  • 我在 Android Studio 中使用即时运行时得到了它(编译时热交换)。把它关掉就行了。

标签: java exception deployment verifyerror


【解决方案1】:

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

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

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

【讨论】:

  • 补充一点,有时是IDE的问题,或者是字节码不对的设备。尝试重新启动 IDE 以使其识别同步问题。未能删除并重新安装该应用程序。重启设备也可能有帮助。
  • 要找出哪个类是罪魁祸首,请添加 VM 参数 -verbose:class,然后在它加载之前查找类 java.lang.VerifyError。这将具有 JAR 的路径。使用javap 并将其与您正在编译的类进行比较。我发现这很有用,因为错误中报告的类不是原因,它实际上是参数之一。
【解决方案2】:

java.lang.VerifyError 是最糟糕的。

如果您方法的字节码大小超过 64kb 限制,您将收到此错误;但你可能已经注意到了。

您是否 100% 确定该类不存在于您应用程序的其他地方的类路径中,也许在另一个 jar 中?

另外,从您的堆栈跟踪来看,源文件的字符编码是 (utf-8?) 正确吗?

【讨论】:

  • 我确定它不存在于其他地方。它是 43Kb,这仍然是一个大类。
  • 感谢那篇文章,在我的例子中,它是一个不同的编码:JasperReports XMl 文件保存一个编码和一个 java 版本,你必须根据你的项目设置进行设置(通过 iReport)。这就是这里的问题,感谢您对编码的想法! :)
  • 这是我的 android 测试问题,multidexing 解决了它。
  • 谢谢@p3t0r!对我来说,类路径上加载了两个 ojdbc jar。删除一个解决了问题。
【解决方案3】:

正如 Kevin Panko 所说,这主要是因为库的变化。 所以在某些情况下,对项目(目录)进行“清理”,然后进行构建就可以了。

【讨论】:

    【解决方案4】:

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

    【讨论】:

    • 请问,你如何申请-Xverify:all
    【解决方案5】:

    我通过使我正在导入库的项目在 Android 上修复了此错误,如此处所述http://developer.android.com/tools/projects/projects-eclipse.html#SettingUpLibraryProject

    以前,我只是在引用该项目(而不是使其成为一个库),我得到了这个奇怪的 VerifyError。

    希望对某人有所帮助。

    【讨论】:

    • 链接已失效,请修复。谢谢
    【解决方案6】:

    VerifyError 表示类文件包含语法正确但违反某些语义限制的字节码,例如跨越方法边界的跳转目标。

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

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

    【讨论】:

      【解决方案7】:

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

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

      【讨论】:

      • Dalvik 只是 Java6 的一个分支版本,因此没有可用的 Java7 功能!
      【解决方案8】:

      由于 pack200 破坏了一个类文件,我遇到了这个问题。经过一番搜索,这个java bug 上升了。基本上,设置--effort=4 会导致问题消失。

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

      【讨论】:

        【解决方案9】:

        我通过替换修复了类似的 java.lang.VerifyError 问题

                catch (MagickException e)
        

                catch (Exception e)
        

        MagickException 是在库项目中定义的(我的项目依赖于该库项目)。

        在那之后我得到了一个java.lang.NoClassDefFoundError,关于同一个库中的一个类(根据https://stackoverflow.com/a/9898820/755804 修复)。

        【讨论】:

        • 这对我有用......我真的很想弄清楚除了“用一揽子异常替换我,我会工作”之外的错误。
        • @AlexHart 适用于 Android,但同样的逻辑可能适用于企业 Java:stackoverflow.com/a/36814155/253468
        【解决方案10】:

        当您尝试加载针对 Oracle 的 JDK 编译的库时,这可能会在 Android 上发生。

        Here is the problem 用于 Ning Async HTTP 客户端。

        【讨论】:

        • 你找到解决方案了吗@MartinKonicek
        【解决方案11】:

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

        compileOptions {
            sourceCompatibility JavaVersion.VERSION_1_7
            targetCompatibility JavaVersion.VERSION_1_7
        }
        

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

        【讨论】:

          【解决方案12】:

          产生错误的最小示例

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

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

          在 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.jjavap -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 编译器为我们添加了一个隐式的 returnvoid 方法。这就是为什么我们不需要在main 方法中添加return。您可以通过javap 进行检查。

          JVMS

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

          JVMS 说,当 Java 加载文件时,它必须在运行之前运行一系列检查以查看类文件是否正常。

          此类错误不会在 Java 代码的单个编译和运行周期中产生,因为JVMS 7 4.10 says:

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

          所以要查看一个最小的失败示例,我们需要生成不带javac 的源代码。

          【讨论】:

            【解决方案13】:

            此页面可能会给您一些提示 - http://www.zanthan.com/itymbi/archives/000337.html

            该方法的主体中可能存在 javac 未能发现的细微错误。除非您在此处发布整个方法,否则很难诊断。

            您可以首先声明尽可能多的变量作为最终变量...这将捕获 zanthan 网站上提到的错误,并且通常是一个很好的做法。

            【讨论】:

            • 那家伙在 2002 年遇到了编译器错误,但从那时起该错误已得到修复。
            【解决方案14】:

            在我的例子中,我的项目 A 依赖于另一个项目,比如 X(A 正在使用 X 中定义的一些类)。所以当我在 A 的构建路径中添加 X 作为参考项目时,我得到了这个错误。但是,当我将 X 作为引用项目删除并将 X 的 jar 作为库之一包含时,问题就解决了。

            【讨论】:

              【解决方案15】:

              在您的类路径中检查同一 jar 文件的多个版本。

              例如,我的类路径中有 opennlp-tools-1.3.0.jar 和 opennlp-tools-1.5.3.jar 并收到此错误。解决方法是删除 opennlp-tools-1.3.0.jar。

              【讨论】:

                【解决方案16】:

                CGLIB 6 可能会触发类似的错误,请参阅"Should I upgrade to CGLIB 3.0?"Spring SPR-9669 的一些评论。

                当在 JRE 6 上一切正常而简单地切换到 JRE7 时,尤其如此。

                【讨论】:

                  【解决方案17】:

                  此错误的另一个原因可能是 AspectJ 6 的组合。

                  详情请参阅Eclipse Bug 353467Kieker ticket 307

                  当在 JRE 6 上一切正常而迁移到 JRE7 时,尤其如此。

                  【讨论】:

                    【解决方案18】:

                    当您使用 maven 导入大量模块时,也会发生这种情况。 将有两个或多个类具有完全相同的名称(相同的限定名称)。 此错误是由于编译时和运行时之间的解释不同造成的。

                    【讨论】:

                      【解决方案19】:

                      如果您正在迁移到 java7 或使用 java7,那么通常可以看到此错误。我遇到了上述错误并努力找出根本原因,我建议在运行您的应用程序时尝试添加 "-XX:-UseSplitVerifier" JVM 参数。

                      【讨论】:

                        【解决方案20】:

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

                        有一个 Glideerror。解决方法是重写proguard-rules.txt

                        降级 Gradle 也有效 (classpath 'com.android.tools.build:gradle:3.5.3'),但它是一个过时的解决方案,不要使用它。

                        【讨论】:

                          【解决方案21】:

                          虽然 Kevin 提到的原因是正确的,但我肯定会在转到其他内容之前检查以下内容:

                          1. 检查我的类路径中的cglibs
                          2. 检查我的类路径中的hibernate 版本。

                          上述任何一个版本的多个版本或相互冲突的版本很可能会导致与相关问题类似的意外问题。

                          【讨论】:

                            【解决方案22】:

                            java.lang.VerifyError 表示您编译的字节码指的是 Android 无法找到的内容。此 verifyError 仅向我发出 kitkat4.4 和不在上述版本中的较小版本,即使我在两个设备中运行相同的构建。当我使用旧版本的杰克逊 json 解析器时,它显示 java.lang.verifyerror

                            compile 'com.fasterxml.jackson.core:jackson-databind:2.2.+'
                            compile 'com.fasterxml.jackson.core:jackson-core:2.2.+'
                            compile 'com.fasterxml.jackson.core:jackson-annotations:2.2.+'
                            

                            然后我将依赖关系更改为 最新版本 2.2 到 2.7 没有 核心库,然后它就可以工作了。这意味着core的Methods和其他内容被迁移到了最新版本的Databind2.7。这解决了我的问题。

                            compile 'com.fasterxml.jackson.core:jackson-annotations:2.7.0-rc3'
                            compile 'com.fasterxml.jackson.core:jackson-databind:2.7.0-rc3'
                            

                            【讨论】:

                            • 你怎么知道要查找哪个 JAR?
                            • jackson-core:2.2.+ 已成为传统。所以我们需要使用 databind:2.7.0-rc3, annotations:2.7.0-rc3 或最新版本。这 2 就足够了,避免使用 jackson-core:2.2.+ 。到那时我得到了一些验证错误。使用 2.7+ 版本时不会显示该错误
                            【解决方案23】:

                            请删除所有不可用的 jar 文件并尝试运行。及其对我的工作我添加了一个 jcommons jar 文件和另一个 jcommons.1.0.14 jar 文件,因此删除 jcommons 及其为我工作

                            【讨论】:

                              【解决方案24】:

                              写入文件:

                              {Wildfly-home}\modules\system\layers\base\org\picketbox\main 
                              

                              接下来进入依赖:<module name="sun.jdk"/>

                              【讨论】:

                                【解决方案25】:

                                在我的情况下,我在下面的堆栈跟踪中遇到了验证错误

                                jasperreports-server-cp-6.4.0-bin\buildomatic\build.xml:61: The following error occurred while executing this line:
                                TIB_js-jrs-cp_6.4.0_bin\jasperreports-server-cp-6.4.0-bin\buildomatic\bin\setup.xml:320: java.lang.VerifyError: (class: org/apache/commons/codec/binary/Base64OutputStream, method: <init> signature: (Ljava/io/OutputStream;ZI[B)V) Incompatible argument to function
                                    at com.jaspersoft.jasperserver.crypto.KeystoreManager.createKeystore(KeystoreManager.java:257)
                                    at com.jaspersoft.jasperserver.crypto.KeystoreManager.init(KeystoreManager.java:224)
                                    at com.jaspersoft.buildomatic.crypto.KeystoreTask.execute(KeystoreTask.java:64)
                                    at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:292)
                                    at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source)
                                    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
                                    at java.lang.reflect.Method.invoke(Method.java:498)
                                    at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
                                    at org.apache.tools.ant.Task.perform(Task.java:348)
                                    at org.apache.tools.ant.taskdefs.Sequential.execute(Sequential.java:68)
                                    at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:292)
                                    at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source)
                                    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
                                    at java.lang.reflect.Method.invoke(Method.java:498)
                                    at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
                                    at org.apache.tools.ant.Task.perform(Task.java:348)
                                    at org.apache.tools.ant.Target.execute(Target.java:435)
                                    at org.apache.tools.ant.helper.ProjectHelper2.parse(ProjectHelper2.java:169)
                                    at org.apache.tools.ant.taskdefs.ImportTask.importResource(ImportTask.java:222)
                                    at org.apache.tools.ant.taskdefs.ImportTask.execute(ImportTask.java:163)
                                    at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:292)
                                    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                                    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
                                    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
                                    at java.lang.reflect.Method.invoke(Method.java:498)
                                    at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
                                    at org.apache.tools.ant.Task.perform(Task.java:348)
                                    at org.apache.tools.ant.Target.execute(Target.java:435)
                                    at org.apache.tools.ant.helper.ProjectHelper2.parse(ProjectHelper2.java:180)
                                    at org.apache.tools.ant.ProjectHelper.configureProject(ProjectHelper.java:93)
                                    at org.apache.tools.ant.Main.runBuild(Main.java:826)
                                    at org.apache.tools.ant.Main.startAnt(Main.java:235)
                                    at org.apache.tools.ant.launch.Launcher.run(Launcher.java:280)
                                    at org.apache.tools.ant.launch.Launcher.main(Launcher.java:109)
                                

                                我通过删除 commons-codec-1.3.jar 的类路径条目解决了这个问题,这个 jar 的版本与 Jasper 附带的版本不匹配。

                                【讨论】:

                                  猜你喜欢
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 2022-10-06
                                  • 2016-07-01
                                  • 2021-08-09
                                  • 2013-05-21
                                  • 1970-01-01
                                  • 2012-10-26
                                  相关资源
                                  最近更新 更多