导致java.lang.VerifyError错误的原因

我正在调查以下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出了问题。

.

.
320096 次浏览
本页可能会给您一些提示 http://www.zanthan.com/itymbi/archives/000337.html < / p >

在该方法的主体中可能存在javac未能发现的微妙错误。很难诊断,除非你把整个方法贴在这里。

你可以先声明尽可能多的变量作为final…这将捕获zanthan网站上提到的bug,而且通常是一个很好的实践。

java.lang.VerifyError是最差的。

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

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

同样,从你的stacktrace中,是源文件的字符编码(utf-8?)对吗?

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

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

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

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

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

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

java.lang.VerifyError可以是当你在运行时使用不同的库进行编译时的结果。

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

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

正如Kevin Panko所说,这主要是因为库的变化。 因此,在某些情况下,“清理”项目(目录),然后构建是有效的

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

以前,我只是引用项目(没有使它成为一个库),我得到这个奇怪的VerifyError。

希望它能帮助到别人。

我已经修复了类似的java.lang.VerifyError问题替换

        catch (MagickException e)

        catch (Exception e)

其中MagickException是在一个库项目中定义的(我的项目依赖于它)。

在此之后,我获得了关于来自同一库的类的java.lang.NoClassDefFoundError(根据https://stackoverflow.com/a/9898820/755804进行修正)。

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

这就是问题所在用于Ning异步HTTP客户端。

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

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

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

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

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}

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

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

例如,我的类路径中有opennlp-tools-1.3.0.jar和opennlp-tools-1.5.3.jar,并得到了这个错误。解决方案是删除opennlp-tools-1.3.0.jar。

导致此错误的另一个原因可能是AspectJ <= 1.6.11与JRE >的组合。

详见Eclipse Bug 353467Kieker票307

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

CGLIB & lt;2.2与JRE > 6可能触发类似的错误,参见“我应该升级到CGLIB 3.0吗?”春天spr - 9669中的一些注释。

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

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

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

有多个或冲突的上述任何一个版本可能会导致意想不到的问题,就像上面提到的那样。

生成错误的最小示例

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

让我们在没有return指令(由Java中的return;语句生成)的情况下创建void方法,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.j,而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编译器为我们添加了一个隐式的returnvoid方法。这就是为什么我们不需要在main方法中添加return。你可以用javap来检查。

jvm

当你试图运行由jvm 7第4.5章指定的某些类型的非法类文件时,会发生VerifyError

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

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

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

因此,为了查看最小失败示例,我们需要生成没有javac的源代码。

当你用maven导入很多模块时,也会发生这种情况。 将有两个或多个类具有完全相同的名称(相同的限定名)。 此错误是由编译时和运行时之间的解释差异引起的

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

verifyerror意味着你编译的字节码指向了Android无法找到的东西。这个verifyError只向我发出Kitkat4.4和较低版本不在以上版本,即使我在两个设备上运行相同的构建。当我使用老版本的jackson 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,然后它就工作了。这意味着核心的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文件并尝试运行。我添加了一个jcommons jar文件和另一个jcommons.1.0.14 jar文件,所以删除jcommons,它为我工作

在我的情况下,我得到验证错误与以下堆栈跟踪

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)

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

写入文件:

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

<module name="sun.jdk"/>

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

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

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