Causas de obtener un java.lang.VerifyError
Estoy investigando lo siguiente 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)
Ocurre cuando se inicia el servidor jboss en el que está implementado el servlet. Está compilado con jdk-1.5.0_11 e intenté recompilarlo con jdk-1.5.0_15 sin éxito. Es decir, la compilación funciona bien, pero cuando se implementa, se produce java.lang.VerifyError.
Cuando cambié el nombre del método y obtuve el siguiente 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)
Puede ver que se muestra más firma del método.
La firma del método real es:
private PgasePdfTable getMonthData(int month, int year, Collection dayTypes,
Collection calendarDays,
HashMap bcSpecialDays,
Collection activityPeriods,
Locale locale, MessageResources resources) throws Exception {
Ya intenté mirarlo javap
y eso le da la firma del método como debería ser.
Cuando mis otros colegas revisan el código, lo compilan y lo implementan, tienen el mismo problema. Cuando el servidor de compilación recoge el código y lo implementa en entornos de desarrollo o prueba (HPUX), se produce el mismo error. Además, una máquina de prueba automatizada que ejecuta Ubuntu muestra el mismo error durante el inicio del servidor.
El resto de la aplicación funciona bien, sólo que un servlet no funciona. Cualquier idea sobre dónde buscar sería útil.
java.lang.VerifyError
puede ser el resultado cuando ha compilado con una biblioteca diferente a la que está utilizando en tiempo de ejecución.
Por ejemplo, esto me sucedió cuando intenté ejecutar un programa que fue compilado contra Xerces 1, pero se encontró Xerces 2 en el classpath. Las clases requeridas (en el org.apache.*
espacio de nombres) se encontraron en tiempo de ejecución, por lo que noClassNotFoundException
fue el resultado. Hubo cambios en las clases y métodos, de modo que las firmas de métodos encontradas en tiempo de ejecución no coincidían con las que había en tiempo de compilación.
Normalmente, el compilador señalará problemas en los que las firmas de los métodos no coinciden. La JVM verificará el código de bytes nuevamente cuando se cargue la clase y lo lanzará VerifyError
cuando el código de bytes esté intentando hacer algo que no debería permitirse, por ejemplo, llamar a un método que devuelve String
y luego almacena ese valor de retorno en un campo que contiene un archivo List
.
java.lang.VerifyError
son los peores.
Recibirá este error si el tamaño del código de bytes de su método excede el límite de 64 kb; pero probablemente lo habrías notado.
¿Está 100% seguro de que esta clase no está presente en el classpath de otra parte de su aplicación, tal vez en otro contenedor?
Además, según su seguimiento de pila, ¿la codificación de caracteres del archivo fuente ( utf-8
?) ¿Es correcta?
Como dijo Kevin Panko, se debe principalmente al cambio de biblioteca. Entonces, en algunos casos, una "limpieza" del proyecto (directorio) seguida de una compilación es suficiente.
Una cosa que puede intentar es usar -Xverify:all
el cual verificará el código de bytes durante la carga y, a veces, mostrará mensajes de error útiles si el código de bytes no es válido.