java.lang.VerifyError: очікування кадру стека на цільовій гілці JDK 1.7


88

Після оновлення до JDK 1.7 я потрапляю нижче винятку:

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)

Відповіді:


171

Java 7 запровадила більш жорстку перевірку і трохи змінила формат класу - щоб містити карту стеків, яка використовується для перевірки правильності коду. Виняток, який ви бачите, означає, що деякий метод не має дійсної карти стека.

Виною тому можуть бути версія Java або байт-код. Зазвичай це означає, що бібліотека, що використовується додатком, генерує невірний байт-код, який не проходить суворішої перевірки. Тож розробник може зробити не що інше, як повідомлення про помилку бібліотеці.

Як обхідне рішення ви можете додати -noverifyдо аргументів JVM, щоб вимкнути перевірку. У Java 7 також можна було використовувати -XX:-UseSplitVerifierменш суворий метод перевірки, але ця опція була вилучена в Java 8.


1
Але що означає -XX: -UseSplitVerifier ?? Я подивився пояснення oracle, там сказано: "Використовуйте перевірку нового типу з атрибутами StackMapTable". Я не зрозумів.
Джон

2
Тож якщо я бачу ці помилки: це помилка в JVM чи мій код?
бентолор

4
ця відповідь не діє довгостроково або, можливо, вже зараз, оскільки Oracle припиняє цю опцію. Мене вражає ця помилка (з іншим кодом) і я шукаю спосіб запобігти відновленню стек-карт
ZiglioUK

2
для модульного тесту вам потрібно передати аргументи в плагіні surefire. Це вирішило проблему як для компіляторів Java 7, так і для 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>
Антуан Вільс

2
я стикався з такою ж проблемою, але після додавання -noverify це справді спрацювало для мене. Дякую.
Правен Кумар Мекала

15

Якщо ви використовуєте java 1.8, видаліть XX:-UseSplitVerifierі використовуйте -noverifyу своїх властивостях JVM.


8

Я зіткнувся з цією проблемою і спробував використати прапор, -noverifyякий справді працює. Це завдяки новому верифікатору байт-кодів. Тож прапор справді повинен працювати. Я використовую JDK 1.7.

Примітка: Це не буде працювати, якщо ви використовуєте JDK 1.8


3
Для мене з використанням прапора виправлено виконання наших модульних тестів Android із використанням JRE 8 як середовища виконання.
ubuntudroid

2
-noverify також працював у мене на Java 8. Я використовую gradle для Android, і тому мені довелося поставити прапор -noverify там, де це вказано в
stackoverflow.com/a/37593189/2848676

де ви встановили -noverify? Я встановив його як MAVEN_OPTS, але він не працює для мене
розробник

@Sara Antunez, Додайте це у файл build.gradle модуля вашого додатка в закритті Android. android {.... testOptions {unitTests.all {jvmArgs '-noverify'}}}
GrokkingDroid

2

Єдина різниця між файлами, що спричинили проблему, - це 8-й байт файлу

CA FE BA BE 00 00 00 33 - Java 7

проти

CA FE BA BE 00 00 00 32 - Java 6

Налаштування -XX:-UseSplitVerifierвирішує проблему. Однак причиною цієї проблеми є https://bugs.eclipse.org/bugs/show_bug.cgi?id=339388


2

Передайте -noverifyаргумент JVM своєму тестовому завданню. Якщо ви використовуєте gradle, у build.gradleвас може бути щось на зразок:

test {
  jvmArgs "-noverify"
}

0

Ця ПОМИЛКА може статися, коли ви використовуєте Mockito для знущань над фінальними класами .

Подумайте про використання Mockito inline або Powermock.


-1

Вибачте за копання, але я зіткнувся з тією ж проблемою і знайшов більш просте рішення.

У параметрах компілятора Java потрібно зняти прапорець біля пункту «Зберегти невикористані (ніколи не читати) локальні змінні», тому немає необхідності змінювати цільову версію JVM.

Здається, це помилка у старих версіях Eclipe.


у мене це не працює. Ось суть моєї помилки: gist.github.com/ZiglioNZ/bd1d7d424727b3f26c64
ZiglioUK

3
OP не згадує Eclipse. Він може навіть не використовувати його.
Дон Бренсон,

-3

Якщо ви створюєте код самостійно, тоді цю проблему можна подолати, надавши "-target 1.5" компілятору java (або встановивши відповідну опцію в IDE або конфігурації збірки).


-11

це посилання корисне. java.lang.VerifyError: очікується кадр стекової карти

найпростіший спосіб - змінити JRE на 6.


7
зниження рівня, коли простий аргумент JVM може виправити? Я сумніваюся у вашому визначенні простого.
Visionary Software Solutions

1
Хоча це теоретично може дати відповідь на питання, переважно було б включити сюди основні частини відповіді та надати посилання для довідки.
Йоахім Зауер,

Це обхід. Як сказав Йоахім, це може спрацювати - але це не визначає проблему чи допомогу для команд чи баз коду, які повинні використовувати Java 7
Кроуі

У зв’язаному питанні є кілька відповідей. Пониження рейтингу - лише один із перерахованих варіантів.
Ogre Psalm33
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.