views:

11028

answers:

6

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 methodname and got the following error:

java.lang.VerifyError: (class: be/post/ehr/wfm/application/serviceorganization/r    eport/DisplayReportServlet, method: getMD signature: (IILjava/util/Collection;Lj    ava/util/Collection;Ljava/util/HashMap;Ljava/util/Collection;Ljava/util/Locale;L    org/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 to 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 ok, only that one servlet is out of order. Any ideas where to look would be helpful.

A: 

This page may give you some hints - http://www.zanthan.com/itymbi/archives/000337.html

There may be a subtle bug in the body of that method that javac fails to spot. Difficult to diagnose unless you post the whole method here.

You could start by declaring as many variables as possible as final... that would have caught the bug mentioned on the zanthan site, and is often a good practice anyways.

Lars Westergren
That guy hit a compiler bug back in 2002, but that bug has been fixed since then.
Kevin Panko
+2  A: 

java.lang.VerifyError are the worst.

You would get this error if the bytecode size of your method exceeds the 64kb limit; but you would probably have noticed that.

Are you 100% sure this class isn't present in the classpath elsewhere in your application, maybe in another jar?

Also, from your stacktrace, is the character encoding of the source file (utf-8?) correct?

p3t0r
I'm sure it is not present somewhere else. It's 43Kb, that is still a big class.
JeroenWyseur
+1  A: 

One thing you might try is using -Xverify:all which will verify bytecode on load and sometimes gives helpful error messages if the bytecode is invalid.

Alex Miller
Thanks for the suggestion but did not reveal anything more.
JeroenWyseur
+2  A: 

I was getting this problem due to pack200 mangling a class file. A bit of searching turned this java bug up. Basically, stetting --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).

Mike Miller
+1  A: 

VerifyError means that the class file contains bytecode that is syntactically correct but violates some semantic restriction e.g. a jump target that crosses method boundaries.

Basically, a VerifyError can only occur when there is a compiler bug, or when the class file gets corrupted in some other way (e.g. through faulty RAM or a failing HD).

Try compiling with a different JDK version and on a different machine.

Michael Borgwardt
+2  A: 

java.lang.VerifyError can be the result when you have compiled against a different library than you are using at runtime.

For example, this happened to me when trying to run a program that was compiled against Xerces 1, but Xerces 2 was found on the classpath. The required classes (in org.apache.* namespace) were found at runtime, so ClassNotFoundException was not the result. There had been changes to the classes and methods, so that the method signatures found at runtime did not match what was there at compile-time.

Normally, the compiler will flag problems where method signatures do not match. The JVM will verify the bytecode again when the class is loaded, and throws VerifyError when the bytecode is trying to do something that should not be allowed -- e.g. calling a method that returns String and then stores that return value in a field that holds a List.

Kevin Panko