Apa yang menyebabkan dan apa perbedaan antara NoClassDefFoundError dan ClassNotFoundException?

371

Apa perbedaan antara NoClassDefFoundErrordan ClassNotFoundException?

Apa yang menyebabkan mereka dilempar? Bagaimana mereka bisa diselesaikan?

Saya sering menemukan lemparan ini ketika memodifikasi kode yang sudah ada untuk memasukkan file jar baru. Saya telah memukul mereka di sisi klien dan sisi server untuk aplikasi java yang didistribusikan melalui webstart.

Kemungkinan alasan yang saya temui:

  1. paket tidak termasuk dalam build.xmluntuk sisi kode klien
  2. runtime classpath hilang untuk guci baru yang kami gunakan
  3. konflik versi dengan toples sebelumnya

Ketika saya menemukan ini hari ini saya mengambil pendekatan jejak-dan-kesalahan untuk membuat semuanya berfungsi. Saya membutuhkan lebih banyak kejelasan dan pengertian.

keris
sumber
Saya sering menemukan menjalankan JVM dengan -verbose(misalnya -verbose:class -verbose:jni) membantu - tetapi mogsie melaporkan di bawah jawaban mereka bahwa ini tidak memberikan informasi tambahan yang berguna :(
PJTraill

Jawaban:

388

Perbedaan dari Spesifikasi Java API adalah sebagai berikut.

Untuk ClassNotFoundException:

Dilemparkan ketika aplikasi mencoba memuat di kelas melalui nama stringnya menggunakan:

  • The forNamemetode di kelas Class.
  • The findSystemClassmetode di kelas ClassLoader.
  • The loadClassmetode di kelas ClassLoader.

tetapi tidak ada definisi untuk kelas dengan nama yang ditentukan dapat ditemukan.

Untuk NoClassDefFoundError:

Dilemparkan jika Java Virtual Machine atau ClassLoaderinstance mencoba memuat dalam definisi kelas (sebagai bagian dari pemanggilan metode normal atau sebagai bagian dari membuat instance baru menggunakan ekspresi baru) dan tidak ada definisi kelas yang dapat ditemukan.

Definisi kelas yang dicari untuk ada ketika kelas yang sedang dieksekusi dikompilasi, tetapi definisi tidak dapat lagi ditemukan.

Jadi, tampak bahwa NoClassDefFoundErrorterjadi ketika sumber berhasil dikompilasi, tetapi saat runtime, classfile yang diperlukan tidak ditemukan. Ini mungkin sesuatu yang bisa terjadi dalam distribusi atau produksi file JAR, di mana tidak semua classfile yang diperlukan dimasukkan.

Adapun ClassNotFoundException, tampaknya itu mungkin berasal dari mencoba membuat panggilan reflektif ke kelas saat runtime, tetapi kelas-kelas yang coba dipanggil oleh program tidak ada.

Perbedaan antara keduanya adalah bahwa yang satu adalah Errordan yang lainnya adalah Exception. Dengan NoClassDefFoundErroradalah Errordan itu muncul dari Java Virtual Machine mengalami masalah menemukan kelas yang diharapkan untuk menemukan. Program yang diharapkan bekerja pada waktu kompilasi tidak dapat berjalan karena classfile tidak ditemukan, atau tidak sama dengan yang diproduksi atau ditemui pada waktu kompilasi. Ini adalah kesalahan yang cukup kritis, karena program tidak dapat dimulai oleh JVM.

Di sisi lain, itu ClassNotFoundExceptionadalah Exception, jadi agak diharapkan, dan merupakan sesuatu yang dapat dipulihkan. Menggunakan refleksi dapat menjadi rawan kesalahan (karena ada beberapa harapan bahwa hal-hal mungkin tidak berjalan seperti yang diharapkan. Tidak ada pemeriksaan waktu kompilasi untuk melihat bahwa semua kelas yang diperlukan ada, sehingga setiap masalah dengan menemukan kelas yang diinginkan akan muncul saat runtime .

coobird
sumber
53
NoClassDefFoundErrorbiasanya terjadi ketika ada masalah (pengecualian dilempar) dengan blok statis atau inisialisasi bidang statis kelas, sehingga kelas tidak dapat diinisialisasi dengan sukses.
Dagang
7
Suara positif. satu adalah Errordan yang lainnya adalah Exception. :)
Ravi
83

ClassNotFoundException dilemparkan ketika kelas yang dilaporkan tidak ditemukan oleh ClassLoader. Ini biasanya berarti bahwa kelas tidak ada di CLASSPATH. Ini juga bisa berarti bahwa kelas yang dimaksud sedang mencoba untuk dimuat dari kelas lain yang dimuat dalam classloader induk dan karenanya kelas dari child classloader tidak terlihat. Ini kadang terjadi ketika bekerja di lingkungan yang lebih kompleks seperti Server Aplikasi (WebSphere terkenal karena masalah classloader tersebut).

Orang sering cenderung bingung java.lang.NoClassDefFoundErrordengan java.lang.ClassNotFoundExceptionnamun ada perbedaan penting. Misalnya pengecualian (kesalahan sejak itu java.lang.NoClassDefFoundErroradalah subclass dari java.lang.Error) seperti

java.lang.NoClassDefFoundError:
org/apache/activemq/ActiveMQConnectionFactory

tidak berarti bahwa kelas ActiveMQConnectionFactory tidak ada di CLASSPATH. Justru sebaliknya. Ini berarti bahwa kelas ActiveMQConnectionFactory ditemukan oleh ClassLoader namun ketika mencoba memuat kelas, itu mengalami kesalahan membaca definisi kelas. Ini biasanya terjadi ketika kelas yang bersangkutan memiliki blok statis atau anggota yang menggunakan Kelas yang tidak ditemukan oleh ClassLoader. Jadi untuk menemukan pelakunya, lihat sumber kelas yang dimaksud (ActiveMQConnectionFactory dalam kasus ini) dan cari kode menggunakan blok statis atau anggota statis. Jika Anda tidak memiliki akses ke sumbernya, cukup dekompilasi menggunakan JAD.

Pada memeriksa kode, katakan Anda menemukan garis kode seperti di bawah ini, pastikan kelas SomeClass di dalam CLASSPATH Anda.

private static SomeClass foo = new SomeClass();

Kiat: Untuk mengetahui toples mana yang dimiliki kelas, Anda dapat menggunakan jarFinder situs web. Ini memungkinkan Anda untuk menentukan nama kelas menggunakan wildcard dan mencari kelas di database guci. jarhoo memungkinkan Anda untuk melakukan hal yang sama tetapi tidak lagi bebas untuk digunakan.

Jika Anda ingin mencari tabung yang dimiliki kelas di jalur lokal, Anda dapat menggunakan utilitas seperti jarscan ( http://www.inetfeedback.com/jarscan/ ). Anda cukup menentukan kelas yang ingin Anda temukan dan jalur direktori root di mana Anda ingin mulai mencari kelas dalam guci dan file zip.

Sanjiv Jivan
sumber
9
Saya lucu bahwa ini adalah jawaban yang paling tepat. (Bahkan -1 sebelum saya memilih). ClassNotFoundException berarti CL tidak melihat file .class. NoClassDefFoundError berarti file .class ada di sana tidak dapat dimuat (mungkin kesalahan JNI).
user43685
1
Bukankah jawaban ini bertentangan dengan bentuk jawaban coobird?
zardosht
Saya mencoba contoh serupa dari blok Statis. Kelas saya Class1 memiliki variabel statis "private static B foo = new B ();" Setelah kompilasi, saya menghapus file B.class dari folder bin. Sekarang dari metode utama kelas ketiga ketika saya membuat objek dari Class1. Rror ini dikenal sebagai follws: -------- "Pengecualian di utas" utama "java.lang.NoClassDefFoundError: spring / B" ........ Jadi persisnya disebutkan kelas mana yang tidak ditemukan. ieclass disebut dalam blok statis dan bukan kelas luar. Jadi itu bertentangan dengan jawaban ini.
Kaushik Lele
+1 untuk klarifikasi mengenai "tidak berarti bahwa kelas ActiveMQConnectionFactory tidak ada dalam CLASSPATH"
akila
35

NoClassDefFoundErroradalah kesalahan tautan pada dasarnya. Ini terjadi ketika Anda mencoba dan membuat instance suatu objek (secara statis dengan "baru") dan itu tidak ditemukan ketika itu selama kompilasi.

ClassNotFoundExceptionlebih umum dan merupakan pengecualian runtime ketika Anda mencoba menggunakan kelas yang tidak ada. Misalnya, Anda memiliki parameter dalam fungsi yang menerima antarmuka dan seseorang lewat di kelas yang mengimplementasikan antarmuka itu tetapi Anda tidak memiliki akses ke kelas. Ini juga mencakup kasus pemuatan kelas dinamis, seperti menggunakan loadClass()atau Class.forName().

cletus
sumber
29

NoClassDefFoundError (NCDFE) terjadi ketika kode Anda menjalankan "Y baru ()" dan tidak dapat menemukan kelas Y.

Mungkin saja bahwa Y hilang dari pemuat kelas Anda seperti komentar lain yang disarankan, tetapi bisa jadi bahwa kelas Y tidak ditandatangani atau memiliki tanda tangan tidak valid, atau bahwa Y dimuat oleh classloader berbeda yang tidak terlihat oleh kode Anda , atau bahkan Y tergantung pada Z yang tidak dapat dimuat karena alasan di atas.

Jika ini terjadi, maka JVM akan mengingat hasil pemuatan X (NCDFE) dan itu hanya akan membuang NCDFE baru setiap kali Anda meminta Y tanpa memberi tahu Anda alasannya:

kelas A {
  kelas statis b {}
  public static static utama (String args []) {
    System.out.println ("Upaya pertama yang baru b ():");
    coba {new b (); } catch (Throwable t) {t.printStackTrace ();}
    System.out.println ("\ nMencoba baru b ():");
    coba {new b (); } catch (Throwable t) {t.printStackTrace ();}
  }
}

simpan ini sebagai a.java di suatu tempat

Kode hanya mencoba membuat instance kelas "b" baru dua kali, selain itu, tidak memiliki bug, dan tidak melakukan apa pun.

Kompilasi kode dengan javac a.java, Kemudian jalankan dengan memohon java -cp . a- itu hanya akan mencetak dua baris teks, dan itu harus berjalan dengan baik tanpa kesalahan.

Kemudian hapus file "a $ b.class" (atau isi dengan sampah, atau salin a.class di atasnya) untuk mensimulasikan kelas yang hilang atau rusak. Inilah yang terjadi:

Upaya pertama yang baru b ():
java.lang.NoClassDefFoundError: a $ b
    di a.main (a.java 5-10)
Disebabkan oleh: java.lang.ClassNotFoundException: a $ b
    di java.net.URLClassLoader $ 1.run (URLClassLoader.java:00)
    di java.security.AccessController.doPrivileged (Metode Asli)
    di java.net.URLClassLoader.findClass (URLClassLoader.java:188)
    di java.lang.ClassLoader.loadClass (ClassLoader.java:307)
    di sun.misc.Launcher $ AppClassLoader.loadClass (Launcher.java:301)
    di java.lang.ClassLoader.loadClass (ClassLoader.java:252)
    di java.lang.ClassLoader.loadClassInternal (ClassLoader.java:320)
    ... 1 lagi

Upaya kedua baru b ():
java.lang.NoClassDefFoundError: a $ b
    di a.main (a.java:7)

Doa pertama menghasilkan ClassNotFoundException (dilemparkan oleh pemuat kelas ketika tidak dapat menemukan kelas), yang harus dibungkus dengan NoClassDefFoundError yang tidak dicentang, karena kode yang dipermasalahkan ( new b()) seharusnya hanya berfungsi.

Upaya kedua tentu saja akan gagal juga, tetapi seperti yang Anda lihat pengecualian dibungkus tidak lebih, karena ClassLoader tampaknya ingat pemuat kelas yang gagal. Anda hanya melihat NCDFE yang sama sekali tidak tahu apa yang sebenarnya terjadi.

Jadi jika Anda pernah melihat NCDFE tanpa akar penyebab, Anda perlu melihat apakah Anda dapat melacak kembali saat pertama kali kelas dimuat untuk menemukan penyebab kesalahan.

mogsie
sumber
Bagaimana dengan menjalankan JVM dengan -verbose, atau beberapa opsi serupa tergantung pada JVM tertentu? Mungkin -verbose:class, mungkin -verbose:class:jnijika menggunakan JNI, tapi saya tidak yakin tentang sintaksisnya. Jika ini berguna, mungkin Anda bisa menunjukkan hasilnya.
PJTraill
Juga -verbose:classtidak -verbose:jnimemberikan output tambahan yang relevan dengan kelas yang hilang.
mogsie
1
Terima kasih telah mencobanya, bahkan jika hasilnya mengecewakan. (PS Saya sejak menemukan bahwa -verbose:class:jniitu salah: kita harus menentukan dua opsi terpisah:. -verbose:class -verbose:jni)
PJTraill
2
Kalimat terakhir * 1.000.000: Jadi jika Anda pernah melihat NCDFE tanpa akar penyebab, Anda perlu melihat apakah Anda dapat melacak kembali saat pertama kali kelas dimuat untuk menemukan penyebab kesalahan.
batwad
20

Dari http://www.javaroots.com/2013/02/classnotfoundexception-vs.html :

ClassNotFoundException: terjadi ketika pemuat kelas tidak dapat menemukan kelas yang diperlukan di jalur kelas. Jadi, pada dasarnya Anda harus memeriksa jalur kelas Anda dan menambahkan kelas di classpath.

NoClassDefFoundError: ini lebih sulit untuk di-debug dan menemukan alasannya. Ini dilemparkan ketika pada waktu kompilasi kelas yang diperlukan hadir, tetapi pada saat run kelas diubah atau dihapus atau statis kelas menginisialisasi melempar pengecualian. Itu berarti kelas yang mendapatkan dimuat hadir di classpath, tetapi salah satu kelas yang diperlukan oleh kelas ini dihapus atau gagal dimuat oleh kompiler. Jadi Anda harus melihat kelas-kelas yang bergantung pada kelas ini.

Contoh :

public class Test1
{
}


public class Test 
{
   public static void main(String[] args)
   {
        Test1 = new Test1();    
   }

}

Sekarang setelah mengkompilasi kedua kelas, jika Anda menghapus file Test1.class dan menjalankan kelas Test, itu akan melempar

Exception in thread "main" java.lang.NoClassDefFoundError: Test
    at Test1.main(Test1.java:5)
Caused by: java.lang.ClassNotFoundException: Test
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    ... 1 more

ClassNotFoundException: dilemparkan ketika aplikasi mencoba memuat di kelas melalui namanya, tetapi tidak ada definisi untuk kelas dengan nama yang ditentukan dapat ditemukan.

NoClassDefFoundError: dilemparkan jika Java Virtual Machine mencoba memuat dalam definisi kelas dan tidak ada definisi kelas yang dapat ditemukan.

KingFeming
sumber
Bagaimana dengan menjalankan JVM dengan -verbose, atau beberapa opsi serupa tergantung pada JVM tertentu? Mungkin -verbose:class, mungkin -verbose:class:jnijika menggunakan JNI, tapi saya tidak yakin tentang sintaksisnya.
PJTraill
-verbose:class:jnisalah, tapi Anda dapat melewati dua pilihan yang terpisah: -verbose:class -verbose:jni.
PJTraill
15

Apa alasan untuk mendapatkan masing-masing dari mereka dan setiap proses pemikiran tentang bagaimana menangani kesalahan seperti itu?

Mereka terkait erat. A ClassNotFoundExceptionterlempar ketika Jawa pergi mencari kelas tertentu dengan nama dan tidak berhasil memuatnya. A NoClassDefFoundErrorterlempar ketika Java pergi mencari kelas yang ditautkan ke beberapa kode yang ada, tetapi tidak dapat menemukannya karena satu dan lain hal (misalnya, classpath yang salah, versi Java yang salah, versi perpustakaan yang salah) dan sangat fatal karena itu menunjukkan bahwa ada sesuatu yang salah.

Jika Anda memiliki latar belakang C, CNFE seperti kegagalan untuk dlopen()/ dlsym()dan NCDFE adalah masalah dengan penghubung; dalam kasus kedua, file kelas yang bersangkutan seharusnya tidak pernah benar-benar dikompilasi dalam konfigurasi yang Anda coba gunakan.

Donal Fellows
sumber
11

Contoh 1:

class A{
 void met(){
   Class.forName("com.example.Class1");
 }
}

Jika com/example/Class1tidak ada di classpath, maka itu melempar ClassNotFoundException.

Contoh # 2:

Class B{
  void met(){
   com.example.Class2 c = new com.example.Class2();
 }
}

Jika com/example/Class2ada saat mengkompilasi B, tetapi tidak ditemukan saat eksekusi, maka itu melempar NoClassDefFoundError.

Keduanya adalah pengecualian waktu berjalan.

Dinesh
sumber
9

ClassNotFoundException dilemparkan ketika ada upaya untuk memuat kelas dengan merujuknya melalui sebuah String. Sebagai contoh, parameter untuk di Class.forName () adalah sebuah String, dan ini meningkatkan potensi nama biner yang tidak valid yang diteruskan ke classloader.

ClassNotFoundException dilemparkan ketika nama biner yang berpotensi tidak valid ditemukan; misalnya, jika nama kelas memiliki karakter '/', Anda terikat untuk mendapatkan ClassNotFoundException. Ini juga terlempar ketika kelas yang direferensikan langsung tidak tersedia di classpath.

Di sisi lain, NoClassDefFoundError terlempar

  • ketika representasi fisik sebenarnya dari kelas - file .class tidak tersedia,
  • atau kelas sudah dimuat di classloader yang berbeda (biasanya classloader induk akan memuat kelas dan karenanya kelas tidak dapat dimuat lagi),
  • atau jika definisi kelas yang tidak kompatibel telah ditemukan - nama dalam file kelas tidak cocok dengan nama yang diminta,
  • atau (paling penting) jika kelas dependen tidak dapat ditemukan dan dimuat. Dalam hal ini, kelas yang dirujuk langsung mungkin telah ditemukan dan dimuat, tetapi kelas dependen tidak tersedia atau tidak dapat dimuat. Ini adalah skenario di mana kelas yang direferensikan langsung dapat dimuat melalui Class.forName atau metode yang setara. Ini menunjukkan kegagalan dalam hubungan.

Singkatnya, NoClassDefFoundError biasanya dilemparkan pada pernyataan () baru atau pemanggilan metode yang memuat kelas yang sebelumnya tidak ada (sebagai lawan dari pemuatan kelas berbasis string untuk ClassNotFoundException), ketika classloader tidak dapat menemukan atau memuat definisi kelas ( s).

Akhirnya, tergantung pada implementasi ClassLoader untuk melempar instance dari ClassNotFoundException ketika tidak dapat memuat kelas. Sebagian besar implementasi classloader kustom melakukan ini karena mereka memperpanjang URLClassLoader. Biasanya classloaders tidak secara eksplisit melempar NoClassDefFoundError pada salah satu implementasi metode - pengecualian ini biasanya dilemparkan dari JVM di kompiler HotSpot, dan bukan oleh classloader itu sendiri.

Vineet Reynolds
sumber
Suara positif karena menyebutkan 'nama dalam file kelas tidak cocok dengan nama yang diminta'. Ini adalah penyebab yang cukup umum.
Marquis of Lorne
8

Perbedaan Antara ClassNotFoundException Vs NoClassDefFoundError

masukkan deskripsi gambar di sini

Lawakush Kurmi
sumber
Tidak sebening kristal. "Tidak diperbarui di classpath" tidak jelas / tidak tepat. Ini tentang JAR yang tidak hadir di classpath, atau versi JAR yang salah berada di classpath. Dan kesalahan ejaan. Dan (desah) karena Anda memposting informasi Anda sebagai grafik yang funky, kami tidak dapat memperbaikinya.
Stephen C
8

Dengan nama itu sendiri kita dapat dengan mudah mengidentifikasi satu dari Exceptiondan yang lainnya dari Error.

Pengecualian: Pengecualian terjadi selama pelaksanaan program. Seorang programmer dapat menangani pengecualian ini dengan mencoba menangkap blok. Kami memiliki dua jenis pengecualian. Memeriksa pengecualian yang melempar pada waktu kompilasi. Pengecualian Runtime yang dilemparkan pada saat dijalankan, pengecualian ini biasanya terjadi karena pemrograman yang buruk.

Kesalahan: Ini bukan pengecualian sama sekali, itu di luar lingkup programmer. Kesalahan ini biasanya dilontarkan oleh JVM.


masukkan deskripsi gambar di sini sumber gambar

Perbedaan:

ClassNotFoundException:

  • Kelas loader gagal untuk memverifikasi kode kelas byte kami menyebutkan di link fase dari class loading subsistem kita ClassNotFoundException.
  • ClassNotFoundExceptionadalah Pengecualian yang diperiksa berasal langsung dari java.lang.Exceptionkelas dan Anda harus memberikan penanganan eksplisit untuk itu
  • ClassNotFoundExceptionmuncul ketika ada pemuatan eksplisit kelas yang terlibat dengan memberikan nama kelas saat runtime menggunakan ClassLoader.loadClass (), Class.forName () dan ClassLoader.findSystemClass ().

NoClassDefFoundError:

  • Loader kelas gagal menyelesaikan referensi kelas dalam fase Tautan dari subsistem pemuatan kelas yang kita dapatkan NoClassDefFoundError.
  • NoClassDefFoundErroradalah kesalahan yang berasal dari LinkageErrorkelas, yang digunakan untuk menunjukkan kasus kesalahan, di mana kelas memiliki ketergantungan pada beberapa kelas lain dan kelas itu telah berubah secara tidak kompatibel setelah kompilasi.
  • NoClassDefFoundErroradalah hasil dari pemuatan kelas implisit karena pemanggilan metode dari kelas itu atau akses variabel apa pun.

Kesamaan:

  • Keduanya NoClassDefFoundErrordan ClassNotFoundExceptionterkait dengan tidak tersedianya kelas saat run-time.
  • Keduanya ClassNotFoundExceptiondan NoClassDefFoundErrorterkait dengan classpath Java.
Premraj
sumber
3

Mengingat tindakan sussystem loader Kelas:

http://www.artima.com/insidejvm/ed2/images/fig7-1.gif

Ini adalah artikel yang banyak membantu saya untuk memahami perbedaannya: http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html

Jika terjadi kesalahan selama pemuatan kelas, maka instance dari subkelas LinkageError harus dilempar ke suatu titik dalam program yang (secara langsung atau tidak langsung) menggunakan kelas atau antarmuka yang sedang dimuat.

Jika Mesin Virtual Java pernah mencoba memuat kelas C selama verifikasi (§5.4.1) atau resolusi (§5.4.3) (tetapi bukan inisialisasi (§5.5)), dan kelas loader yang digunakan untuk memulai memuat C melempar instance dari ClassNotFoundException , maka Java Virtual Machine harus melempar instance dari NoClassDefFoundError yang penyebabnya adalah instance dari ClassNotFoundException .

Jadi ClassNotFoundException adalah penyebab utama dari NoClassDefFoundError .
Dan NoClassDefFoundError adalah kasus khusus kesalahan pemuatan tipe, yang terjadi pada langkah Linking .

Anton Shchastnyi
sumber
2

Tambahkan satu kemungkinan alasan dalam praktik:

  • ClassNotFoundException: seperti kata cletus, Anda menggunakan antarmuka sementara kelas antarmuka bawaan tidak ada di classpath. Misalnya, Pola Penyedia Layanan (atau Penentu Lokasi Layanan ) mencoba menemukan beberapa kelas yang tidak ada
  • NoClassDefFoundError: kelas yang diberikan ditemukan sementara ketergantungan kelas yang diberikan tidak ditemukan

Dalam praktiknya, Kesalahan dapat dilemparkan secara diam - diam , misalnya, Anda mengirimkan tugas penghitung waktu dan dalam tugas penghitung waktu ia melempar Kesalahan , sementara dalam kebanyakan kasus, program Anda hanya menangkap Pengecualian . Kemudian loop utama Timer berakhir tanpa informasi apa pun. Kesalahan serupa dengan NoClassDefFoundError adalah ExceptionInInitializerError , ketika penginisialisasi statis Anda atau penginisialisasi untuk variabel statis melempar pengecualian.

Leef
sumber
1

ClassNotFoundException adalah pengecualian yang diperiksa yang terjadi ketika kita memberi tahu JVM untuk memuat kelas dengan nama stringnya menggunakan Class.forName () atau ClassLoader.findSystemClass () atau metode ClassLoader.loadClass () dan kelas yang disebutkan tidak ditemukan di classpath.

Sebagian besar waktu, pengecualian ini terjadi ketika Anda mencoba menjalankan aplikasi tanpa memperbarui classpath dengan file JAR yang diperlukan. Sebagai Contoh, Anda mungkin telah melihat pengecualian ini ketika melakukan kode JDBC untuk terhubung ke database Anda yaituMySQL tetapi classpath Anda tidak memiliki JAR untuk itu.

Kesalahan NoClassDefFoundError terjadi ketika JVM mencoba memuat kelas tertentu yang merupakan bagian dari eksekusi kode Anda (sebagai bagian dari panggilan metode normal atau sebagai bagian dari pembuatan instance menggunakan kata kunci baru) dan kelas itu tidak ada di classpath Anda tetapi sebelumnya hadir pada waktu kompilasi karena untuk menjalankan program Anda, Anda perlu mengkompilasinya dan jika Anda mencoba menggunakan kelas yang tidak hadir, kompiler akan meningkatkan kesalahan kompilasi.

Di bawah ini adalah deskripsi singkat

masukkan deskripsi gambar di sini

Anda dapat membaca Semuanya Tentang ClassNotFoundException Vs NoClassDefFoundError untuk lebih jelasnya.

Naresh Joshi
sumber
0

Saya mengingatkan diri saya pada hal-hal berikut lagi dan lagi ketika saya perlu menyegarkan

ClassNotFoundException

Hirarki Kelas

ClassNotFoundException extends ReflectiveOperationException extends Exception extends Throwable

Saat debugging

  1. Wadah yang diperlukan, kelas tidak ada di classpath.
  2. Verifikasi semua guci yang diperlukan berada di classpath jvm.

NoClassDefFoundError

Hirarki Kelas

NoClassDefFoundError extends LinkageError  extends Error extends Throwable

Saat debugging

  1. Masalah dengan memuat kelas secara dinamis, yang dikompilasi dengan benar
  2. Masalah dengan blok statis, konstruktor, init () metode kelas dependen dan kesalahan aktual dibungkus oleh beberapa lapisan [terutama ketika Anda menggunakan pegas, hibernasi pengecualian aktual dibungkus dan Anda akan mendapatkan NoClassDefError]
  3. Saat Anda menghadapi "ClassNotFoundException" di bawah blok statis kelas dependen
  4. Masalah dengan versi kelas. Ini terjadi ketika Anda memiliki dua versi v1, v2 dari kelas yang sama di bawah jar yang berbeda / paket, yang dikompilasi berhasil menggunakan v1 dan v2 dimuat saat runtime yang tidak memiliki metode / vars yang relevan & Anda akan melihat pengecualian ini. [Saya pernah menyelesaikan masalah ini dengan menghapus duplikat dari kelas terkait log4j di bawah beberapa botol yang muncul di classpath]
Sankarganesh Eswaran
sumber
-1

ClassNotFoundException dan NoClassDefFoundError terjadi ketika kelas tertentu tidak ditemukan saat runtime. Namun, mereka terjadi pada skenario yang berbeda.

ClassNotFoundException adalah pengecualian yang terjadi ketika Anda mencoba memuat kelas pada waktu berjalan menggunakan metode Class.forName () atau loadClass () dan kelas yang disebutkan tidak ditemukan di classpath.

    public class MainClass
    {
        public static void main(String[] args)
        {
            try
            {
                Class.forName("oracle.jdbc.driver.OracleDriver");
            }catch (ClassNotFoundException e)
            {
                e.printStackTrace();
            }
        }
    }



    java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Unknown Source)
    at pack1.MainClass.main(MainClass.java:17)

NoClassDefFoundError adalah kesalahan yang terjadi ketika kelas tertentu hadir pada waktu kompilasi, tetapi hilang pada saat dijalankan.

    class A
    {
      // some code
    }
    public class B
    {
        public static void main(String[] args)
        {
            A a = new A();
        }
    }

Ketika Anda mengkompilasi program di atas, dua file .class akan dihasilkan. Satu adalah A.class dan satu lagi adalah B.class. Jika Anda menghapus file A.class dan menjalankan file B.class, Java Runtime System akan melempar NoClassDefFoundError seperti di bawah ini:

    Exception in thread "main" java.lang.NoClassDefFoundError: A
    at MainClass.main(MainClass.java:10)
    Caused by: java.lang.ClassNotFoundException: A
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
Neeraj Gahlawat
sumber