Penyebab mendapatkan java.lang.VerifyError


191

Saya sedang menyelidiki yang berikut ini java.lang.VerifyError

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)

Ini terjadi ketika server jboss di mana servlet digunakan dimulai. Itu dikompilasi dengan jdk-1.5.0_11 dan saya mencoba untuk mengkompilasi ulang dengan jdk-1.5.0_15 tanpa berhasil. Itu adalah kompilasi berjalan dengan baik tetapi ketika digunakan, java.lang.VerifyError terjadi.

Ketika saya mengubah nama metode dan mendapat kesalahan berikut:

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)

Anda dapat melihat bahwa lebih banyak metode tanda tangan ditampilkan.

Tanda tangan metode aktual adalah

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

Saya sudah mencoba melihatnya dengan javapdan itu memberikan metode tanda tangan sebagaimana mestinya.

Ketika kolega saya yang lain memeriksa kode, mengkompilasinya dan menyebarkannya, mereka memiliki masalah yang sama. Ketika server build mengambil kode dan menyebarkannya pada pengembangan atau lingkungan pengujian (HPUX), kesalahan yang sama terjadi. Juga mesin pengujian otomatis yang menjalankan Ubuntu menunjukkan kesalahan yang sama selama startup server.

Sisa aplikasi berjalan dengan baik, hanya satu servlet yang rusak. Setiap ide ke mana harus mencari akan sangat membantu.


1
Saya mendapatkannya dari menggunakan versi ComparisonFailure yang salah. Butuh SELAMANYA untuk menemukan ... itu menyakitkan
Tim Boland

1
Saya mendapatkannya saat menggunakan instant run di Android studio (hotswapping on compile). Mematikannya berhasil.
Serge

Jawaban:


188

java.lang.VerifyError bisa menjadi hasil ketika Anda telah dikompilasi terhadap pustaka yang berbeda dari yang Anda gunakan saat runtime.

Sebagai contoh, ini terjadi pada saya ketika mencoba menjalankan program yang dikompilasi melawan Xerces 1, tetapi Xerces 2 ditemukan di classpath. Kelas yang diperlukan (di org.apache.*namespace) ditemukan pada saat runtime, jadi ClassNotFoundExceptionitu tidak hasilnya. Ada perubahan pada kelas dan metode, sehingga tanda tangan metode yang ditemukan saat runtime tidak cocok dengan apa yang ada di waktu kompilasi.

Biasanya, kompiler akan menandai masalah di mana tanda tangan metode tidak cocok. JVM akan memverifikasi bytecode lagi ketika kelas dimuat, dan melempar VerifyErrorketika bytecode mencoba melakukan sesuatu yang tidak boleh diizinkan - misalnya memanggil metode yang mengembalikan Stringdan kemudian menyimpan nilai yang dikembalikan dalam bidang yang menampung a List.


3
Satu hal untuk ditambahkan, kadang-kadang kesalahan IDE, atau perangkat yang bytecode tidak benar. Coba mulai ulang IDE untuk membuatnya mengenali masalah sinkronisasi. Gagal yang menghapus dan menginstal ulang aplikasi. Mem-boot ulang perangkat juga dapat membantu.
ima747

2
Untuk mencari tahu kelas mana yang menjadi pelakunya, tambahkan argumen VM -verbose:classdan kemudian cari kelas sebelum memuat java.lang.VerifyError. Ini akan memiliki jalur ke JAR. Gunakan javapdan bandingkan dengan kelas yang Anda kompilasi. Saya menemukan ini berguna karena kelas yang dilaporkan dalam kesalahan itu bukan penyebabnya sebenarnya adalah salah satu argumen.
steinybot

21

java.lang.VerifyError adalah yang terburuk.

Anda akan mendapatkan kesalahan ini jika ukuran bytecode metode Anda melebihi batas 64kb; tetapi Anda mungkin akan memperhatikan itu.

Apakah Anda 100% yakin kelas ini tidak ada di classpath di tempat lain dalam aplikasi Anda, mungkin di toples lain?

Juga, dari stacktrace Anda, apakah pengkodean karakter file sumber ( utf-8?) Apakah itu benar?


Saya yakin itu tidak ada di tempat lain. Ini 43Kb, itu masih kelas besar.
Jeroen Wyseur

Terima kasih untuk posting itu, dalam kasus saya, ini merupakan penyandian yang berbeda: File JasperReports XMl menyimpan penyandian dan versi java, Anda harus menyetel ini sesuai dengan pengaturan proyek Anda (melalui iReport). Itulah masalahnya di sini, terima kasih atas ide Anda dengan penyandian! :)
Tobias

Ini adalah masalah saya untuk tes android, multidexing memperbaikinya.
Prakash Nadar

10

Seperti yang dikatakan Kevin Panko, itu sebagian besar karena perubahan perpustakaan. Jadi dalam beberapa kasus "bersih" dari proyek (direktori) diikuti oleh build yang berfungsi.


9

Satu hal yang mungkin Anda coba adalah menggunakan -Xverify:allbytecode yang akan memverifikasi saat memuat dan terkadang memberikan pesan kesalahan yang bermanfaat jika bytecode tidak valid.



8

VerifyError berarti file kelas berisi bytecode yang benar secara sintaksis tetapi melanggar beberapa pembatasan semantik misalnya target lompatan yang melintasi batas metode.

Pada dasarnya, VerifyError hanya dapat terjadi ketika ada bug kompiler, atau ketika file kelas rusak dalam beberapa cara lain (misalnya melalui RAM yang rusak atau HD yang gagal).

Coba kompilasi dengan versi JDK yang berbeda dan pada mesin yang berbeda.



4

Saya mendapatkan masalah ini karena mengemas 200 file kelas. Sedikit pencarian mengubah bug java ini . Pada dasarnya, pengaturan--effort=4 menyebabkan masalah hilang.

Menggunakan java 1.5.0_17 (meskipun dipotong di setiap varian tunggal java 1.5, saya mencobanya).


3

Saya telah memperbaiki masalah java.lang.VerifyError serupa dengan mengganti

        catch (MagickException e)

dengan

        catch (Exception e)

dimana MagickException didefinisikan dalam proyek perpustakaan (di mana proyek saya memiliki ketergantungan).

Setelah itu saya mendapat java.lang.NoClassDefFoundErrorkelas tentang dari perpustakaan yang sama (diperbaiki menurut https://stackoverflow.com/a/9898820/755804 ).


1
Ini bekerja untuk saya ... saya benar-benar ingin mencari tahu apa kesalahannya selain "ganti saya dengan pengecualian selimut dan saya akan bekerja" sekalipun.
Alex Hart

@AlexHart itu untuk Android, tetapi kemungkinan logika yang sama akan berlaku untuk perusahaan Java: stackoverflow.com/a/36814155/253468
TWiStErRob


2

Dalam kasus saya, saya harus menghapus blok ini:

compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_7
    targetCompatibility JavaVersion.VERSION_1_7
}

Itu menunjukkan kesalahan di dekat Fragment.showDialog()pemanggilan metode.


2

Contoh minimal yang menghasilkan kesalahan

Satu kemungkinan sederhana adalah menggunakan Jasmin , atau mengedit bytecode secara manual dengan editor file biner.

Mari kita membuat voidmetode tanpa returninstruksi (dihasilkan oleh return;pernyataan di Jawa), yang menurut JVMS adalah ilegal.

Di Jasmin kita bisa menulis:

.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

Kami kemudian melakukan javac Main.jdan javap -v Mainmengatakan bahwa kami telah menyusun:

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

jadi sungguh tidak ada instruksi pengembalian.

Sekarang jika kita mencoba menjalankan java Mainkita mendapatkan:

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)

Kesalahan ini tidak pernah bisa terjadi di Jawa biasanya, karena compiler Java menambahkan implisit returnuntuk voidmetode bagi kita. Inilah sebabnya kami tidak perlu menambahkan metode returnkami main. Anda dapat memeriksanya denganjavap .

JVMS

VerifyError terjadi ketika Anda mencoba menjalankan beberapa jenis file kelas ilegal seperti yang ditentukan oleh JVMS 7 bab 4.5

JVMS mengatakan bahwa ketika Java memuat file, ia harus menjalankan serangkaian pemeriksaan untuk melihat bahwa file kelas OK sebelum menjalankannya.

Kesalahan seperti itu tidak dapat dihasilkan pada satu kompilasi dan menjalankan siklus kode Java, karena JVMS 7 4.10 mengatakan :

Meskipun kompiler untuk bahasa pemrograman Java hanya harus menghasilkan file kelas yang memenuhi semua kendala statis dan struktural [...]

Jadi untuk melihat contoh kegagalan minimal, kita perlu membuat kode sumber tanpa javac.


1

Halaman ini dapat memberi Anda beberapa petunjuk - http://www.zanthan.com/itymbi/archives/000337.html

Mungkin ada bug halus dalam tubuh metode itu yang gagal ditemukan javac. Sulit didiagnosis kecuali Anda memposting seluruh metode di sini.

Anda bisa mulai dengan mendeklarasikan variabel sebanyak mungkin sebagai final ... yang akan menangkap bug yang disebutkan di situs zanthan, dan seringkali merupakan praktik yang baik.


1
Orang itu menabrak bug kompilator pada tahun 2002, tetapi bug itu telah diperbaiki sejak saat itu.
Kevin Panko

1

Nah dalam kasus saya, proyek saya A memiliki ketergantungan pada yang lain, katakanlah X (A menggunakan beberapa kelas yang didefinisikan dalam X). Jadi ketika saya menambahkan X sebagai proyek referensi di jalur build A, saya mendapatkan kesalahan ini. Namun ketika saya menghapus X sebagai proyek yang dirujuk dan memasukkan tabung X sebagai salah satu perpustakaan, masalahnya terpecahkan.


1

Periksa beberapa versi file jar yang sama di classpath Anda.

Sebagai contoh, saya memiliki opennlp-tools-1.3.0.jar dan opennlp-tools-1.5.3.jar di classpath saya dan mendapatkan kesalahan ini. Solusinya adalah menghapus opennlp-tools-1.3.0.jar.




1

Itu juga bisa terjadi ketika Anda memiliki banyak modul impor dengan pakar. Akan ada dua atau lebih kelas yang memiliki nama yang persis sama (nama yang memenuhi syarat sama). Kesalahan ini dihasilkan dari perbedaan interpretasi antara waktu kompilasi dan runtime.


1

Jika Anda bermigrasi ke java7 atau menggunakan java7 maka secara umum kesalahan ini dapat dilihat. Saya menghadapi kesalahan di atas dan banyak berjuang untuk mencari tahu penyebab utama, saya akan menyarankan untuk mencoba menambahkan argumen "-XX: -UseSplitVerifier" JVM saat menjalankan aplikasi Anda.


1

Setelah memperbarui Gradledi Android Studio 3.6.1 crash terjadi pada API 19 dalam rilis rilis.

Ada kesalahanGlide perpustakaan . Solusi adalah menulis ulang proguard-rules.txt .

Juga menurunkan versi Gradle( classpath 'com.android.tools.build:gradle:3.5.3'), tetapi ini adalah solusi yang sudah ketinggalan zaman, jangan gunakan itu.


0

Meskipun alasan yang disebutkan oleh Kevin benar, tapi saya pasti akan memeriksa di bawah sebelum pindah ke sesuatu yang lain:

  1. Periksa cglibsdi classpath saya.
  2. Periksa hibernateversi di classpath saya.

Kemungkinannya bagus bahwa memiliki beberapa versi atau yang bertentangan dari salah satu di atas dapat menyebabkan masalah tak terduga seperti yang dipertanyakan.


0

java.lang.VerifyError berarti bytecode kompilasi Anda merujuk ke sesuatu yang tidak dapat ditemukan Android. Ini memverifikasi saya Masalah hanya saya dengan kitkat4.4 dan versi lebih rendah tidak dalam versi di atas bahkan saya menjalankan build yang sama di kedua Perangkat. ketika saya menggunakan parser jackson json dari versi yang lebih lama itu menunjukkan 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.+'

Kemudian saya telah mengubah Ketergantungan ke versi terbaru 2.2 ke 2.7 tanpa perpustakaan inti , lalu berfungsi. yang berarti Metode dan konten inti lainnya dimigrasikan ke versi terbaru Databind2.7 . Ini memperbaiki Masalah saya.

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

Bagaimana Anda tahu JAR mana yang harus dicari?
Siddharth

1
jackson-core: 2.2. + menjadi warisan. jadi kita perlu menggunakan databind: 2.7.0-rc3, annotations: 2.7.0-rc3 atau versi terbaru dari ini. Ini 2 sudah cukup, hindari jackson-core: 2.2. +. Saya mendapat beberapa verifikasi saat itu. saat menggunakan versi 2.7+ itu tidak menunjukkan kesalahan itu
anand krish

0

harap hapus file jar yang tidak dapat digunakan dan coba jalankan. dan itu berfungsi untuk saya, saya menambahkan file jar jcommons dan juga file jar jcommons.1.0.14 lainnya jadi hapus jcommons dan itu berfungsi untuk saya


0

tulis di file:

{Wildfly-home}\modules\system\layers\base\org\picketbox\main 

ke dalam dependensi berikutnya: <module name="sun.jdk"/>


-1

Dalam kasus saya, saya mendapatkan kesalahan verifikasi dengan jejak stack di bawah ini

jasperreports-server-cp-6.4.0-bin\buildomatic\build.xml:61: The following error occurred while executing this line:
TIB_js-jrs-cp_6.4.0_bin\jasperreports-server-cp-6.4.0-bin\buildomatic\bin\setup.xml:320: java.lang.VerifyError: (class: org/apache/commons/codec/binary/Base64OutputStream, method: <init> signature: (Ljava/io/OutputStream;ZI[B)V) Incompatible argument to function
    at com.jaspersoft.jasperserver.crypto.KeystoreManager.createKeystore(KeystoreManager.java:257)
    at com.jaspersoft.jasperserver.crypto.KeystoreManager.init(KeystoreManager.java:224)
    at com.jaspersoft.buildomatic.crypto.KeystoreTask.execute(KeystoreTask.java:64)
    at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:292)
    at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
    at org.apache.tools.ant.Task.perform(Task.java:348)
    at org.apache.tools.ant.taskdefs.Sequential.execute(Sequential.java:68)
    at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:292)
    at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
    at org.apache.tools.ant.Task.perform(Task.java:348)
    at org.apache.tools.ant.Target.execute(Target.java:435)
    at org.apache.tools.ant.helper.ProjectHelper2.parse(ProjectHelper2.java:169)
    at org.apache.tools.ant.taskdefs.ImportTask.importResource(ImportTask.java:222)
    at org.apache.tools.ant.taskdefs.ImportTask.execute(ImportTask.java:163)
    at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:292)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
    at org.apache.tools.ant.Task.perform(Task.java:348)
    at org.apache.tools.ant.Target.execute(Target.java:435)
    at org.apache.tools.ant.helper.ProjectHelper2.parse(ProjectHelper2.java:180)
    at org.apache.tools.ant.ProjectHelper.configureProject(ProjectHelper.java:93)
    at org.apache.tools.ant.Main.runBuild(Main.java:826)
    at org.apache.tools.ant.Main.startAnt(Main.java:235)
    at org.apache.tools.ant.launch.Launcher.run(Launcher.java:280)
    at org.apache.tools.ant.launch.Launcher.main(Launcher.java:109)

Saya menyelesaikannya dengan menghapus entri classpath untuk commons-codec-1.3.jar, ada ketidakcocokan dalam versi jar ini dengan yang datang dengan Jasper.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.