Ursachen für das Abrufen eines java.lang.VerifyError

191

Ich untersuche Folgendes 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)

Es tritt auf, wenn der jboss-Server gestartet wird, auf dem das Servlet bereitgestellt wird. Es wurde mit jdk-1.5.0_11 kompiliert und ich habe versucht, es mit jdk-1.5.0_15 ohne Erfolg neu zu kompilieren. Das heißt, die Kompilierung läuft einwandfrei, aber bei der Bereitstellung tritt der java.lang.VerifyError auf.

Als ich den Methodennamen änderte und den folgenden Fehler bekam:

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)

Sie können sehen, dass mehr von der Methodensignatur angezeigt wird.

Die tatsächliche Methodensignatur lautet

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

Ich habe bereits versucht, es mit zu betrachten, javapund das gibt die Methodensignatur so, wie sie sein sollte.

Wenn meine anderen Kollegen den Code auschecken, kompilieren und bereitstellen, haben sie das gleiche Problem. Wenn der Build-Server den Code aufnimmt und in Entwicklungs- oder Testumgebungen (HPUX) bereitstellt, tritt der gleiche Fehler auf. Auch eine automatisierte Testmaschine, auf der Ubuntu ausgeführt wird, zeigt denselben Fehler beim Serverstart an.

Der Rest der Anwendung läuft in Ordnung, nur das eine Servlet ist außer Betrieb. Irgendwelche Ideen, wo man suchen sollte, wären hilfreich.

Jeroen Wyseur
quelle
1
Ich habe es durch die Verwendung der falschen Version von ComparisonFailure erhalten. Es dauerte für immer zu finden ... das war schmerzhaft
Tim Boland
1
Ich habe es bekommen, wenn ich Instant Run in Android Studio verwende (Hotswapping beim Kompilieren). Das Ausschalten hat den Job gemacht.
Serge

Antworten:

188

java.lang.VerifyError kann das Ergebnis sein, wenn Sie für eine andere Bibliothek kompiliert haben, als Sie zur Laufzeit verwenden.

Dies ist mir beispielsweise passiert, als ich versucht habe, ein Programm auszuführen, das für Xerces 1 kompiliert wurde, aber Xerces 2 im Klassenpfad gefunden wurde. Die erforderlichen Klassen (in org.apache.*Namensraum) wurden zur Laufzeit gefunden, so ClassNotFoundExceptionwar nicht das Ergebnis. Die Klassen und Methoden wurden geändert, sodass die zur Laufzeit gefundenen Methodensignaturen nicht mit denen zur Kompilierungszeit übereinstimmten.

Normalerweise kennzeichnet der Compiler Probleme, bei denen Methodensignaturen nicht übereinstimmen. Die JVM überprüft den Bytecode erneut, wenn die Klasse geladen wird, und löst aus, VerifyErrorwenn der Bytecode versucht, etwas zu tun, das nicht zulässig sein sollte - z. B. das Aufrufen einer Methode, die zurückgibt, Stringund das Speichern dieses Rückgabewerts in einem Feld, das a enthält List.

Kevin Panko
quelle
3
Eine Sache hinzuzufügen, manchmal ist es die Schuld der IDE oder das Gerät, dass der Bytecode nicht richtig ist. Starten Sie die IDE neu, damit das Synchronisierungsproblem erkannt wird. Andernfalls löschen Sie die App und installieren Sie sie erneut. Ein Neustart des Geräts kann ebenfalls hilfreich sein.
ima747
2
Um herauszufinden, welche Klasse der Schuldige ist, fügen Sie das VM-Argument hinzu -verbose:classund suchen Sie kurz vor dem Laden nach der Klasse java.lang.VerifyError. Dies wird den Weg zum JAR haben. Verwenden Sie das javapund vergleichen Sie es mit der Klasse, für die Sie kompilieren. Ich fand dies nützlich, da die im Fehler gemeldete Klasse nicht die Ursache war, sondern tatsächlich eines der Argumente war.
Steinybot
21

java.lang.VerifyError sind die schlimmsten.

Sie würden diesen Fehler erhalten, wenn die Bytecode-Größe Ihrer Methode die 64-KB-Grenze überschreitet. aber das hättest du wahrscheinlich bemerkt.

Sind Sie zu 100% sicher, dass diese Klasse an keiner anderen Stelle in Ihrer Anwendung im Klassenpfad vorhanden ist, möglicherweise in einem anderen Glas?

utf-8Ist aus Ihrem Stacktrace auch die Zeichenkodierung der Quelldatei ( ?) Ist das korrekt?

p3t0r
quelle
Ich bin sicher, dass es nicht woanders vorhanden ist. Es ist 43 KB, das ist immer noch eine große Klasse.
Jeroen Wyseur
Vielen Dank für diesen Beitrag, in meinem Fall war es eine andere Codierung: JasperReports XMl-Dateien speichern eine Codierung und eine Java-Version. Sie müssen dies entsprechend Ihren Projekteinstellungen (über iReport) einstellen. Das war hier das Problem, danke für deine Idee mit der Codierung! :)
Tobias
Dies war mein Problem für Android-Tests, Multidexing es behoben.
Prakash Nadar
10

Wie Kevin Panko sagte, liegt es hauptsächlich an Bibliotheksänderungen. In einigen Fällen reicht eine "Bereinigung" des Projekts (Verzeichnisses) gefolgt von einem Build aus.

Fließen
quelle
9

Eine Sache, die Sie versuchen könnten, ist die Verwendung, -Xverify:alldie den Bytecode beim Laden überprüft und manchmal hilfreiche Fehlermeldungen ausgibt, wenn der Bytecode ungültig ist.

Alex Miller
quelle
8

Ich habe diesen Fehler unter Android behoben, indem ich das Projekt erstellt habe, für das ich eine Bibliothek importiert habe, wie hier beschrieben: http://developer.android.com/tools/projects/projects-eclipse.html#SettingUpLibraryProject

Zuvor habe ich nur auf das Projekt verwiesen (es nicht zu einer Bibliothek gemacht) und diesen seltsamen VerifyError erhalten.

Hoffe es hilft jemandem.

Tiago
quelle
2
Der Link ist nicht mehr verfügbar, bitte beheben Sie ihn. danke
Mahdi Rashidi
8

VerifyError bedeutet, dass die Klassendatei Bytecode enthält, der syntaktisch korrekt ist, jedoch eine semantische Einschränkung verletzt, z. B. ein Sprungziel, das Methodengrenzen überschreitet.

Grundsätzlich kann ein VerifyError nur auftreten, wenn ein Compilerfehler vorliegt oder wenn die Klassendatei auf andere Weise beschädigt wird (z. B. durch fehlerhaften RAM oder eine fehlerhafte Festplatte).

Versuchen Sie, mit einer anderen JDK-Version und auf einem anderen Computer zu kompilieren.

Michael Borgwardt
quelle
5

In meinem Fall hängt mein Android-Projekt von einem anderen Java-Projekt ab, das für Java 7 kompiliert wurde. Es ist java.lang.VerifyErrorverschwunden, nachdem ich die Compiler-Konformitätsstufe dieses Java-Projekts auf 6.0 geändert habe

Später fand ich heraus, dass dies ein Dalvik-Problem ist: https://groups.google.com/forum/?fromgroups#!topic/android-developers/sKsMTZ42pwE

Michal Vician
quelle
1
Dalvik ist nur eine verzweigte Version von Java6, daher sind keine Java7-Funktionen verfügbar!
Jeroen Wyseur
4

Ich habe dieses Problem bekommen, weil pack200 eine Klassendatei entstellt hat. Ein bisschen Suchen hat diesen Java-Fehler aufgedeckt . Grundsätzlich hat die Einstellung dazu geführt, --effort=4dass das Problem behoben wurde.

Verwenden von Java 1.5.0_17 (obwohl es in jeder einzelnen Variante von Java 1.5 aufgetaucht ist, in der ich es ausprobiert habe).

Mike Miller
quelle
3

Ich habe ein ähnliches Problem mit java.lang.VerifyError durch Ersetzen behoben

        catch (MagickException e)

mit

        catch (Exception e)

wo MagickExceptionwurde in einem Bibliotheksprojekt definiert (von dem mein Projekt abhängig ist).

Danach habe ich java.lang.NoClassDefFoundErrorungefähr eine Klasse aus derselben Bibliothek (behoben gemäß https://stackoverflow.com/a/9898820/755804 ).

18446744073709551615
quelle
1
Das hat bei mir funktioniert ... Ich würde wirklich gerne herausfinden, was der Fehler war, außer "Ersetze mich durch eine pauschale Ausnahme und ich werde arbeiten".
Alex Hart
@AlexHart ist es für Android, aber wahrscheinlich würde die gleiche Logik für Enterprise Java gelten: stackoverflow.com/a/36814155/253468
TWiStErRob
2

Dies kann unter Android passieren, wenn Sie versuchen, eine Bibliothek zu laden, die mit dem JDK von Oracle kompiliert wurde.

Hier ist das Problem für den Ning Async HTTP-Client.

Martin Konicek
quelle
Haben Sie schon eine Lösung dafür gefunden
? @MartinKonicek
2

In meinem Fall musste ich diesen Block entfernen:

compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_7
    targetCompatibility JavaVersion.VERSION_1_7
}

Es wurde ein Fehler in der Nähe des Fragment.showDialog()Methodenaufrufs angezeigt.

ViliusK
quelle
2

Minimales Beispiel, das den Fehler generiert

Eine einfache Möglichkeit besteht darin, Jasmin zu verwenden oder den Bytecode manuell mit einem Binärdatei-Editor zu bearbeiten.

Erstellen wir eine voidMethode ohne returnAnweisung (generiert durch die return;Anweisung in Java), die laut JVMS illegal ist.

In Jasmin konnten wir schreiben:

.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

Wir tun dann javac Main.jund javap -v Mainsagen, dass wir zusammengestellt haben:

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

Es gibt also wirklich keine Rückgabeanweisung.

Wenn wir jetzt versuchen zu rennen java Main, bekommen wir:

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)

Dieser Fehler kann normalerweise nie in Java passieren, da die Java - Compiler ein implizites fügen returnan voidMethoden für uns. Aus diesem Grund müssen wir returnunseren mainMethoden kein a hinzufügen . Sie können dies mit überprüfen javap.

JVMS

VerifyError tritt auf, wenn Sie versuchen, bestimmte Arten von unzulässigen Klassendateien auszuführen, wie in JVMS 7, Kapitel 4.5 angegeben

Das JVMS gibt an, dass Java beim Laden einer Datei eine Reihe von Überprüfungen ausführen muss, um festzustellen, ob die Klassendatei in Ordnung ist, bevor sie ausgeführt wird.

Solche Fehler können nicht in einem einzigen Kompilierungs- und Ausführungszyklus von Java-Code generiert werden, da in JVMS 7 4.10 Folgendes angegeben ist :

Obwohl ein Compiler für die Programmiersprache Java nur Klassendateien erstellen darf, die alle statischen und strukturellen [...]

Um ein Beispiel für einen minimalen Fehler zu sehen, müssen wir den Quellcode ohne generieren javac.

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

Diese Seite kann Ihnen einige Hinweise geben - http://www.zanthan.com/itymbi/archives/000337.html

Es kann einen subtilen Fehler im Körper dieser Methode geben, den Javac nicht erkennt. Schwer zu diagnostizieren, wenn Sie nicht die gesamte Methode hier veröffentlichen.

Sie könnten damit beginnen, so viele Variablen wie möglich als endgültig zu deklarieren ... das hätte den auf der Zanthan-Site erwähnten Fehler behoben und ist sowieso oft eine gute Praxis.

Lars Westergren
quelle
1
Dieser Typ hatte bereits 2002 einen Compiler-Fehler, der jedoch seitdem behoben wurde.
Kevin Panko
1

Nun, in meinem Fall hatte mein Projekt A eine Abhängigkeit von einem anderen, sagen wir X (A verwendete einige der in X definierten Klassen). Als ich X als Referenzprojekt in den Erstellungspfad von A einfügte, wurde dieser Fehler angezeigt. Als ich jedoch X als das referenzierte Projekt entfernte und X's jar als eine der Bibliotheken einbezog, war das Problem gelöst.

user2484130
quelle
1

Suchen Sie in Ihrem Klassenpfad nach mehreren Versionen derselben JAR-Datei.

Zum Beispiel hatte ich opennlp-tools-1.3.0.jar und opennlp-tools-1.5.3.jar in meinem Klassenpfad und bekam diesen Fehler. Die Lösung bestand darin, opennlp-tools-1.3.0.jar zu löschen.

Demongolem
quelle
1

CGLIB <2.2 mit JRE> 6 kann ähnliche Fehler auslösen, siehe "Soll ich auf CGLIB 3.0 aktualisieren?" und einige Kommentare bei Spring SPR-9669 .

Dies gilt insbesondere dann, wenn bei JRE 6 alles einwandfrei funktioniert und ein einfacher Wechsel zu JRE7 zu Problemen führt.

Alexander Wessel
quelle
1

Ein weiterer Grund für diesen Fehler kann die Kombination von AspectJ <= 1.6.11 mit JRE> 6 sein.

Siehe Eclipse Bug 353467 und Kieker Ticket 307 für Details.

Dies gilt insbesondere dann, wenn bei JRE 6 alles einwandfrei funktioniert und die Umstellung auf JRE7 Probleme verursacht.

Alexander Wessel
quelle
1

Dies kann auch passieren, wenn Sie viele Modulimporte mit maven haben. Es gibt zwei oder mehr Klassen mit genau demselben Namen (gleicher qualifizierter Name). Dieser Fehler resultiert aus unterschiedlichen Interpretationen zwischen Kompilierungszeit und Laufzeit.

Toumi
quelle
1

Wenn Sie auf Java7 migrieren oder Java7 verwenden, wird dieser Fehler im Allgemeinen angezeigt. Ich hatte die oben genannten Fehler und hatte große Probleme , die Hauptursache herauszufinden. Ich würde vorschlagen, das JVM-Argument "-XX: -UseSplitVerifier" hinzuzufügen, während Sie Ihre Anwendung ausführen .

Ulhas N.
quelle
1

Nach dem Update Gradlein Android Studio 3.6.1 kam es in Release 19 zu Abstürzen auf API 19.

Es ist ein GlideBibliotheksfehler aufgetreten . Die Lösung besteht darin, proguard-rules.txt neu zu schreiben .

Auch ein Downgrade Gradlefunktioniert ( classpath 'com.android.tools.build:gradle:3.5.3'), aber es ist eine veraltete Lösung, verwenden Sie es nicht.

CoolMind
quelle
0

Der von Kevin erwähnte Grund ist zwar richtig, aber ich würde es auf jeden Fall weiter unten überprüfen, bevor ich zu etwas anderem übergehe:

  1. Überprüfen Sie die cglibsin meinem Klassenpfad.
  2. Überprüfen Sie die hibernateVersionen in meinem Klassenpfad.

Die Chancen stehen gut, dass mehrere oder widersprüchliche Versionen der oben genannten Probleme zu unerwarteten Problemen wie dem fraglichen führen können.

Sandeep Jindal
quelle
0

java.lang.VerifyError bedeutet, dass Ihr kompilierter Bytecode auf etwas verweist, das Android nicht finden kann. Dieser verifyError gibt mir nur Probleme mit kitkat4.4 und einer kleineren Version, die nicht in der obigen Version enthalten ist , selbst wenn ich auf beiden Geräten denselben Build ausgeführt habe. Wenn ich den Jackson Json Parser einer älteren Version verwendet habe, wird java.lang.verifyerror angezeigt

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.+'

Dann habe ich die Dependancy der geänderten neueste Version 2,2 bis 2,7 ohne die Kernbibliothek , dann funktioniert es. Dies bedeutet, dass die Methoden und andere Inhalte des Kerns auf die neueste Version von Databind2.7 migriert werden . Dies behebt meine Probleme.

compile 'com.fasterxml.jackson.core:jackson-annotations:2.7.0-rc3'
compile 'com.fasterxml.jackson.core:jackson-databind:2.7.0-rc3'
anand krish
quelle
Woher wissen Sie, nach welchem ​​JAR Sie suchen müssen?
Siddharth
1
Jackson-Core: 2.2. + ist Vermächtnis geworden. Daher müssen wir die Datenbindung verwenden: 2.7.0-rc3, Anmerkungen: 2.7.0-rc3 oder die neueste Version. Diese 2 ist genug, vermeiden Sie Jackson-Core: 2.2. +. Zu diesem Zeitpunkt habe ich einen Verifizierungsfehler erhalten. Bei Verwendung der Version 2.7+ wird dieser Fehler
nicht angezeigt
0

Bitte entfernen Sie alle unbrauchbaren JAR-Dateien und versuchen Sie sie auszuführen. und seine Arbeit für mich Ich fügte eine Jcommons JAR-Datei und auch eine andere Jcommons.1.0.14 JAR-Datei hinzu, also entferne Jcommons und es funktioniert für mich

Jat Rahul
quelle
0

in Datei schreiben:

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

in Abhängigkeiten weiter: <module name="sun.jdk"/>

Eduardo Morales
quelle
-1

In meinem Fall wurde ein Überprüfungsfehler mit der folgenden Stapelverfolgung angezeigt

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)

Ich habe es behoben, indem ich den Klassenpfadeintrag für commons-codec-1.3.jar entfernt habe. Die Version dieses JARs stimmte nicht mit der Version überein, die mit Jasper geliefert wurde.

Aashirwad Sinha
quelle