java.lang.VerifyError: Attente d'un cadre stackmap au niveau de la cible de branche JDK 1.7

88

Après la mise à niveau vers JDK 1.7, je reçois l'exception ci-dessous:

java.lang.VerifyError: Expecting a stackmap frame at branch target 71 in method com.abc.domain.myPackage.MyClass$JaxbAccessorM_getDescription_setDescription_java_lang_String.get(Ljava/lang/Object;)Ljava/lang/Object; at offset 20
    at java.lang.Class.getDeclaredConstructors0(Native Method)
    at java.lang.Class.privateGetDeclaredConstructors(Class.java:2413)
    at java.lang.Class.getConstructor0(Class.java:2723)
    at java.lang.Class.newInstance0(Class.java:345)
    at java.lang.Class.newInstance(Class.java:327)
    at com.sun.xml.internal.bind.v2.runtime.reflect.opt.OptimizedAccessorFactory.instanciate(OptimizedAccessorFactory.java:184)
    at com.sun.xml.internal.bind.v2.runtime.reflect.opt.OptimizedAccessorFactory.get(OptimizedAccessorFactory.java:129)
    at com.sun.xml.internal.bind.v2.runtime.reflect.Accessor$GetterSetterReflection.optimize(Accessor.java:384)
    at com.sun.xml.internal.bind.v2.runtime.property.SingleElementLeafProperty.<init>(SingleElementLeafProperty.java:72)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
    at com.sun.xml.internal.bind.v2.runtime.property.PropertyFactory.create(PropertyFactory.java:113)
    at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.<init>(ClassBeanInfoImpl.java:166)
    at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:494)
    at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:311)
    at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:126)
    at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1148)
    at com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:130)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:248)
    at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:235)
    at javax.xml.bind.ContextFinder.find(ContextFinder.java:445)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:637)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:584)
    at com.abc.domain.myPackage.MyClass.marshalFacetsTest(MyClass.java:73)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:80)
    at org.testng.internal.Invoker.invokeMethod(Invoker.java:714)
    at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901)
    at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231)
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:128)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
    at org.testng.TestRunner.privateRun(TestRunner.java:767)
    at org.testng.TestRunner.run(TestRunner.java:617)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:291)
    at org.testng.SuiteRunner.run(SuiteRunner.java:240)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1203)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1128)
    at org.testng.TestNG.run(TestNG.java:1036)
    at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:111)
    at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:204)
    at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:175)
John
la source

Réponses:

171

Java 7 a introduit une vérification plus stricte et a légèrement modifié le format de la classe - pour contenir une carte de pile utilisée pour vérifier que le code est correct. L'exception que vous voyez signifie que certaines méthodes n'ont pas de carte de pile valide.

La version Java ou l'instrumentation bytecode pourraient être toutes deux à blâmer. Cela signifie généralement qu'une bibliothèque utilisée par l'application génère un bytecode non valide qui ne passe pas la vérification plus stricte. Donc, rien d'autre que de le signaler comme un bogue à la bibliothèque ne peut être fait par le développeur.

Pour contourner le problème, vous pouvez ajouter -noverifydes arguments JVM afin de désactiver la vérification. Dans Java 7, il était également possible d'utiliser -XX:-UseSplitVerifierla méthode de vérification la moins stricte, mais cette option a été supprimée dans Java 8.

Mirko Adari
la source
1
Mais que signifie -XX: -UseSplitVerifier ?? J'ai regardé l'explication d'Oracle, elle dit: "Utilisez le nouveau vérificateur de type avec les attributs StackMapTable". Je n'ai pas compris.
John
2
Donc, si je vois ces erreurs: s'agit-il d'un bogue dans la JVM ou dans mon code?
bentolor
4
cette réponse n'est pas valable à long terme, ou peut-être plus déjà, car Oracle abandonne cette option. Je suis affligé par ce bogue (avec un autre code) et je cherche un moyen de reconstruire avant de reconstruire les stackmaps
ZiglioUK
2
pour le test unitaire, vous devez passer les arguments dans le plugin surefire. Cela a résolu le problème pour les compilateurs java 7 et 8: <plugin> <groupId> org.apache.maven.plugins </groupId> <artifactId> maven-surefire-plugin </artifactId> <version> 2.18.1 </ version > <configuration> <argLine> -noverify -XX: -UseSplitVerifier </argLine> </configuration> </plugin>
Antoine Wils
2
J'étais confronté au même problème mais après avoir ajouté -noverify, cela a vraiment fonctionné pour moi.Merci.
Praveen Kumar Mekala
15

Si vous utilisez java 1.8, supprimez XX:-UseSplitVerifieret utilisez -noverifydans vos propriétés JVM.

Anand Kumar KK
la source
8

J'ai rencontré ce problème et j'ai essayé d'utiliser le drapeau -noverifyqui fonctionne vraiment. C'est à cause du nouveau vérificateur de bytecode. Le drapeau devrait donc vraiment fonctionner. J'utilise JDK 1.7.

Remarque: cela ne fonctionnera pas si vous utilisez JDK 1.8

Charan Raj
la source
3
Pour moi, l'utilisation de l'indicateur a été corrigée en exécutant nos tests unitaires Android en utilisant JRE 8 comme runtime.
ubuntudroid
2
-noverify a également fonctionné pour moi sur Java 8. J'utilise gradle pour Android et j'ai donc dû mettre l'indicateur -noverify à l'endroit spécifié dans stackoverflow.com/a/37593189/2848676
Michael Osofsky
où avez-vous mis -noverify? Je l'ai défini comme MAVEN_OPTS mais cela ne fonctionne pas pour moi
dev
@Sara Antunez, Dans le fichier build.gradle de vos modules d'application dans la fermeture Android, ajoutez ceci. android {.... testOptions {unitTests.all {jvmArgs '-noverify'}}}
GrokkingDroid
2

La seule différence entre les fichiers à l'origine du problème est le 8e octet du fichier

CA FE BA BE 00 00 00 33 - Java 7

contre.

CA FE BA BE 00 00 00 32 - Java 6

Le réglage -XX:-UseSplitVerifierrésout le problème. Cependant, la cause de ce problème est https://bugs.eclipse.org/bugs/show_bug.cgi?id=339388

Un Kunin
la source
2

Passer -noverifyargument JVM à votre tâche de test. Si vous utilisez gradle, build.gradlevous pouvez avoir quelque chose comme:

test {
  jvmArgs "-noverify"
}
Leo
la source
0

Cette ERREUR peut se produire lorsque vous utilisez Mockito pour simuler les classes finales .

Pensez à utiliser Mockito inline ou Powermock à la place.

nhoxbypass
la source
-1

Désolé d'avoir creusé, mais j'ai rencontré le même problème et j'ai trouvé la solution la plus simple.

Dans les options du compilateur Java, vous devez décocher "Conserver les variables locales inutilisées (jamais lues)" afin qu'il n'y ait pas besoin de modifier la version JVM cible.

Cela semble être un bogue dans les anciennes versions d'Eclipe.

Scoro
la source
ça ne marche pas pour moi. Voici l'essentiel de mon erreur: gist.github.com/ZiglioNZ/bd1d7d424727b3f26c64
ZiglioUK
3
L'OP ne mentionne pas Eclipse. Il ne l'utilise peut-être même pas.
Don Branson
-3

Si vous construisez le code vous-même, alors ce problème peut être résolu en donnant "-target 1.5" au compilateur java (ou en définissant l'option correspondante dans votre IDE ou votre configuration de construction).

jrajp2184
la source
-11

ce lien est utile. java.lang.VerifyError: Attente d'un cadre de stackmap

le moyen le plus simple est de changer JRE en 6.

yuxiaomin
la source
7
rétrograder quand un simple argument JVM peut réparer? Je doute de votre définition de simple.
Visionary Software Solutions
1
Bien que cela puisse théoriquement répondre à la question, il serait préférable d'inclure ici les parties essentielles de la réponse et de fournir le lien pour référence.
Joachim Sauer
C'est un travail autour. Comme l'a dit Joachim, cela peut fonctionner - mais cela ne définit pas le problème ou l'aide pour les équipes ou les bases de code qui doivent utiliser Java 7
Crowie
Il y a plusieurs réponses dans la question liée. Le déclassement n'est qu'une option répertoriée.
Ogre Psalm33