Saya mendapatkan NoSuchMethodError
kesalahan saat menjalankan program Java saya. Apa yang salah dan bagaimana cara memperbaikinya?
java
nosuchmethoderror
John Meagher
sumber
sumber
Jawaban:
Tanpa informasi lebih lanjut, sulit untuk menentukan masalah, tetapi akar masalahnya adalah bahwa Anda kemungkinan besar telah mengkompilasi kelas terhadap versi berbeda dari kelas yang tidak memiliki metode, daripada yang Anda gunakan saat menjalankannya.
Lihat jejak tumpukan ... Jika pengecualian muncul saat memanggil metode pada objek di pustaka, Anda kemungkinan besar menggunakan versi pustaka yang terpisah saat menyusun dan menjalankan. Pastikan Anda memiliki versi yang tepat di kedua tempat.
Jika pengecualian muncul saat memanggil metode pada objek yang dipakai oleh kelas yang Anda buat, maka proses build Anda tampaknya salah. Pastikan file kelas yang Anda jalankan benar-benar diperbarui ketika Anda kompilasi.
sumber
Caused by
di tumpukan jejak untuk menemukan kelas / jar pelakunyaSaya mengalami masalah Anda, dan ini adalah bagaimana saya memperbaikinya. Langkah-langkah berikut adalah cara kerja untuk menambahkan perpustakaan. Saya telah melakukan dua langkah pertama dengan benar, tetapi saya belum melakukan yang terakhir dengan menyeret file ".jar" langsung dari sistem file ke folder "lib" pada proyek gerhana saya. Selain itu, saya harus menghapus versi pustaka sebelumnya dari folder build dan folder "lib".
Langkah 1 - Tambahkan .jar untuk membangun jalur
Langkah 2 - Mengaitkan sumber dan javadocs (opsional)
Langkah 3 - Sebenarnya seret file .jar ke folder "lib" (bukan opsional)
sumber
Perhatikan bahwa dalam kasus refleksi, Anda mendapatkan
NoSuchMethodException
, sedangkan dengan kode non-reflektif, Anda dapatkanNoSuchMethodError
. Saya cenderung pergi mencari di tempat yang sangat berbeda ketika berhadapan dengan satu lawan yang lain.sumber
Jika Anda memiliki akses untuk mengubah parameter JVM, menambahkan output verbose akan memungkinkan Anda untuk melihat kelas apa yang sedang diambil dari file JAR mana.
Ketika program Anda dijalankan, JVM harus membuang ke informasi standar seperti:
sumber
Ini biasanya disebabkan ketika menggunakan sistem build seperti Apache Ant yang hanya mengkompilasi file java ketika file java lebih baru daripada file kelas. Jika metode perubahan tanda tangan dan kelas menggunakan versi lama hal-hal yang tidak dapat dikompilasi dengan benar. Perbaikan yang biasa adalah melakukan pembangunan kembali penuh (biasanya "semut bersih" lalu "semut").
Kadang-kadang ini juga bisa disebabkan ketika kompilasi terhadap satu versi perpustakaan tetapi berjalan melawan versi yang berbeda.
sumber
Jika menggunakan Maven atau kerangka kerja lain, dan Anda mendapatkan kesalahan ini hampir secara acak, coba instal bersih seperti ...
Ini sangat mungkin bekerja jika Anda menulis objek dan Anda tahu itu memiliki metode. Bekerja untukku.
sumber
Ini juga bisa menjadi hasil dari menggunakan refleksi. Jika Anda memiliki kode yang mencerminkan kelas dan mengekstrak metode dengan nama (misalnya: dengan
Class.getDeclaredMethod("someMethodName", .....)
) maka setiap kali nama metode itu berubah, seperti saat refactor, Anda harus ingat untuk memperbarui parameter ke metode refleksi untuk mencocokkan dengan tanda tangan metode baru, ataugetDeclaredMethod
panggilan akan melempar aNoSuchMethodException
.Jika ini alasannya, maka jejak tumpukan harus menunjukkan titik bahwa metode refleksi dipanggil, dan Anda hanya perlu memperbarui parameter agar sesuai dengan tanda tangan metode yang sebenarnya.
Dalam pengalaman saya, ini muncul sesekali ketika unit menguji metode / bidang pribadi, dan menggunakan
TestUtilities
kelas untuk mengekstrak bidang untuk verifikasi pengujian. (Umumnya dengan kode lawas yang tidak dirancang dengan pengujian unit dalam pikiran.)sumber
Jika Anda menulis aplikasi web, pastikan bahwa Anda tidak memiliki versi yang bertentangan dari sebuah toples di direktori global library Anda dan juga di aplikasi Anda. Anda mungkin belum tentu tahu stoples mana yang sedang digunakan oleh classloader.
misalnya
sumber
Masalah-masalah ini disebabkan oleh penggunaan objek yang sama di dua kelas yang sama. Objek yang digunakan tidak mengandung metode baru telah ditambahkan yang berisi kelas objek baru.
ex:
Masalah-masalah ini disebabkan oleh 02 kelas yang sama secara bersamaan (1 dalam src, 1 dalam file jar di sini adalah gateway.jar)
sumber
Ini berarti masing-masing metode tidak ada di kelas:
sumber
Bagi saya itu terjadi karena saya mengubah tipe argumen dalam fungsi, dari Object a, ke String a. Saya bisa menyelesaikannya dengan bersih dan membangun lagi
sumber
Saya baru saja menyelesaikan kesalahan ini dengan memulai ulang Eclipse saya dan menjalankan applcation. Alasan untuk kasus saya mungkin karena saya mengganti file sumber saya tanpa menutup proyek atau Eclipse saya. Yang menyebabkan versi berbeda dari kelas yang saya gunakan.
sumber
Coba dengan cara ini: hapus semua file .class di bawah direktori proyek Anda (dan, tentu saja, semua subdirektori). Membangun kembali.
Terkadang
mvn clean
(jika Anda menggunakan maven) tidak membersihkan file .class yang dibuat secara manual olehjavac
. Dan file-file lama berisi tanda tangan lama, mengarah keNoSuchMethodError
.sumber
Hanya menambah jawaban yang ada. Saya menghadapi masalah ini dengan kucing jantan dalam gerhana. Saya telah mengubah satu kelas dan melakukan langkah-langkah berikut,
Membersihkan dan membangun proyek di eclpise
bersihkan instalasi
Namun saya masih menghadapi kesalahan yang sama. Kemudian saya membersihkan tomcat, membersihkan direktori kerja tomcat dan me-restart server dan masalah saya hilang. Semoga ini bisa membantu seseorang
sumber
Untuk menjawab pertanyaan awal. Menurut java docs di sini :
Biasanya, kesalahan ini ditangkap oleh kompiler; kesalahan ini hanya dapat terjadi pada saat run time jika definisi kelas telah berubah secara tidak kompatibel.
sumber
Saya memperbaiki masalah ini di Eclipse dengan mengganti nama file tes Junit.
Di ruang kerja Eclipse saya, saya memiliki proyek App dan proyek Uji.
Proyek Uji memiliki proyek Aplikasi sebagai proyek yang diperlukan di jalur build.
Mulai mendapatkan NoSuchMethodError.
Kemudian saya menyadari bahwa kelas dalam proyek Uji memiliki nama yang sama dengan kelas dalam proyek Aplikasi.
Setelah mengganti nama Tes ke nama yang benar "ProjectionTest.java" pengecualian hilang.
sumber
Saya memiliki kesalahan yang sama:
Untuk mengatasinya saya memeriksa, pertama-tama, Diagram Modul Ketergantungan (
click in your POM the combination -> Ctrl+Alt+Shift+U
atauright click in your POM -> Maven -> Show dependencies
) untuk memahami di mana tepatnya konflik antara perpustakaan (Intelij IDEA). Dalam kasus khusus saya, saya memiliki versi dependensi Jackson yang berbeda.1) Jadi, saya menambahkan secara langsung di POM proyek saya secara eksplisit versi tertinggi - 2.8.7 dari keduanya.
Di properti:
Dan sebagai ketergantungan:
2) Tetapi juga bisa diselesaikan menggunakan Ketergantungan Pengecualian .
Dengan prinsip yang sama seperti di bawah ini dalam contoh:
Ketergantungan dengan versi yang tidak diinginkan akan dikeluarkan dari proyek Anda.
sumber
Dalam kasus saya, saya memiliki proyek multi-modul dan skenario seperti
com.xyz.TestClass
dalam modulA
dan juga dalam modulB
dan modulA
tergantung pada modulB
. Jadi saat membuat toples perakitan saya pikir hanya satu versi kelas yang dipertahankan jika itu tidak memiliki metode yang dipanggil maka saya dapatkanNoSuchMethodError
pengecualian runtime, tetapi kompilasi baik-baik saja.Terkait: https://reflectoring.io/nosuchmethod/
sumber
Saya mengalami masalah yang sama ketika saya mengubah tanda tangan metode dalam aplikasi saya. Membersihkan dan membangun kembali proyek saya menyelesaikan "NoSuchMethodError".
sumber
Di atas jawaban menjelaskan dengan sangat baik .. hanya untuk menambahkan satu hal Jika Anda menggunakan menggunakan gerhana gunakan ctrl + shift + T dan masukkan struktur paket kelas (misalnya: gateway.smpp.PDUEventListener), Anda akan menemukan semua guci / proyek di mana ia hadir . Hapus guci yang tidak perlu dari classpath atau tambahkan di atas di jalur kelas. Sekarang akan mengambil yang benar.
sumber
Saya mengalami masalah serupa.
Akhirnya saya mengidentifikasi akar penyebabnya adalah mengubah tipe data variabel.
Employee.java
-> Berisi variabel (EmpId
) yang Tipe datanya telah diubah dariint
menjadiString
.ReportGeneration.java
-> Mengambil nilai menggunakan pengambilgetEmpId()
,.Kita seharusnya menyatukan kembali toples dengan memasukkan hanya kelas yang dimodifikasi. Karena tidak ada perubahan pada
ReportGeneration.java
saya hanya termasuk fileEmployee.class
in Jar. Saya harus memasukkanReportGeneration.class
file ke dalam toples untuk menyelesaikan masalah.sumber
Saya memiliki masalah yang sama. Ini juga disebabkan ketika ada ambiguitas di kelas. Program saya mencoba memanggil metode yang ada di dua file JAR yang ada di lokasi / jalur kelas yang sama. Hapus satu file JAR atau jalankan kode Anda sehingga hanya satu file JAR yang digunakan. Pastikan Anda tidak menggunakan JAR yang sama atau versi yang berbeda dari JAR yang sama yang berisi kelas yang sama.
sumber
Penjelasan Terbaik: https://www.journaldev.com/14538/java-lang-nosuchmethoderror
sumber
Saya juga mengalami kesalahan ini.
Masalah saya adalah saya telah mengubah tanda tangan metode, seperti
ke
Metode ini dipanggil dari konteks yang mirip dengan
Kompilator diam sehubungan dengan peringatan / kesalahan, karena modal adalah Mata Uang dan juga Euro.
Masalahnya muncul karena fakta bahwa saya hanya mengkompilasi kelas di mana metode tersebut didefinisikan - Bank, tetapi bukan kelas dari mana metode ini dipanggil, yang berisi metode main ().
Masalah ini bukan sesuatu yang mungkin Anda temui terlalu sering, karena paling sering proyek dibangun kembali secara manual atau tindakan Build dipicu secara otomatis, alih-alih hanya mengkompilasi satu kelas yang dimodifikasi.
Usecase saya adalah bahwa saya membuat file .jar yang akan digunakan sebagai perbaikan terbaru, yang tidak mengandung App.class karena ini tidak dimodifikasi. Masuk akal bagi saya untuk tidak memasukkannya karena saya mempertahankan kelas dasar argumen awal melalui warisan.
Masalahnya adalah, ketika Anda mengkompilasi kelas, bytecode yang dihasilkan agak statis , dengan kata lain, itu adalah referensi yang sulit .
Bytecode asli yang dibongkar (dibuat dengan alat javap) terlihat seperti ini:
Setelah ClassLoader memuat Bank.class yang baru dikompilasi, itu tidak akan menemukan metode seperti itu, tampaknya seolah-olah itu dihapus dan tidak diubah, dengan demikian kesalahan bernama.
Semoga ini membantu.
sumber
Masalah dalam kasus saya adalah memiliki dua versi dari perpustakaan yang sama di jalur build. Versi perpustakaan yang lebih lama tidak memiliki fungsi, dan yang lebih baru memilikinya.
sumber
Saya memiliki masalah yang sama dengan Proyek Gradle saya menggunakan Intelij. Saya menyelesaikannya dengan menghapus paket .gradle (lihat tangkapan layar di bawah) dan membangun kembali Proyek. Paket .gradle
sumber
NoSuchMethodError: Saya telah menghabiskan beberapa jam untuk memperbaiki masalah ini, akhirnya memperbaikinya hanya dengan mengubah nama nama paket, membersihkan dan membangun ... Coba bersihkan bangunan terlebih dahulu jika tidak berfungsi coba ganti nama nama kelas atau nama paket dan bangun bersih .. .itu harus diperbaiki. Semoga berhasil.
sumber
Jika nama file Anda berbeda dari nama kelas yang berisi metode utama maka kemungkinan kesalahan ini dapat terjadi.
sumber