Cause di ottenere un java.lang.VerifyError


191

Sto studiando quanto segue 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)

Si verifica quando viene avviato il server jboss in cui viene distribuito il servlet. È compilato con jdk-1.5.0_11 e ho provato a ricompilarlo con jdk-1.5.0_15 senza successo. Vale a dire che la compilation funziona correttamente ma quando viene distribuita, si verifica java.lang.VerifyError.

Quando ho cambiato il nome del metodo e ho ottenuto il seguente errore:

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)

Puoi vedere che viene mostrata una parte maggiore della firma del metodo.

La firma del metodo effettivo è

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

Ho già provato a guardarlo con javap e questo dà la firma del metodo come dovrebbe essere.

Quando gli altri miei colleghi controllano il codice, lo compilano e lo distribuiscono, hanno lo stesso problema. Quando il server di build preleva il codice e lo distribuisce negli ambienti di sviluppo o test (HPUX), si verifica lo stesso errore. Anche una macchina di test automatizzata che esegue Ubuntu mostra lo stesso errore all'avvio del server.

Il resto dell'applicazione funziona bene, solo un servlet è fuori servizio. Qualsiasi idea su dove cercare sarebbe utile.


1
L'ho preso usando la versione sbagliata di ComparisonFailure. Impiegò PER SEMPRE a trovare ... che era doloroso
Tim Boland,

1
L'ho preso quando si utilizza la corsa istantanea in Android Studio (hotswapping durante la compilazione). Spegnerlo ha fatto il lavoro.
Serge,

Risposte:


188

java.lang.VerifyError può essere il risultato quando è stata compilata una libreria diversa da quella che si sta utilizzando in fase di esecuzione.

Ad esempio, questo è successo a me durante il tentativo di eseguire un programma compilato su Xerces 1, ma Xerces 2 è stato trovato sul percorso di classe. Le classi richieste (nello org.apache.*spazio dei nomi) sono state trovate in fase di esecuzione, quindi nonClassNotFoundException è stato il risultato. Sono state apportate modifiche alle classi e ai metodi, in modo che le firme dei metodi trovate in fase di esecuzione non corrispondessero a quelle presenti al momento della compilazione.

Normalmente, il compilatore segnalerà i problemi in cui le firme del metodo non corrispondono. La JVM verificherà di nuovo il bytecode quando viene caricata la classe e lancia VerifyErrorquando il bytecode sta tentando di fare qualcosa che non dovrebbe essere consentito, ad esempio chiamando un metodo che restituisce Stringe quindi memorizza quel valore restituito in un campo che contiene un List.


3
Una cosa da aggiungere, a volte è colpa dell'IDE o del dispositivo che il bytecode non è corretto. Prova a riavviare l'IDE per farlo riconoscere il problema di sincronizzazione. In caso contrario, eliminare e reinstallare l'app. Anche il riavvio del dispositivo può essere d'aiuto.
ima747,

2
Per scoprire quale classe è il colpevole aggiungere l'argomento VM -verbose:classe quindi cercare la classe appena prima che si carichi java.lang.VerifyError. Questo avrà il percorso verso il JAR. Usa javape confronta quello con la classe che stai compilando. L'ho trovato utile poiché la classe segnalata nell'errore non era la causa, in realtà era uno degli argomenti.
steinybot,

21

java.lang.VerifyError sono i peggiori.

Si otterrebbe questo errore se la dimensione del bytecode del metodo supera il limite di 64 kb; ma probabilmente l'avresti notato.

Sei sicuro al 100% che questa classe non sia presente nel percorso di classe altrove nella tua applicazione, forse in un altro vaso?

Inoltre, dal tuo stacktrace, la codifica dei caratteri del file sorgente ( utf-8?) È corretta?


Sono sicuro che non è presente altrove. È 43Kb, che è ancora una grande classe.
Jeroen Wyseur,

Grazie per quel post, nel mio caso, era una codifica diversa: i file XMl di JasperReports salvano una codifica e una versione java, devi impostarla di conseguenza sulle impostazioni del tuo progetto (tramite iReport). Questo è stato il problema qui, grazie per la tua idea con la codifica! :)
Tobias,

Questo era il mio problema per i test Android, il multidex lo ha risolto.
Prakash Nadar,

10

Come ha detto Kevin Panko, è principalmente a causa del cambio di biblioteca. Quindi in alcuni casi un "clean" del progetto (directory) seguito da una build fa il trucco.


9

Una cosa che potresti provare è usare -Xverify:allche verificherà il bytecode al caricamento e talvolta fornirà utili messaggi di errore se il bytecode non è valido.



8

VerifyError significa che il file di classe contiene bytecode sintatticamente corretto ma viola alcune restrizioni semantiche, ad esempio un target jump che attraversa i confini del metodo.

Fondamentalmente, un VerifyError può verificarsi solo in presenza di un bug del compilatore o quando il file di classe viene corrotto in qualche altro modo (ad esempio attraverso RAM difettosa o HD difettoso).

Prova a compilare con una versione JDK diversa e su una macchina diversa.


5

Nel mio caso il mio progetto Android dipende da un altro progetto Java compilato per Java 7. java.lang.VerifyErrorscomparso dopo aver modificato il livello di conformità del compilatore di quel progetto Java su 6.0

Successivamente ho scoperto che si tratta di un problema di Dalvik: https://groups.google.com/forum/?fromgroups#!topic/android-developers/sKsMTZ42pwE


1
Dalvik è solo una versione ramificata di Java6, quindi non sono disponibili funzionalità Java7!
Jeroen Wyseur,

4

Stavo riscontrando questo problema a causa di pack200 che stava manipolando un file di classe. Un po 'di ricerca ha rivelato questo bug java . Fondamentalmente, l'impostazione ha --effort=4causato la scomparsa del problema.

Usando java 1.5.0_17 (anche se è stato ritagliato in ogni singola variante di java 1.5 in cui l'ho provato).


3

Ho risolto un problema simile java.lang.VerifyError sostituendolo

        catch (MagickException e)

con

        catch (Exception e)

dove è MagickExceptionstato definito in un progetto di libreria (da cui il mio progetto ha una dipendenza).

Dopodiché ho ottenuto una java.lang.NoClassDefFoundErrorclasse circa dalla stessa libreria (risolto secondo https://stackoverflow.com/a/9898820/755804 ).


1
Questo ha funzionato per me ... Mi piacerebbe davvero capire quale fosse l'errore oltre a "sostituirmi con un'eccezione generale e lavorerò" però.
Alex Hart,

@AlexHart è per Android, ma probabilmente la stessa logica si applica per le imprese Java: stackoverflow.com/a/36814155/253468
TWiStErRob


2

Nel mio caso ho dovuto rimuovere questo blocco:

compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_7
    targetCompatibility JavaVersion.VERSION_1_7
}

Stava mostrando un errore vicino alla Fragment.showDialog()chiamata del metodo.


2

Esempio minimo che genera l'errore

Una semplice possibilità è quella di utilizzare Jasmin o modificare manualmente il bytecode con un editor di file binario.

Consente di creare un voidmetodo senza returnun'istruzione (generato dareturn; in Java), che secondo JVMS è illegale.

In Jasmin potremmo scrivere:

.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

Quindi facciamo javac Main.je javap -v Maindice che abbiamo compilato:

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

quindi davvero non ci sono istruzioni per il ritorno.

Ora se proviamo a correre java Mainotteniamo:

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)

Questo errore non può mai verificarsi normalmente in Java, poiché il compilatore Java aggiunge implicitamente returnai voidmetodi per noi. Questo è il motivo per cui non è necessario aggiungere un returnai nostri mainmetodi. Puoi verificarlo con javap.

JVM

VerifyError si verifica quando si tenta di eseguire determinati tipi di file di classe illegali come specificato nel capitolo 4.5 di JVMS 7

JVMS afferma che quando Java carica un file, deve eseguire una serie di controlli per verificare che il file di classe sia OK prima di eseguirlo.

Tali errori non possono essere generati su un singolo ciclo di compilazione ed esecuzione del codice Java, poiché JVMS 7 4.10 dice :

Anche se un compilatore per il linguaggio di programmazione Java deve produrre solo file di classe che soddisfano tutti i vincoli statici e strutturali [...]

Quindi, per vedere un esempio di errore minimo, avremo bisogno di generare il codice sorgente senza javac.


1

Questa pagina potrebbe darti alcuni suggerimenti: http://www.zanthan.com/itymbi/archives/000337.html

Potrebbe esserci un sottile bug nel corpo di quel metodo che javac non riesce a individuare. Difficile da diagnosticare a meno che non pubblichi l'intero metodo qui.

Potresti iniziare dichiarando quante più variabili possibili di final ... che avrebbe colto il bug menzionato sul sito zanthan, ed è spesso comunque una buona pratica.


1
Quel ragazzo ha colpito un bug del compilatore nel 2002, ma quel bug è stato corretto da allora.
Kevin Panko,

1

Bene nel mio caso, il mio progetto A aveva una dipendenza da un altro, diciamo X (A stava usando alcune delle classi definite in X). Quindi quando ho aggiunto X come progetto di riferimento nel percorso di compilazione di A, ho riscontrato questo errore. Tuttavia, quando ho rimosso X come progetto di riferimento e ho incluso il vaso di X come una delle librerie, il problema è stato risolto.


1

Controlla più versioni dello stesso file jar sul tuo percorso di classe.

Ad esempio, avevo opennlp-tools-1.3.0.jar e opennlp-tools-1.5.3.jar sul mio percorso di classe e ho riscontrato questo errore. La soluzione era eliminare opennlp-tools-1.3.0.jar.



1

Un altro motivo di questo errore può essere la combinazione di AspectJ <= 1.6.11 con JRE> 6.

Vedi Eclipse Bug 353467 e Kieker ticket 307 per i dettagli.

Ciò è particolarmente vero quando tutto funziona perfettamente su JRE 6 e passare a JRE7 rompe le cose.


1

Potrebbe accadere anche quando si hanno molte importazioni di moduli con Maven. Ci saranno due o più classi con esattamente lo stesso nome (stesso nome qualificato). Questo errore deriva dalla differenza di interpretazione tra tempo di compilazione e runtime.


1

Se stai eseguendo la migrazione a java7 o stai utilizzando java7, in genere questo errore può essere visualizzato. Ho affrontato gli errori sopra e ho faticato molto a scoprire la causa principale, suggerirei di provare ad aggiungere l' argomento JVM "-XX: -UseSplitVerifier" durante l'esecuzione dell'applicazione.


1

Dopo l'aggiornamento Gradlein Android Studio 3.6.1 si sono verificati arresti anomali sull'API 19 nella build di rilascio.

Si è verificato un errore dellaGlide libreria . La soluzione è riscrivere proguard-rules.txt .

Anche il downgrade Gradlefunziona ( classpath 'com.android.tools.build:gradle:3.5.3'), ma è una soluzione obsoleta, non usarla.


0

Sebbene il motivo citato da Kevin sia corretto, ma vorrei sicuramente controllare di seguito prima di passare a qualcos'altro:

  1. Controlla il cglibs nel mio percorso di classe.
  2. Controlla le hibernateversioni nel mio percorso di classe.

È probabile che avere una versione multipla o in conflitto di una qualsiasi delle opzioni precedenti possa causare problemi imprevisti come quello in questione.


0

java.lang.VerifyError significa che il codice byte compilato si riferisce a qualcosa che Android non riesce a trovare. Questo errore di verifica mi dà problemi solo con kitkat4.4 e versioni precedenti non nella versione precedente, anche se ho eseguito la stessa build in entrambi i dispositivi. quando ho usato jackson json parser della versione precedente mostra 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.+'

Quindi ho modificato Dependancy all'ultima versione da 2.2 a 2.7 senza la libreria principale , quindi funziona. il che significa che i Metodi e altri contenuti di core vengono migrati all'ultima versione di Databind2.7 . Questo risolve i miei problemi.

compile 'com.fasterxml.jackson.core:jackson-annotations:2.7.0-rc3'
compile 'com.fasterxml.jackson.core:jackson-databind:2.7.0-rc3'

Come fai a sapere quale JAR cercare?
Siddharth,

1
jackson-core: 2.2. + è diventato eredità. quindi dobbiamo usare databind: 2.7.0-rc3, annotazioni: 2.7.0-rc3 o versione più recente di questa. Questo 2 è abbastanza, evitare jackson-core: 2.2. +. A quel punto ho ricevuto un po 'di verifica. durante l'utilizzo della versione 2.7+ non mostra questo errore
anand krish

0

rimuovere qualsiasi file jar inutilizzabile e provare a eseguirlo. e il suo lavoro per me ho aggiunto un file jar jcommons e anche un altro file jar jcommons.1.0.14, quindi rimuovi jcommons e funziona per me


0

scrivere su file:

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

nelle dipendenze successivo: <module name="sun.jdk"/>


-1

Nel mio caso, stavo ottenendo un errore di verifica con la traccia dello stack sottostante

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)

L'ho risolto rimuovendo la voce classpath per commons-codec-1.3.jar, c'era una discrepanza nella versione di questo vaso con quella fornita con Jasper.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.