Causes of getting a java.lang.VerifyError

2018-12-31 02:36发布

I'm investigating the following 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)

It occurs when the jboss server in which the servlet is deployed is started. It is compiled with jdk-1.5.0_11 and I tried to recompile it with jdk-1.5.0_15 without succes. That is the compilation runs fine but when deployed, the java.lang.VerifyError occurs.

When I changed the method name and got the following error:

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)

You can see that more of the method signature is shown.

The actual method signature is

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

I already tried looking at it with javap and that gives the method signature as it should be.

When my other colleagues check out the code, compile it and deploy it, they have the same problem. When the build server picks up the code and deploys it on development or testing environments (HPUX), the same error occurs. Also an automated testing machine running Ubuntu shows the same error during server startup.

The rest of the application runs okay, only that one servlet is out of order. Any ideas where to look would be helpful.

23条回答
君临天下
2楼-- · 2018-12-31 02:49

Minimal example that generates the error

One simple possibility is to use Jasmin, or to manually edit the bytecode with a binary file editor.

Lets create void method without a return instruction (generated by the return; statement in Java), which the JVMS says is illegal.

In Jasmin we could write:

.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

We then do javac Main.j and javap -v Main says that we have compiled:

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

so really there is no return instruction.

Now if we try to run java Main we get:

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)

This error can never happen in Java normally, since the Java compiler adds an implicit return to void methods for us. This is why we don't need to add a return to our main methods. You can check this with javap.

JVMS

VerifyError happens when you try to run certain types of illegal class file as specified by JVMS 7 chapter 4.5

The JVMS says that when Java loads a file, it must run a series of checks to see that the class file is OK before running it.

Such errors cannot be generated on a single compile and run cycle of Java code, because JVMS 7 4.10 says:

Even though a compiler for the Java programming language must only produce class files that satisfy all the static and structural constraints [... ]

So to see a minimal failure example, we will need to generate the source code without javac.

查看更多
浅入江南
3楼-- · 2018-12-31 02:52

Though the reason mentioned by Kevin is correct, but I would definitely check below before moving to something else:

  1. Check the cglibs in my classpath.
  2. Check the hibernate versions in my classpath.

Chances are good that having multiple or conflicting version of any of the above could cause unexpected issues like the one in question.

查看更多
爱死公子算了
4楼-- · 2018-12-31 02:52

please remove any unusable jar file and try to run. and its work for me i added a jcommons jar file and also another jcommons.1.0.14 jar file so remove jcommons and its working for me

查看更多
像晚风撩人
5楼-- · 2018-12-31 02:53

In my case my Android project depends on another Java project compiled for Java 7. java.lang.VerifyError disappeared after I changed Compiler Compliance Level of that Java project to 6.0

Later I found out that this is a Dalvik issue: https://groups.google.com/forum/?fromgroups#!topic/android-developers/sKsMTZ42pwE

查看更多
旧时光的记忆
6楼-- · 2018-12-31 02:54

I was getting this problem due to pack200 mangling a class file. A bit of searching turned this java bug up. Basically, setting --effort=4 caused the problem to go away.

Using java 1.5.0_17 (though it cropped up in every single variant of java 1.5 I tried it in).

查看更多
高级女魔头
7楼-- · 2018-12-31 02:54

java.lang.VerifyError means your compiled bytecode is referring to something that Android cannot find. This verifyError Issues me only with kitkat4.4 and lesser version not in above version of that even I ran the same build in both Devices. when I used jackson json parser of older version it shows 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.+'

Then I have changed the Dependancy to the latest version 2.2 to 2.7 without the core library, then it works. which means the Methods and other contents of core is migrated to the latest version of Databind2.7. This fix my Issues.

compile 'com.fasterxml.jackson.core:jackson-annotations:2.7.0-rc3'
compile 'com.fasterxml.jackson.core:jackson-databind:2.7.0-rc3'
查看更多
登录 后发表回答