NoClassDefFoundError (NCDFE) xảy ra khi mã của bạn chạy "new Y ()" và nó không thể tìm thấy lớp Y.
Có thể đơn giản là Y bị thiếu trong trình tải lớp của bạn như các bình luận khác đề xuất, nhưng có thể là lớp Y không được ký hoặc có chữ ký không hợp lệ hoặc Y được tải bởi một trình nạp lớp khác không hiển thị với mã của bạn hoặc thậm chí Y phụ thuộc vào Z không thể được tải vì bất kỳ lý do nào ở trên.
Nếu điều này xảy ra, thì JVM sẽ ghi nhớ kết quả của việc tải X (NCDFE) và nó sẽ chỉ ném một NCDFE mới mỗi khi bạn yêu cầu Y mà không cho bạn biết lý do:
lớp một {
lớp tĩnh b {}
public static void main (String args []) {
System.out.println ("Lần thử đầu tiên mới b ():");
thử {mới b (); } bắt (Có thể ném t) {t.printStackTrace ();}
System.out.println ("\ nSecond thử mới b ():");
thử {mới b (); } bắt (Có thể ném t) {t.printStackTrace ();}
}
}
lưu cái này dưới dạng a.java ở đâu đó
Mã chỉ đơn giản là cố gắng khởi tạo một lớp "b" mới hai lần, ngoài ra, nó không có bất kỳ lỗi nào và nó không làm gì cả.
Biên dịch mã với javac a.java
, sau đó chạy a bằng cách gọi java -cp . a
- nó chỉ cần in ra hai dòng văn bản và nó sẽ chạy tốt mà không có lỗi.
Sau đó xóa tệp "a $ b. Class" (hoặc lấp đầy nó bằng rác hoặc sao chép a. Class qua nó) để mô phỏng lớp bị thiếu hoặc bị hỏng. Đây là những gì xảy ra:
Lần đầu tiên thử b () mới:
java.lang.NoClassDefFoundError: a $ b
tại a.main (a.java giáp)
Nguyên nhân bởi: java.lang.ClassNotFoundException: a $ b
tại java.net.URLClassLoader $ 1.run (URLClassLoader.java:200)
tại java.security.AccessControll.doPriv đặc biệt (Phương thức gốc)
tại java.net.URLClassLoader.findClass (URLClassLoader.java:188)
tại java.lang.ClassLoader.loadClass (ClassLoader.java:307)
tại sun.misc.Launcher $ AppClassLoader.loadClass (Launcher.java:602)
tại java.lang.ClassLoader.loadClass (ClassLoader.java:252)
tại java.lang.ClassLoader.loadClassI Internalal (ClassLoader.java:320)
... 1 nữa
Lần thử thứ hai mới b ():
java.lang.NoClassDefFoundError: a $ b
tại a.main (a.java:7)
Lệnh gọi đầu tiên dẫn đến ClassNotFoundException (được trình tải lớp ném khi nó không thể tìm thấy lớp), phải được bọc trong một NoClassDefFoundError không được kiểm tra, vì mã trong câu hỏi ( new b()
) sẽ chỉ hoạt động.
Lần thử thứ hai tất nhiên cũng sẽ thất bại, nhưng như bạn có thể thấy ngoại lệ được bao bọc không còn nữa, bởi vì ClassLoader dường như nhớ các trình nạp lớp không thành công. Bạn chỉ thấy NCDFE hoàn toàn không có manh mối gì về những gì thực sự đã xảy ra.
Vì vậy, nếu bạn từng thấy một NCDFE không có nguyên nhân gốc, bạn cần xem liệu bạn có thể theo dõi lại lần đầu tiên lớp được tải để tìm nguyên nhân gây ra lỗi không.
-verbose
(ví dụ-verbose:class -verbose:jni
) giúp - nhưng mogsie báo cáo bên dưới câu trả lời của họ rằng điều này không cung cấp thêm thông tin hữu ích nào :(