java.lang.VerifyError: Erwarten eines Stackmap-Frames am Zweigziel JDK 1.7

88

Nach dem Upgrade auf JDK 1.7 erhalte ich die folgende Ausnahme:

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
quelle

Antworten:

171

Java 7 führte eine strengere Überprüfung ein und änderte das Klassenformat ein wenig, um eine Stapelzuordnung zu enthalten, mit der überprüft wird, ob der Code korrekt ist. Die angezeigte Ausnahme bedeutet, dass einige Methoden keine gültige Stapelzuordnung haben.

Die Java-Version oder die Bytecode-Instrumentierung könnten beide schuld sein. Normalerweise bedeutet dies, dass eine von der Anwendung verwendete Bibliothek einen ungültigen Bytecode generiert, der die strengere Überprüfung nicht besteht. Der Entwickler kann also nichts anderes tun, als es der Bibliothek als Fehler zu melden.

-noverifyUm dieses Problem zu umgehen, können Sie den JVM-Argumenten hinzufügen , um die Überprüfung zu deaktivieren. In Java 7 war es auch möglich, -XX:-UseSplitVerifierdie weniger strenge Überprüfungsmethode zu verwenden, aber diese Option wurde in Java 8 entfernt.

Mirko Adari
quelle
1
Aber was bedeutet -XX: -UseSplitVerifier? Ich habe mir die Erklärung von Orakel angesehen: "Verwenden Sie die neue Typprüfung mit StackMapTable-Attributen". Ich habe es nicht verstanden.
John
2
Wenn ich also folgende Fehler sehe: Ist dies ein Fehler in der JVM oder in meinem Code?
Bentolor
4
Diese Antwort ist auf lange Sicht nicht mehr gültig oder möglicherweise bereits länger, da Oracle diese Option ablehnt. Ich bin von diesem Fehler (mit anderem Code) betroffen und suche nach einer Möglichkeit, die Neuerstellung von Stackmaps voranzutreiben
ZiglioUK
2
Für den Unit-Test müssen Sie die Argumente im todsicheren Plugin übergeben. Dies behebt das Problem für Java 7- und 8-Compiler: <plugin> <groupId> org.apache.maven.plugins </ groupId> <artifactId> maven-surefire-plugin </ifactId> <version> 2.18.1 </ version > <Konfiguration> <argLine> -noverify -XX: -UseSplitVerifier </ argLine> </ configuration> </ plugin>
Antoine Wils
2
Ich hatte das gleiche Problem, aber nach dem Hinzufügen von -noverify hat es wirklich für mich funktioniert. Danke.
Praveen Kumar Mekala
15

Wenn Sie Java 1.8 verwenden, entfernen Sie es XX:-UseSplitVerifierund verwenden Sie es -noverifyin Ihren JVM-Eigenschaften.

Anand Kumar KK
quelle
8

Ich bin auf dieses Problem gestoßen und habe versucht, das Flag zu verwenden, -noverifydas wirklich funktioniert. Dies liegt an der neuen Bytecode-Überprüfung. Die Flagge sollte also wirklich funktionieren. Ich benutze JDK 1.7.

Hinweis: Dies würde nicht funktionieren, wenn Sie JDK 1.8 verwenden

Charan Raj
quelle
3
Für mich wurde das Flag behoben, das unsere Android Unit Tests mit JRE 8 als Laufzeit ausführt.
Ubuntudroid
2
-noverify funktionierte auch für mich unter Java 8. Ich verwende gradle für Android und musste daher das Flag -noverify an der Stelle setzen, die in stackoverflow.com/a/37593189/2848676
Michael Osofsky
Wo hast du -noverify gesetzt? Ich habe es als MAVEN_OPTS festgelegt, aber es funktioniert nicht für mich
dev
@ Sara Antunez, Fügen Sie dies in der build.gradle-Datei Ihrer Anwendungsmodule in Android Closure hinzu. android {.... testOptions {unitTests.all {jvmArgs '-noverify'}}}
GrokkingDroid
2

Der einzige Unterschied zwischen Dateien, die das Problem verursachen, ist das 8. Byte der Datei

CA FE BA BE 00 00 00 33 - Java 7

vs.

CA FE BA BE 00 00 00 32 - Java 6

Die Einstellung -XX:-UseSplitVerifierbehebt das Problem. Die Ursache für dieses Problem ist jedoch https://bugs.eclipse.org/bugs/show_bug.cgi?id=339388

Ein Kunin
quelle
2

Übergeben Sie das -noverifyJVM-Argument an Ihre Testaufgabe. Wenn Sie Gradle verwenden, können Sie in der folgenden Datei Folgendes build.gradlehaben:

test {
  jvmArgs "-noverify"
}
Löwe
quelle
0

Dieser FEHLER kann auftreten, wenn Sie Mockito verwenden, um Abschlussklassen zu verspotten .

Verwenden Sie stattdessen Mockito Inline oder Powermock.

nhoxbypass
quelle
-1

Entschuldigung für das Graben, aber ich bin auf das gleiche Problem gestoßen und habe die einfachere Lösung gefunden.

In den Java-Compileroptionen müssen Sie das Kontrollkästchen " Nicht verwendete (nie gelesene) lokale Variablen beibehalten " deaktivieren. damit die JVM-Zielversion nicht zurückgesetzt werden muss.

Es scheint ein Fehler in einer älteren Eclipe-Version zu sein.

scoro
quelle
es funktioniert nicht bei mir. Hier ist ein Kern meines Fehlers: gist.github.com/ZiglioNZ/bd1d7d424727b3f26c64
ZiglioUK
3
Das OP erwähnt Eclipse nicht. Er kann es nicht einmal benutzen.
Don Branson
-3

Wenn Sie den Code selbst erstellen, kann dieses Problem behoben werden, indem Sie dem Java-Compiler "-target 1.5" geben (oder indem Sie die entsprechende Option in Ihrer IDE oder Ihrer Build-Konfiguration festlegen).

jrajp2184
quelle
-11

Dieser Link ist hilfreich. java.lang.VerifyError: Erwartet einen Stackmap-Frame

Am einfachsten ist es, JRE auf 6 zu ändern.

yuxiaomin
quelle
7
Downgrade, wenn ein einfaches JVM-Argument behoben werden kann? Ich bezweifle deine Definition von einfach.
Visionary Software Solutions
1
Während dies theoretisch die Frage beantworten kann, wäre es vorzuziehen , die wesentlichen Teile der Antwort hier aufzunehmen und den Link als Referenz bereitzustellen.
Joachim Sauer
Dies ist eine Problemumgehung. Wie Joachim sagte, kann es funktionieren - aber es definiert nicht das Problem oder die Hilfe für Teams oder Codebasen, die Java 7 verwenden müssen
Crowie
Die verknüpfte Frage enthält mehrere Antworten. Ein Downgrade ist nur eine aufgelistete Option.
Oger Psalm33