我正在调查以下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出了问题。
知道去哪里找会很有帮助。
生成错误的最小示例
一种简单的方法是使用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的情况下生成源代码。
生成错误的最小示例
一种简单的方法是使用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的情况下生成源代码。