java.lang.VerifyError: Mengharapkan bingkai stackmap pada target cabang JDK 1.7

88

Setelah meningkatkan ke JDK 1.7, saya mendapatkan pengecualian di bawah ini:

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
sumber

Jawaban:

171

Java 7 memperkenalkan verifikasi yang lebih ketat dan sedikit mengubah format kelas — untuk memuat peta tumpukan yang digunakan untuk memverifikasi bahwa kode sudah benar. Pengecualian yang Anda lihat berarti bahwa beberapa metode tidak memiliki peta tumpukan yang valid.

Versi Java atau instrumentasi bytecode bisa jadi penyebabnya. Biasanya ini berarti bahwa pustaka yang digunakan oleh aplikasi menghasilkan bytecode tidak valid yang tidak lolos verifikasi yang lebih ketat. Jadi tidak ada hal lain selain melaporkannya sebagai bug ke perpustakaan yang dapat dilakukan oleh pengembang.

Sebagai solusinya, Anda dapat menambahkan -noverifyargumen JVM untuk menonaktifkan verifikasi. Di Java 7 juga memungkinkan untuk menggunakan -XX:-UseSplitVerifiermetode verifikasi yang kurang ketat, tetapi opsi itu telah dihapus di Java 8.

Mirko Adari
sumber
1
Tapi apa artinya -XX: -UseSplitVerifier ?? Saya melihat penjelasan oracle, Ia mengatakan "Gunakan pemeriksa tipe baru dengan atribut StackMapTable". Saya tidak mengerti.
Yohanes
2
Jadi jika saya melihat kesalahan ini: Apakah ini bug dalam JVM atau kode saya?
bentolor
4
jawaban ini tidak valid dalam jangka panjang, atau mungkin sudah lebih lama lagi, karena Oracle menghentikan opsi ini. Saya terkena bug ini (dengan kode lain) dan saya sedang mencari cara untuk membangun kembali stackmap
ZiglioUK
2
untuk pengujian unit Anda harus meneruskan argumen di plugin yang pasti. Ini memperbaiki masalah untuk compiler java 7 dan 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
saya menghadapi masalah yang sama tetapi setelah menambahkan -noverify itu benar-benar berhasil untuk saya.
Praveen Kumar Mekala
15

Jika Anda menggunakan java 1.8, hapus XX:-UseSplitVerifierdan gunakan -noverifydi properti JVM Anda.

Anand Kumar KK
sumber
8

Saya mengalami masalah ini dan mencoba menggunakan bendera -noverifyyang benar-benar berfungsi. Ini karena pemverifikasi bytecode baru. Jadi benderanya harus benar-benar berfungsi. Saya menggunakan JDK 1.7.

Catatan: Ini tidak akan berhasil jika Anda menggunakan JDK 1.8

Charan Raj
sumber
3
Bagi saya yang menggunakan flag tetap menjalankan Tes Unit Android kami menggunakan JRE 8 sebagai runtime.
ubuntudroid
2
-noverify juga berfungsi untuk saya di Java 8. Saya menggunakan gradle untuk Android sehingga saya harus meletakkan flag -noverify yang ditentukan di stackoverflow.com/a/37593189/2848676
Michael Osofsky
di mana Anda mengatur -noverify? Saya menetapkannya sebagai MAVEN_OPTS tetapi tidak berfungsi untuk saya
dev
@ Sara Antunez, Dalam file build.gradle modul aplikasi Anda di penutupan android, tambahkan ini. android {.... testOptions {unitTests.all {jvmArgs '-noverify'}}}
GrokkingDroid
2

Satu-satunya perbedaan antara file yang menyebabkan masalah adalah file byte ke-8

CA FE BA BE 00 00 00 33 - Jawa 7

vs.

CA FE BA BE 00 00 00 32 - Jawa 6

Pengaturan -XX:-UseSplitVerifiermenyelesaikan masalah. Namun, penyebab masalah ini adalah https://bugs.eclipse.org/bugs/show_bug.cgi?id=339388

A Kunin
sumber
2

Teruskan -noverifyargumen JVM ke tugas pengujian Anda. Jika Anda menggunakan gradle, build.gradleAnda dapat memiliki sesuatu seperti:

test {
  jvmArgs "-noverify"
}
Leo
sumber
0

KESALAHAN ini dapat terjadi saat Anda menggunakan Mockito untuk membuat tiruan kelas akhir .

Pertimbangkan untuk menggunakan Mockito inline atau Powermock sebagai gantinya.

nhoxbypass.dll
sumber
-2

Maaf untuk menggali, tetapi saya menemui masalah yang sama dan menemukan solusi yang lebih sederhana.

Dalam opsi kompilator Java Anda perlu menghapus centang "Pertahankan variabel lokal yang tidak digunakan (tidak pernah dibaca)" sehingga tidak perlu mengubah kembali versi JVM target.

Tampaknya ini adalah bug di versi Eclipe yang lebih lama.

scoro
sumber
itu tidak berhasil untuk saya. Inilah inti dari kesalahan saya: gist.github.com/ZiglioNZ/bd1d7d424727b3f26c64
ZiglioUK
3
OP tidak menyebut Eclipse. Dia bahkan mungkin tidak menggunakannya.
Don Branson
-4

Jika Anda membuat kode sendiri, masalah ini dapat diatasi dengan memberikan "-target 1.5" ke compiler java (atau dengan menyetel opsi yang sesuai di IDE atau konfigurasi build Anda).

jrajp2184.dll
sumber
-11

tautan ini bermanfaat. java.lang.VerifyError: Mengharapkan bingkai stackmap

cara termudah adalah mengubah JRE menjadi 6.

yuxiaomin
sumber
7
menurunkan versi ketika arg JVM sederhana dapat diperbaiki? Saya meragukan definisi Anda tentang sederhana.
Solusi Perangkat Lunak Visioner
1
Meskipun ini secara teoritis dapat menjawab pertanyaan, akan lebih baik jika menyertakan bagian penting dari jawaban di sini, dan menyediakan tautan untuk referensi.
Joachim Sauer
Ini adalah penyelesaian. Seperti yang dikatakan Joachim, ini mungkin berhasil - tetapi tidak menentukan masalah atau bantuan untuk tim atau basis kode yang harus menggunakan Java 7
Crowie
Ada beberapa jawaban dalam pertanyaan terkait. Menurunkan hanya satu opsi yang terdaftar.
Ogre Mazmur33