Causas de obtener un java.lang.VerifyError

191

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)

Se produce cuando se inicia el servidor jboss en el que se implementa el servlet. Está compilado con jdk-1.5.0_11 y traté de recompilarlo con jdk-1.5.0_15 sin éxito. Esa es la compilación funciona bien, pero cuando se implementa, se produce el 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 de la 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 con javapy 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, solo que un servlet está fuera de servicio. Cualquier idea sobre dónde buscar sería útil.

Jeroen Wyseur
fuente
1
Lo obtuve al usar la versión incorrecta de ComparisonFailure. Tomó PARA SIEMPRE encontrar ... eso fue doloroso
Tim Boland
1
Lo obtuve cuando uso la ejecución instantánea en el estudio de Android (hotswapping en la compilación). Apagarlo hizo el trabajo.
Serge

Respuestas:

188

java.lang.VerifyError puede ser el resultado cuando compiló en una biblioteca diferente de la que está utilizando en tiempo de ejecución.

Por ejemplo, esto me sucedió al intentar ejecutar un programa que se compiló contra Xerces 1, pero Xerces 2 se encontró en el classpath. Las clases requeridas (en el org.apache.*espacio de nombres) se encontraron en tiempo de ejecución, por ClassNotFoundExceptionlo que no 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 lo que había en tiempo de compilación.

Normalmente, el compilador marcará problemas donde las firmas de métodos no coinciden. La JVM verificará el bytecode nuevamente cuando se cargue la clase, y arrojará VerifyErrorcuando el bytecode intente hacer algo que no debería permitirse, por ejemplo, llamar a un método que devuelve Stringy luego almacena ese valor de retorno en un campo que contiene a List.

Kevin Panko
fuente
3
Una cosa para agregar, a veces es culpa del IDE o del dispositivo que el código de bytes no es correcto. Intente reiniciar el IDE para que reconozca el problema de sincronización. Si no, elimine y vuelva a instalar la aplicación. Reiniciar el dispositivo también puede ayudar.
ima747
2
Para averiguar qué clase es la culpable, agregue el argumento VM -verbose:classy luego busque la clase justo antes de que se cargue java.lang.VerifyError. Esto tendrá el camino hacia el JAR. Use javapy compare eso con la clase con la que está compilando. Encontré esto útil ya que la clase que se informó en el error no fue la causa, sino que fue uno de los argumentos.
steinybot
21

java.lang.VerifyError son los peores.

Obtendrá este error si el tamaño del código de bytes de su método excede el límite de 64 kb; pero probablemente te habrás dado cuenta de eso.

¿Estás 100% seguro de que esta clase no está presente en el classpath en otra parte de tu aplicación, tal vez en otro frasco?

Además, desde su stacktrace, ¿es la codificación de caracteres del archivo fuente ( utf-8?) ¿Es correcto?

p3t0r
fuente
Estoy seguro de que no está presente en otro lugar. Son 43Kb, eso sigue siendo una gran clase.
Jeroen Wyseur el
Gracias por esa publicación, en mi caso, era una codificación diferente: los archivos JasperReports XMl guardan una codificación y una versión java, debe configurar esto de acuerdo con la configuración de su proyecto (a través de iReport). Ese fue el problema aquí, ¡gracias por tu idea con la codificación! :)
Tobias
Este fue mi problema para las pruebas de Android, multidexing lo solucionó.
Prakash Nadar
10

Como dijo Kevin Panko, se debe principalmente al cambio de biblioteca. Entonces, en algunos casos, una "limpieza" del proyecto (directorio) seguido de una compilación hace el truco.

Fluir
fuente
9

Una cosa que puede intentar es usar, -Xverify:allque verificará el bytecode en la carga y, a veces, dará mensajes de error útiles si el bytecode no es válido.

Alex Miller
fuente
8

VerifyError significa que el archivo de clase contiene un código de bytes que es sintácticamente correcto pero viola alguna restricción semántica, por ejemplo, un objetivo de salto que cruza los límites del método.

Básicamente, un VerifyError solo puede ocurrir cuando hay un error del compilador o cuando el archivo de clase se corrompe de alguna otra manera (por ejemplo, a través de una RAM defectuosa o un HD defectuoso).

Intente compilar con una versión diferente de JDK y en una máquina diferente.

Michael Borgwardt
fuente
5

En mi caso, mi proyecto de Android depende de otro proyecto Java compilado para Java 7. java.lang.VerifyErrordesapareció después de cambiar el Nivel de cumplimiento del compilador de ese proyecto Java a 6.0

Más tarde descubrí que este es un problema de Dalvik: https://groups.google.com/forum/?fromgroups#!topic/android-developers/sKsMTZ42pwE

Michal Vician
fuente
1
¡Dalvik es solo una versión ramificada de Java6, por lo que no hay funciones Java7 disponibles!
Jeroen Wyseur
4

Estaba teniendo este problema debido a que pack200 destrozó un archivo de clase. Un poco de búsqueda convirtió este error de Java . Básicamente, la configuración --effort=4causó que el problema desapareciera.

Usando java 1.5.0_17 (aunque surgió en cada variante de java 1.5 lo probé).

Mike Miller
fuente
3

He solucionado un problema similar de java.lang.VerifyError reemplazando

        catch (MagickException e)

con

        catch (Exception e)

donde MagickExceptionse definió en un proyecto de biblioteca (del cual mi proyecto tiene una dependencia).

Después de eso, recibí java.lang.NoClassDefFoundErroraproximadamente una clase de la misma biblioteca (corregida de acuerdo con https://stackoverflow.com/a/9898820/755804 ).

18446744073709551615
fuente
1
Esto funcionó para mí ... Realmente me gustaría descubrir cuál fue el error además de "reemplazarme con una excepción general y trabajaré".
Alex Hart
@AlexHart es para Android, pero probablemente la misma lógica se aplicaría para Java empresarial: stackoverflow.com/a/36814155/253468
TWiStErRob
2

Esto puede suceder en Android cuando intentas cargar una biblioteca compilada con el JDK de Oracle.

Aquí está el problema para el cliente HTTP Ning Async.

Martin Konicek
fuente
¿Ya ha encontrado una solución para esto @MartinKonicek
Abimbola Esuruoso
2

En mi caso tuve que eliminar este bloque:

compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_7
    targetCompatibility JavaVersion.VERSION_1_7
}

Estaba mostrando un error cerca de la Fragment.showDialog()llamada al método.

ViliusK
fuente
2

Ejemplo mínimo que genera el error.

Una posibilidad simple es usar Jasmin , o editar manualmente el código de bytes con un editor de archivos binarios.

Vamos a crear un voidmétodo sin una returninstrucción (generada por la return;declaración en Java), que el JVMS dice que es ilegal.

En Jasmin podríamos escribir:

.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

Luego lo hacemos javac Main.jy javap -v Maindice que hemos compilado:

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

así que realmente no hay instrucciones de devolución.

Ahora si tratamos de correr java Mainobtenemos:

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)

Este error nunca puede ocurrir en Java normalmente, ya que el compilador de Java agrega un implícito returna los voidmétodos para nosotros. Es por eso que no necesitamos agregar returna nuestros mainmétodos. Puedes verificar esto con javap.

JVMS

VerifyError ocurre cuando intenta ejecutar ciertos tipos de archivos de clase ilegales según lo especificado por JVMS 7 capítulo 4.5

El JVMS dice que cuando Java carga un archivo, debe ejecutar una serie de comprobaciones para ver si el archivo de clase está bien antes de ejecutarlo.

Tales errores no se pueden generar en un solo ciclo de compilación y ejecución de código Java, porque JVMS 7 4.10 dice :

Aunque un compilador para el lenguaje de programación Java solo debe producir archivos de clase que satisfagan todas las restricciones estáticas y estructurales [...]

Entonces, para ver un ejemplo de falla mínima, tendremos que generar el código fuente sin él javac.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
fuente
1

Esta página puede darle algunos consejos: http://www.zanthan.com/itymbi/archives/000337.html

Puede haber un error sutil en el cuerpo de ese método que javac no puede detectar. Difícil de diagnosticar a menos que publique todo el método aquí.

Podría comenzar declarando tantas variables como sea posible como final ... eso habría detectado el error mencionado en el sitio de Zanthan, y de todos modos es una buena práctica.

Lars Westergren
fuente
1
Ese tipo golpeó un error del compilador en 2002, pero ese error se ha solucionado desde entonces.
Kevin Panko
1

Bueno, en mi caso, mi proyecto A dependía de otro, digamos X (A estaba usando algunas de las clases definidas en X). Entonces, cuando agregué X como proyecto de referencia en la ruta de compilación de A, recibí este error. Sin embargo, cuando eliminé X como el proyecto referenciado e incluí el jar de X como una de las bibliotecas, el problema se resolvió.

usuario2484130
fuente
1

Compruebe si hay varias versiones del mismo archivo jar en su classpath.

Por ejemplo, tenía opennlp-tools-1.3.0.jar y opennlp-tools-1.5.3.jar en mi classpath y obtuve este error. La solución fue eliminar opennlp-tools-1.3.0.jar.

demongolem
fuente
1

CGLIB <2.2 con JRE> 6 podría desencadenar errores similares, consulte "¿Debo actualizar a CGLIB 3.0?" y algunos comentarios en Spring SPR-9669 .

Esto es especialmente cierto cuando todo funciona bien en JRE 6 y simplemente cambiar a JRE7 rompe las cosas.

Alexander Wessel
fuente
1

Otra razón para este error puede ser la combinación de AspectJ <= 1.6.11 con JRE> 6.

Consulte el error Eclipse 353467 y el boleto 307 de Kieker para obtener más detalles.

Esto es especialmente cierto cuando todo funciona bien en JRE 6 y pasar a JRE7 rompe las cosas.

Alexander Wessel
fuente
1

También podría suceder cuando tienes muchas importaciones de módulos con maven. Habrá dos o más clases que tengan exactamente el mismo nombre (mismo nombre calificado). Este error es el resultado de la diferencia de interpretación entre el tiempo de compilación y el tiempo de ejecución.

Toumi
fuente
1

Si está migrando a java7 o está usando java7, generalmente se puede ver este error. Me enfrenté a los errores anteriores y luché mucho para descubrir la causa raíz, sugeriría intentar agregar el argumento JVM "-XX: -UseSplitVerifier" mientras ejecutaba su aplicación.

Ulhas N
fuente
1

Después de actualizar Gradleen Android Studio 3.6.1 se bloqueos en API 19 en la versión de compilación.

Hubo un error deGlide biblioteca . La solución es reescribir proguard-rules.txt .

También la degradación Gradlefunciona ( classpath 'com.android.tools.build:gradle:3.5.3'), pero es una solución desactualizada, no la use.

CoolMind
fuente
0

Aunque la razón mencionada por Kevin es correcta, definitivamente verificaría a continuación antes de pasar a otra cosa:

  1. Verifica cglibsen mi classpath.
  2. Verifique las hibernateversiones en mi classpath.

Es muy probable que tener una versión múltiple o conflictiva de cualquiera de los anteriores pueda causar problemas inesperados como el en cuestión.

Sandeep Jindal
fuente
0

java.lang.VerifyError significa que su bytecode compilado se refiere a algo que Android no puede encontrar. Esto verifica que el error me emite solo con kitkat4.4 y versiones inferiores que no están en la versión anterior de eso, incluso ejecuté la misma compilación en ambos dispositivos. cuando utilicé el analizador jackson json de la versión anterior, muestra 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.+'

Luego, cambié la dependencia a la última versión 2.2 a 2.7 sin la biblioteca principal , luego funciona. lo que significa que los métodos y otros contenidos del núcleo se migran a la última versión de Databind2.7 . Esto soluciona mis problemas.

compile 'com.fasterxml.jackson.core:jackson-annotations:2.7.0-rc3'
compile 'com.fasterxml.jackson.core:jackson-databind:2.7.0-rc3'
anand krish
fuente
¿Cómo sabes qué JAR buscar?
Siddharth
1
jackson-core: 2.2. + se convirtió en legado. así que necesitamos usar databind: 2.7.0-rc3, anotaciones: 2.7.0-rc3 o la última versión que esta. Este 2 es suficiente, evite jackson-core: 2.2. +. Tengo un poco de verifyerror para ese momento. mientras usa la versión 2.7+ no muestra ese error
anand krish
0

elimine cualquier archivo jar inutilizable e intente ejecutarlo. y funciona para mí, agregué un archivo jar jcommons y también otro archivo jar jcommons.1.0.14, así que elimine jcommons y funciona para mí

Jat Rahul
fuente
0

escribir en el archivo:

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

en dependencias a continuación: <module name="sun.jdk"/>

Eduardo Morales
fuente
-1

En mi caso, estaba obteniendo un error de verificación con el siguiente seguimiento de la pila

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)

Lo resolví eliminando la entrada classpath para commons-codec-1.3.jar, había una discrepancia en la versión de este jar con la que viene con Jasper.

Aashirwad Sinha
fuente