web-dev-qa-db-fra.com

Causes d'obtenir un Java.lang.VerifyError

J'enquête sur le Java.lang.VerifyError suivant

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)

Cela se produit lorsque le serveur jboss dans lequel le servlet est déployé est démarré . Il est compilé avec jdk-1.5.0_11 et j'ai essayé de le recompiler avec jdk-1.5.0_15 sans succès. C'est-à-dire que la compilation fonctionne correctement, mais une fois déployé, Java.lang.VerifyError se produit.

Lorsque j'ai changé le nom de la méthode et obtenu l'erreur suivante:

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)

Vous pouvez voir que plus de signature de la méthode est affichée.

La signature de la méthode actuelle est

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

J'ai déjà essayé de le regarder avec javap et cela donne la signature de la méthode comme il se doit.

Lorsque mes autres collègues extraient le code, le compilent et le déploient, ils ont le même problème. Lorsque le serveur de génération récupère le code et le déploie dans des environnements de développement ou de test (HPUX), la même erreur se produit. De plus, une machine de test automatique exécutant Ubuntu affiche la même erreur lors du démarrage du serveur.

Le reste de l'application fonctionne correctement, une seule servlet est en panne . Toute idée de recherche serait utile.

181
JeroenWyseur

Java.lang.VerifyError peut être le résultat lorsque vous avez compilé avec une bibliothèque différente de celle que vous utilisez au moment de l'exécution.

Par exemple, cela m'est arrivé lorsque j'essayais d'exécuter un programme compilé avec Xerces 1, mais Xerces 2 était trouvé sur le chemin de classe. Les classes requises (dans l'espace de noms org.Apache.*) ont été trouvées au moment de l'exécution. ClassNotFoundException était doncnotle résultat. Des modifications ont été apportées aux classes et aux méthodes, de sorte que les signatures de méthode trouvées à l'exécution ne correspondent pas à celles qui existaient à la compilation.

Normalement, le compilateur signalera les problèmes où les signatures de méthode ne correspondent pas. La JVM vérifiera à nouveau le bytecode lors du chargement de la classe et lancera VerifyError lorsque le bytecode tentera de faire quelque chose qui ne devrait pas être autorisé - par exemple. appeler une méthode qui retourne String puis stocke cette valeur dans un champ qui contient List.

180
Kevin Panko

Java.lang.VerifyError sont les pires.

Vous obtiendrez cette erreur si la taille du bytecode de votre méthode dépasse la limite de 64 Ko; mais vous auriez probablement remarqué cela.

Êtes-vous sûr à 100% que cette classe n'est pas présente dans le classpath ailleurs dans votre application, peut-être dans un autre fichier jar?

De plus, à partir de votre pile, le codage de caractères du fichier source (utf-8?) Est-il correct?

20
p3t0r

Comme Kevin Panko l’a dit, c’est principalement à cause du changement de bibliothèque… .. Ainsi, dans certains cas, un «nettoyage» du projet (répertoire) suivi d’une construction fait l’essentiel.

10
Flow

J'ai corrigé cette erreur sur Android en faisant en sorte que le projet importait une bibliothèque, comme décrit ici http://developer.Android.com/tools/projects/projects-Eclipse.html#SettingUpLibraryProject

Auparavant, je ne faisais que référencer le projet (ne pas en faire une bibliothèque) et je recevais cet étrange VerifyError.

J'espère que ça aide quelqu'un.

8
Tiago

VerifyError signifie que le fichier de classe contient un bytecode qui est syntaxiquement correct mais qui enfreint certaines restrictions sémantiques, par exemple. une cible de saut qui dépasse les limites de la méthode.

Fondamentalement, une erreur VerifyError ne peut se produire que s'il existe un bogue du compilateur ou lorsque le fichier de classe est corrompu d'une autre manière (par exemple, via RAM défectueux ou un disque dur défaillant).

Essayez de compiler avec une version différente du JDK et sur un autre ordinateur.

7
Michael Borgwardt

Une chose que vous pourriez essayer est d'utiliser -Xverify:all qui vérifiera le code à la charge et donnera parfois des messages d'erreur utiles si le code est invalide. 

7
Alex Miller

Dans mon cas, mon projet Android dépend d'un autre projet Java compilé pour Java 7. Java.lang.VerifyError a disparu après avoir changé le niveau de conformité du compilateur de ce projet Java en 6.0

Plus tard, j'ai découvert qu'il s'agissait d'un problème avec Dalvik: https://groups.google.com/forum/?fromgroups#!topic/Android-developers/sKsMTZ42pwE

5
Michal Vician

Je commençais à avoir ce problème à cause de la manipulation par Pack200 d'un fichier de classe. Un peu de recherche a tourné ce Java bug up. Fondamentalement, régler --effort=4 a permis de résoudre le problème.

Utilisation de Java 1.5.0_17 (bien que cela se soit produit dans toutes les variantes de Java 1.5, je l’ai essayé).

4
Mike Miller

Cela peut arriver sous Android lorsque vous essayez de charger une bibliothèque compilée avec le JDK d'Oracle.

Voici le problème pour le client HTTP Ning Async.

2
Martin Konicek

J'ai résolu un problème similaire à Java.lang.VerifyError en remplaçant

        catch (MagickException e)

avec

        catch (Exception e)

MagickException a été défini dans un projet de bibliothèque (sur lequel mon projet a une dépendance).

Après cela, j'ai un Java.lang.NoClassDefFoundError concernant une classe de la même bibliothèque (corrigé selon https://stackoverflow.com/a/9898820/755804 ).

2

Dans mon cas je devais enlever ce bloc:

compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_7
    targetCompatibility JavaVersion.VERSION_1_7
}

Il montrait une erreur près de l'appel de la méthode Fragment.showDialog().

2
ViliusK

Exemple minimal générant l'erreur

Une possibilité simple consiste à utiliser Jasmin , ou à modifier manuellement le bytecode avec un éditeur de fichier binaire.

Permet de créer la méthode void sans instruction return (générée par l'instruction return; en Java), que le système JVMS dit illégale.

En Jasmin, nous pourrions écrire:

.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

Nous faisons ensuite javac Main.j et javap -v Main dit que nous avons compilé:

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

donc vraiment il n'y a pas d'instruction de retour.

Maintenant, si nous essayons d'exécuter Java Main, nous obtenons:

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)

Cette erreur ne peut jamais se produire normalement en Java, car le compilateur Java ajoute une méthode implicite return à void pour nous. C'est pourquoi nous n'avons pas besoin d'ajouter une return à nos méthodes main. Vous pouvez vérifier ceci avec javap.

JVMS

VerifyError se produit lorsque vous essayez d'exécuter certains types de fichiers de classe illégaux comme spécifié par JVMS 7 chapitre 4.5

Le JVMS indique que lorsque Java charge un fichier, il doit exécuter une série de vérifications pour vérifier que le fichier de classe est correct avant de l'exécuter.

De telles erreurs ne peuvent pas être générées sur un seul cycle de compilation et d’exécution de code Java, car JVMS 7 4.10 indique :

Même si un compilateur pour le langage de programmation Java ne doit produire que des fichiers de classe qui satisfont à toutes les contraintes statiques et structurelles [... ]

Donc, pour voir un exemple d'échec minimal, nous aurons besoin de générer le code source sans javac.

Dans mon cas, mon projet A dépendait d’un autre, disons X (A utilisait certaines des classes définies dans X). Ainsi, lorsque j'ai ajouté X en tant que projet de référence dans le chemin de génération de A, j'ai eu cette erreur. Cependant, lorsque j'ai supprimé X en tant que projet référencé et inclus le fichier jar de X en tant que bibliothèque, le problème a été résolu.

1
user2484130

Cette page peut vous donner quelques indices. - http://www.zanthan.com/itymbi/archives/000337.html

Il peut y avoir un bogue subtil dans le corps de cette méthode que javac ne parvient pas à détecter. Difficile à diagnostiquer sauf si vous postez toute la méthode ici. 

Vous pouvez commencer par déclarer autant de variables que possible en tant que final ... ce qui aurait attrapé le bogue mentionné sur le site zanthan et constitue souvent une bonne pratique de toute façon.

1
Lars Westergren

Si vous migrez vers Java7 ou utilisez Java7, cette erreur est généralement visible. J'ai fait face aux erreurs ci-dessus et ai beaucoup lutté pour trouver la cause du problème. Je vous conseillerais donc d'ajouter l'ajout de l'argument "-XX: -UseSplitVerifier" à la JVM lors de l'exécution de votre application.

1
Ulhas N

Recherchez plusieurs versions du même fichier JAR sur votre chemin de classe. 

Par exemple, j'avais opennlp-tools-1.3.0.jar et opennlp-tools-1.5.3.jar sur mon chemin de classe et j'ai eu cette erreur. La solution consistait à supprimer opennlp-tools-1.3.0.jar.

1
demongolem

Une autre raison de cette erreur peut être la combinaison de AspectJ <= 1.6.11 avec JRE> 6.

Voir Bug Eclipse 353467 et Ticket Kieker 307 pour plus de détails.

Cela est particulièrement vrai lorsque tout fonctionne bien sur JRE 6 et que le passage à JRE7 casse les choses. 

1
Alexander Wessel

Cela peut également arriver lorsque vous avez beaucoup d'importations de modules avec maven . Deux ou plusieurs classes auront exactement le même nom (même nom qualifié) . Cette erreur résulte d'une différence d'interprétation entre les temps de compilation. et d'exécution.

1
Toumi

CGLIB <2.2 avec JRE> 6 pourrait provoquer des erreurs similaires, voir "Devrais-je effectuer une mise à niveau vers CGLIB 3.0?" et quelques commentaires à Spring SPR-9669 .

Cela est particulièrement vrai lorsque tout fonctionne correctement sur JRE 6 et que le simple passage à JRE7 casse les choses.

1
Alexander Wessel

Java.lang.VerifyError signifie que votre bytecode compilé fait référence à quelque chose qu'Android ne peut pas trouver. This verifyError Ne me lance qu'avec KitKat4.4 et une version inférieure ne figurant pas dans la version ci-dessus même si j'ai exécuté la même version dans les deux périphériques. quand j’ai utilisé l’analyseur jackson json de l’ancienne version, il montre 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.+'

Ensuite, j'ai changé la dépendance à la dernière version 2.2 en 2.7 sans la bibliothèque core , puis cela fonctionne. ce qui signifie que les méthodes et autres contenus de core sont migrés vers la dernière version de Databind2.7 . Cela corrige mes problèmes.

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

veuillez supprimer tous les fichiers jar inutilisables et essayer de les exécuter. et son travail pour moi j'ai ajouté un fichier jcommons jar et aussi un autre fichier jcommons.1.0.14 jar afin de supprimer jcommons et son travail pour moi

0
Jat Rahul

Bien que la raison mentionnée par Kevin soit correcte, je vérifierais certainement ci-dessous avant de passer à autre chose:

  1. Vérifiez la cglibs dans mon classpath. 
  2. Vérifiez les versions hibernate dans mon classpath.

Il est fort probable que la présence de versions multiples ou conflictuelles de l’un des éléments ci-dessus puisse entraîner des problèmes inattendus, comme celui en question.

0
Sandeep Jindal