Jakie są przyczyny i jakie są różnice między NoClassDefFoundError a ClassNotFoundException?

371

Jaka jest różnica między NoClassDefFoundErrori ClassNotFoundException?

Co powoduje ich wyrzucenie? Jak można je rozwiązać?

Często napotykam te rzuty podczas modyfikowania istniejącego kodu, aby zawierał nowe pliki jar. Uderzyłem je zarówno po stronie klienta, jak i po stronie serwera dla aplikacji Java dystrybuowanej za pośrednictwem WebStart.

Możliwe przyczyny, z którymi się zetknąłem:

  1. pakiety nie są zawarte build.xmlpo stronie klienta kodu
  2. brakuje ścieżki klas środowiska wykonawczego dla nowych używanych słoików
  3. wersja jest w konflikcie z poprzednim słoikiem

Kiedy spotykam je dzisiaj, stosuję podejście oparte na analizie błędów i błędów, aby wszystko działało. Potrzebuję więcej jasności i zrozumienia.

krisp
źródło
Często zdarza się, że uruchamianie JVM z -verbose(np. -verbose:class -verbose:jni) Pomaga - ale mogsie informuje poniżej ich odpowiedź, że nie zapewnia to żadnych dodatkowych użytecznych informacji :(
PJTraill

Odpowiedzi:

388

Różnica w stosunku do specyfikacji Java API jest następująca.

Dla ClassNotFoundException:

Zgłaszane, gdy aplikacja próbuje załadować klasę za pomocą nazwy swojego ciągu przy użyciu:

  • forNameMetoda w klasie Class.
  • findSystemClassMetoda w klasie ClassLoader.
  • loadClassMetoda w klasie ClassLoader.

ale nie można znaleźć definicji klasy o podanej nazwie.

Dla NoClassDefFoundError:

Zgłaszane, jeśli wirtualna maszyna Java lub ClassLoaderinstancja próbuje załadować definicję klasy (w ramach normalnego wywołania metody lub w ramach tworzenia nowej instancji za pomocą nowego wyrażenia) i nie można znaleźć definicji klasy.

Szukana definicja klasy istniała, gdy aktualnie wykonywana klasa została skompilowana, ale definicji nie można już znaleźć.

Wygląda więc na to, że NoClassDefFoundErrorwystępuje, gdy źródło zostało pomyślnie skompilowane, ale w czasie wykonywania classnie znaleziono wymaganych plików. Może się tak zdarzyć w dystrybucji lub produkcji plików JAR, w których nie wszystkie wymagane classpliki zostały uwzględnione.

Jak dla ClassNotFoundExceptionwydaje się, że może to wynikać z starając się odblaskowe połączeń do klas w czasie wykonywania, ale zajęcia program próbuje rozmowy jest nie istnieje.

Różnica między nimi polega na tym, że jeden jest drugim, Errora drugi jest Exception. Z NoClassDefFoundErrorjest Errori wynika z tego, że wirtualna maszyna Java ma problemy ze znalezieniem oczekiwanej klasy. Program, który miał działać w czasie kompilacji, nie może zostać uruchomiony z powodu braku classplików lub nie jest taki sam, jak został utworzony lub napotkany w czasie kompilacji. Jest to dość krytyczny błąd, ponieważ JVM nie może zainicjować programu.

Z drugiej strony ClassNotFoundExceptionjest to Exception, więc jest nieco oczekiwane i jest czymś, co można odzyskać. Używanie refleksji może być podatne na błędy (ponieważ istnieją pewne oczekiwania, że ​​rzeczy mogą nie pójść zgodnie z oczekiwaniami. Nie ma sprawdzania czasu kompilacji, aby sprawdzić, czy istnieją wszystkie wymagane klasy, więc wszelkie problemy ze znalezieniem pożądanych klas pojawią się w czasie wykonywania .

coobird
źródło
53
NoClassDefFoundErrorzwykle występuje, gdy występuje problem (zgłoszony wyjątek) z inicjalizacją bloku statycznego lub pól statycznych, więc klasy nie można pomyślnie zainicjować.
Dagang
7
głosować. jeden jest, Errora drugi jest Exception. :)
Ravi
83

ClassNotFoundException jest generowany, gdy zgłoszona klasa nie zostanie znaleziona przez ClassLoader. Zazwyczaj oznacza to brak klasy w CLASSPATH. Może to również oznaczać, że dana klasa próbuje zostać załadowana z innej klasy, która została załadowana do nadrzędnego modułu ładującego klasy, a zatem klasa z podrzędnego modułu ładującego klasy nie jest widoczna. Czasami ma to miejsce w przypadku pracy w bardziej złożonych środowiskach, takich jak serwer aplikacji (WebSphere jest niesławny z powodu takich problemów z modułem ładującym klasy).

Ludzie często mylą się java.lang.NoClassDefFoundErrorz tym, java.lang.ClassNotFoundExceptionże istnieje ważne rozróżnienie. Na przykład wyjątek (tak naprawdę błąd java.lang.NoClassDefFoundErrorjest podklasą java.lang.Error)

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

nie oznacza, że ​​klasy ActiveMQConnectionFactory nie ma w CLASSPATH. W rzeczywistości jest wręcz przeciwnie. Oznacza to, że klasa ActiveMQConnectionFactory została znaleziona przez ClassLoader, jednak podczas próby załadowania klasy wystąpił błąd podczas odczytu definicji klasy. Zwykle dzieje się tak, gdy dana klasa ma statyczne bloki lub elementy, które używają Klasy, która nie została znaleziona przez ClassLoader. Aby więc znaleźć winowajcę, przejrzyj źródło danej klasy (w tym przypadku ActiveMQConnectionFactory) i poszukaj kodu za pomocą bloków statycznych lub elementów statycznych. Jeśli nie masz dostępu do źródła, po prostu dekompiluj je za pomocą JAD.

Podczas sprawdzania kodu powiedz, że znajdujesz wiersz kodu jak poniżej, upewnij się, że klasa SomeClass znajduje się w Twojej CLASSPATH.

private static SomeClass foo = new SomeClass();

Wskazówka: aby dowiedzieć się, do którego słoika należy klasa, możesz skorzystać ze strony jarFinder. Pozwala to określić nazwę klasy za pomocą symboli wieloznacznych i wyszukuje klasę w bazie danych słoików. jarhoo pozwala robić to samo, ale nie jest już darmowy.

Jeśli chcesz zlokalizować słoik, do którego należy klasa w ścieżce lokalnej, możesz użyć narzędzia takiego jak jarscan ( http://www.inetfeedback.com/jarscan/ ). Po prostu określ klasę, którą chcesz zlokalizować, i ścieżkę do katalogu głównego, w której chcesz, aby zaczęła szukać klasy w słoikach i plikach zip.

Sanjiv Jivan
źródło
9
To zabawne, że to jest dokładnie poprawna odpowiedź, przegłosowana jako ostatnia. (Nawet -1 zanim głosowałem). ClassNotFoundException oznacza, że ​​CL nie widzi pliku .class. NoClassDefFoundError oznacza, że ​​plik .class jest tam, że nie można go załadować (prawdopodobnie błąd JNI).
user43685,
1
Czy ta odpowiedź nie jest sprzeczna z odpowiedzią z coobird?
zardosht
Próbowałem podobny przykład bloku statycznego. Moja klasa Class1 ma zmienną statyczną „private static B foo = new B ();” Po kompilacji usunąłem plik B.class z folderu bin. Teraz z głównej metody trzeciej klasy, kiedy tworzę obiekt klasy 1. Rror jest zgłaszany w następujący sposób: -------- "Wyjątek w wątku" main "java.lang.NoClassDefFoundError: spring / B" ........ Więc dokładnie wspomina, której klasy nie znalazł ieclass, do którego odnosi się blok statyczny, a nie klasa zewnętrzna, więc jest to sprzeczne z tą odpowiedzią.
Kaushik Lele,
+1 za wyjaśnienie dotyczące „nie oznacza, że ​​klasy ActiveMQConnectionFactory nie ma w CLASSPATH”
akila
35

NoClassDefFoundErrorjest zasadniczo błędem powiązania. Występuje, gdy próbujesz utworzyć instancję obiektu (statycznie z „nowym”) i nie można go znaleźć podczas kompilacji.

ClassNotFoundExceptionjest bardziej ogólny i stanowi wyjątek czasu wykonywania, gdy próbujesz użyć klasy, która nie istnieje. Na przykład, parametr w funkcji akceptuje interfejs i ktoś przechodzi do klasy, która implementuje ten interfejs, ale nie masz dostępu do klasy. Obejmuje również przypadki dynamicznego ładowania klas, takie jak używanie loadClass()lub Class.forName().

Cletus
źródło
29

NoClassDefFoundError (NCDFE) ma miejsce, gdy kod uruchamia „new Y ()” i nie może znaleźć klasy Y.

Być może po prostu brakuje Y w module ładującym klasy, jak sugerują inne komentarze, ale może być tak, że klasa Y nie jest podpisana lub ma nieprawidłowy podpis, lub że Y jest ładowany przez inny moduł ładujący klasy niewidoczny dla Twojego kodu lub nawet, że Y zależy od Z, którego nie można załadować z żadnego z powyższych powodów.

Jeśli tak się stanie, wówczas JVM zapamięta wynik ładowania X (NCDFE) i po prostu wyrzuci nowy NCDFE za każdym razem, gdy poprosisz o Y, bez podania przyczyny:

klasa A {
  klasa statyczna b {}
  public static void main (String args []) {
    System.out.println („Pierwsza próba nowa b ():”);
    spróbuj {new b (); } catch (Throwable t) {t.printStackTrace ();}
    System.out.println ("\ n Druga próba nowa b ():");
    spróbuj {new b (); } catch (Throwable t) {t.printStackTrace ();}
  }
}

zapisz gdzieś jako a.java

Kod po prostu próbuje dwa razy utworzyć nową klasę „b”, poza tym nie ma żadnych błędów i nic nie robi.

Skompiluj kod javac a.java, a następnie uruchom a, wywołując java -cp . a- powinien po prostu wydrukować dwa wiersze tekstu i powinien działać poprawnie bez błędów.

Następnie usuń plik „a $ b.class” (lub wypełnij go śmieciami lub skopiuj nad nim klasę a.class), aby zasymulować brakującą lub uszkodzoną klasę. Oto co się dzieje:

Pierwsza próba nowa b ():
java.lang.NoClassDefFoundError: a $ b
    o godz. (a.java:5)
Przyczyna: java.lang.ClassNotFoundException: a $ b
    na java.net.URLClassLoader $ 1.run (URLClassLoader.java:200)
    at java.security.AccessController.doPrivileged (metoda rodzima)
    at java.net.URLClassLoader.findClass (URLClassLoader.java:188)
    at java.lang.ClassLoader.loadClass (ClassLoader.java:307)
    at sun.misc.Launcher $ AppClassLoader.loadClass (Launcher.java:301)
    at java.lang.ClassLoader.loadClass (ClassLoader.java:252)
    at java.lang.ClassLoader.loadClassInternal (ClassLoader.java:320)
    ... jeszcze 1

Druga próba nowa b ():
java.lang.NoClassDefFoundError: a $ b
    o godz. (a.java:7)

Pierwsze wywołanie powoduje wyjątek ClassNotFoundException (generowany przez moduł ładujący klasy, gdy nie może znaleźć klasy), który musi być zawinięty w niezaznaczone NoClassDefFoundError, ponieważ kod, o którym mowa ( new b()) powinien po prostu działać.

Druga próba oczywiście również się nie powiedzie, ale jak widać zawinięty wyjątek już nie istnieje, ponieważ ClassLoader wydaje się pamiętać, że nie udało się załadować klas. Widzisz tylko NCDFE bez absolutnie żadnego pojęcia, co tak naprawdę się wydarzyło.

Więc jeśli kiedykolwiek zobaczysz NCDFE bez podstawowej przyczyny, musisz sprawdzić, czy możesz prześledzić do pierwszego załadowania klasy, aby znaleźć przyczynę błędu.

mogsie
źródło
Co z uruchomieniem maszyny JVM z -verbosejakąś podobną opcją w zależności od konkretnej maszyny JVM? Prawdopodobnie -verbose:classmoże -verbose:class:jniprzy użyciu JNI, ale nie jestem pewien co do składni. Jeśli jest to przydatne, być może możesz pokazać wyniki.
PJTraill,
Ani -verbose:classnie -verbose:jniprzekazuj żadnych dodatkowych danych wyjściowych dotyczących brakującej klasy.
mogsie
1
Dzięki za wypróbowanie, nawet jeśli wynik jest rozczarowujący. (PS Od tego czasu dowiedziałem się, że -verbose:class:jnijest źle: trzeba określić dwie osobne opcje -verbose:class -verbose:jni
:.
2
Ostatnie zdanie * 1 000 000: Jeśli kiedykolwiek zobaczysz NCDFE bez podstawowej przyczyny, musisz sprawdzić, czy możesz prześledzić do pierwszego załadowania klasy, aby znaleźć przyczynę błędu.
batwad
20

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

ClassNotFoundException: występuje, gdy moduł ładujący klasy nie może znaleźć wymaganej klasy na ścieżce klasy. Zasadniczo powinieneś sprawdzić ścieżkę swojej klasy i dodać klasę do ścieżki klasy.

NoClassDefFoundError: trudniej jest debugować i znaleźć przyczynę. Jest to generowane, gdy w czasie kompilacji obecne są wymagane klasy, ale w czasie wykonywania klasy są zmieniane lub usuwane lub statyczna inicjalizacja klasy generuje wyjątki. Oznacza to, że ładowana klasa jest obecna w ścieżce klas, ale jedna z klas wymaganych przez tę klasę została usunięta lub nie można jej załadować przez kompilator. Powinieneś zobaczyć klasy zależne od tej klasy.

Przykład :

public class Test1
{
}


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

}

Teraz po skompilowaniu obu klas, jeśli usuniesz plik Test1.class i uruchomisz klasę testową, to rzuci

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: generowany, gdy aplikacja próbuje załadować klasę poprzez swoją nazwę, ale nie można znaleźć definicji klasy o podanej nazwie.

NoClassDefFoundError: wyrzucany, jeśli wirtualna maszyna Java próbuje załadować definicję klasy i nie można znaleźć definicji klasy.

KingFeming
źródło
Co z uruchomieniem maszyny JVM z -verbosejakąś podobną opcją w zależności od konkretnej maszyny JVM? Prawdopodobnie -verbose:classmoże -verbose:class:jniprzy użyciu JNI, ale nie jestem pewien co do składni.
PJTraill,
-verbose:class:jnijest źle, ale można przejść dwie oddzielne opcje: -verbose:class -verbose:jni.
PJTraill,
15

Jaki jest powód, dla którego każdy z nich i jakikolwiek proces przemyślenia, jak radzić sobie z takimi błędami?

Są blisko spokrewnieni. Zgłaszane ClassNotFoundExceptionjest, gdy Java szukała określonej klasy według nazwy i nie mogła jej pomyślnie załadować. NoClassDefFoundErrorJest generowany, gdy Java poszedł szuka klasy, która była związana do jakiegoś istniejącego kodu, ale nie mógł znaleźć dla jednej lub innego powodu (np błędne ścieżki klasy, zła wersja Java, niewłaściwej wersji biblioteki) i jest dokładnie śmiertelne ponieważ wskazuje, że coś poszło nie tak.

Jeśli masz tło C, CNFE jest jak awaria dlopen()/ dlsym()a NCDFE stanowi problem z łącznikiem; w drugim przypadku odnośne pliki klas nigdy nie powinny były zostać skompilowane w konfiguracji, w której próbujesz ich użyć.

Donal Fellows
źródło
11

Przykład 1:

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

Jeśli com/example/Class1nie istnieje w żadnej z klas, to rzuca ClassNotFoundException.

Przykład 2:

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

Jeśli com/example/Class2istniał podczas kompilacji B, ale nie został znaleziony podczas wykonywania, to rzuca NoClassDefFoundError.

Oba są wyjątkami czasu wykonywania.

Dinesh
źródło
9

ClassNotFoundException jest generowany, gdy następuje próba załadowania klasy przez odwołanie do niej za pomocą ciągu znaków. Na przykład parametr to w Class.forName () jest ciągiem, co podnosi potencjał przekazywania niepoprawnych nazw binarnych do modułu ładującego klasy.

ClassNotFoundException jest zgłaszany, gdy napotkamy potencjalnie niepoprawną nazwę binarną; na przykład, jeśli nazwa klasy ma znak „/”, musisz uzyskać wyjątek ClassNotFoundException. Jest także generowany, gdy bezpośrednio odwoływana klasa nie jest dostępna w ścieżce klasy.

Z drugiej strony generowany jest NoClassDefFoundError

  • gdy rzeczywista fizyczna reprezentacja klasy - plik .class jest niedostępny,
  • lub klasa została już załadowana w innym module ładującym (zwykle moduł ładujący nadrzędny załadowałby klasę, a zatem klasy nie można załadować ponownie),
  • lub jeśli znaleziono niezgodną definicję klasy - nazwa w pliku klasy nie jest zgodna z żądaną nazwą,
  • lub (co najważniejsze), jeśli nie można zlokalizować i załadować klasy zależnej. W takim przypadku klasa bezpośrednio przywołana mogła zostać zlokalizowana i załadowana, ale klasa zależna jest niedostępna lub nie można jej załadować. Jest to scenariusz, w którym bezpośrednio przywołaną klasę można załadować za pomocą Class.forName lub równoważnych metod. Wskazuje to na awarię połączenia.

Krótko mówiąc, NoClassDefFoundError jest zwykle generowany przez nowe () instrukcje lub wywołania metod, które ładują wcześniej nieobecną klasę (w przeciwieństwie do łańcuchowego ładowania klas dla ClassNotFoundException), gdy moduł ładujący klasy nie jest w stanie znaleźć lub załadować definicji klasy ( s).

Ostatecznie do implementacji ClassLoader należy zgłoszenie wystąpienia wyjątku ClassNotFoundException, gdy nie można załadować klasy. Wykonuje to większość niestandardowych implementacji modułu ładującego klasy, ponieważ rozszerzają one URLClassLoader. Zazwyczaj moduły ładujące klasy nie rzucają jawnie NoClassDefFoundError na żadną implementację metody - ten wyjątek jest zwykle zgłaszany z maszyny JVM w kompilatorze HotSpot, a nie przez sam moduł ładujący klasy.

Vineet Reynolds
źródło
Głosuj za wzmianką „nazwa w pliku klasy nie odpowiada żądanej nazwie”. To dość powszechna przyczyna.
Markiz Lorne
8

Różnica między ClassNotFoundException Vs NoClassDefFoundError

wprowadź opis zdjęcia tutaj

Lawakush Kurmi
źródło
Nie krystalicznie czysty. „Brak aktualizacji w ścieżce klas” jest niejasny / nieprecyzyjny. Chodzi o to, czy plik JAR nie jest obecny w ścieżce klasy, albo zła wersja pliku JAR w ścieżce klasy. I błędy ortograficzne. I (westchnienie), ponieważ opublikowałeś swoje informacje jako fajną grafikę, nie możemy tego naprawić.
Stephen C
8

Za pomocą samych nazw możemy łatwo zidentyfikować jedną z nich, Exceptiona drugą z nich Error.

Wyjątek: wyjątki występują podczas wykonywania programu. Programista może obsłużyć te wyjątki, próbując złapać blok. Mamy dwa rodzaje wyjątków. Sprawdzono wyjątek, który zgłasza się w czasie kompilacji. Wyjątki czasu wykonywania zgłaszane w czasie wykonywania, wyjątki te zwykle występują z powodu złego programowania.

Błąd: W ogóle nie są to wyjątki, wykracza to poza zakres programisty. Błędy te są zwykle zgłaszane przez JVM.


wprowadź opis zdjęcia tutaj Źródło obrazu

Różnica:

Klasa nie znaleziono wyjątku:

  • Klasa ładowarka nie trafia do sprawdzenia kodu bajtowego klasy wspominaliśmy w fazie link z klasa obciążenia podsystemu otrzymujemy ClassNotFoundException.
  • ClassNotFoundExceptionto sprawdzony wyjątek wywodzący się bezpośrednio z java.lang.Exceptionklasy i należy dla niego zapewnić jawną obsługę
  • ClassNotFoundExceptionpojawia się, gdy następuje jawne załadowanie klasy poprzez podanie nazwy klasy w czasie wykonywania przy użyciu ClassLoader.loadClass (), Class.forName () i ClassLoader.findSystemClass ().

NoClassDefFoundError:

  • Klasa ładowarka nie trafia do rozwiązywania odniesienia klasy w fazie link z klasa obciążenia podsystemu otrzymujemy NoClassDefFoundError.
  • NoClassDefFoundErrorjest błędem wywodzącym się z LinkageErrorklasy, który służy do wskazywania przypadków błędów, w których klasa jest zależna od innej klasy, a klasa ta zmieniła się niekompatybilnie po kompilacji.
  • NoClassDefFoundErrorjest wynikiem niejawnego ładowania klasy z powodu wywołania metody z tej klasy lub dowolnego dostępu do zmiennej.

Podobieństwa:

  • Zarówno NoClassDefFoundErrori ClassNotFoundExceptionsą związane z niedostępnością klasy w czasie wykonywania.
  • Zarówno ClassNotFoundExceptioni NoClassDefFoundErrorzwiązane są ścieżki klasy Java.
Premraj
źródło
3

Biorąc pod uwagę działania sussystem modułu ładującego klasy:

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

To jest artykuł, który bardzo pomógł mi zrozumieć różnicę: http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html

Jeśli podczas ładowania klasy wystąpi błąd, wówczas instancja podklasy LinkageError musi zostać zgłoszona w punkcie programu, który (bezpośrednio lub pośrednio) korzysta z ładowanej klasy lub interfejsu.

Jeśli wirtualna maszyna Java kiedykolwiek spróbuje załadować klasę C podczas weryfikacji (§5.4.1) lub rozwiązania (§5.4.3) (ale nie inicjalizacji (§5.5)), a moduł ładujący klasy, który jest używany do inicjowania ładowania C zgłasza wystąpienie ClassNotFoundException , następnie wirtualna maszyna Java musi zgłosić wystąpienie NoClassDefFoundError, którego przyczyną jest wystąpienie ClassNotFoundException .

Zatem wyjątek ClassNotFoundException jest podstawową przyczyną NoClassDefFoundError .
A NoClassDefFoundError jest szczególnym przypadkiem błędu ładowania typu, który występuje na etapie łączenia .

Anton Shchastnyi
źródło
2

Dodaj jeden możliwy powód w praktyce:

  • ClassNotFoundException: jak powiedział cletus, używasz interfejsu, gdy odziedziczona klasa interfejsu nie znajduje się w ścieżce klasy. Na przykład wzorzec dostawcy usług (lub lokalizator usług ) próbuje zlokalizować nieistniejącą klasę
  • NoClassDefFoundError: znaleziono daną klasę, a nie znaleziono zależności danej klasy

W praktyce błąd może być rzucany w ciszy , np. Przesyłasz zadanie czasomierza, aw zadaniu czasomierza wyrzuca błąd , podczas gdy w większości przypadków twój program tylko przechwytuje wyjątek . Następnie główna pętla timera kończy się bez żadnych informacji. Podobny błąd do NoClassDefFoundError to ExceptionInInitializerError , gdy inicjator statyczny lub inicjator zmiennej statycznej zgłasza wyjątek.

leef
źródło
1

ClassNotFoundException to sprawdzony wyjątek, który występuje, gdy mówimy JVM, aby załadowała klasę za pomocą nazwy swojego ciągu przy użyciu metod Class.forName () lub ClassLoader.findSystemClass () lub ClassLoader.loadClass () i wspomniana klasa nie została znaleziona w ścieżce klasy.

W większości przypadków ten wyjątek występuje podczas próby uruchomienia aplikacji bez aktualizacji ścieżki klasy wymaganymi plikami JAR. Na przykład ten wyjątek mógł występować podczas wykonywania kodu JDBC w celu połączenia się z bazą danych, tj. MySQL, ale ścieżka klasy nie ma dla niego pliku JAR.

Błąd NoClassDefFoundError występuje, gdy JVM próbuje załadować określoną klasę, która jest częścią wykonania kodu (w ramach normalnego wywołania metody lub w ramach tworzenia instancji przy użyciu nowego słowa kluczowego), a klasa ta nie jest obecna w ścieżce klasy, ale była obecny w czasie kompilacji, ponieważ aby uruchomić program, musisz go skompilować, a jeśli próbujesz użyć klasy, która nie jest obecna, kompilator zgłosi błąd kompilacji.

Poniżej znajduje się krótki opis

wprowadź opis zdjęcia tutaj

Możesz przeczytać Wszystko o ClassNotFoundException Vs NoClassDefFoundError, aby uzyskać więcej informacji.

Naresh Joshi
źródło
0

Powtarzam sobie raz po raz, kiedy muszę odświeżyć

Klasa nie znaleziono wyjątku

Hierarchia klas

ClassNotFoundException extends ReflectiveOperationException extends Exception extends Throwable

Podczas debugowania

  1. Wymagany słoik, brakuje klasy w ścieżce klasy.
  2. Sprawdź, czy wszystkie wymagane słoiki znajdują się w ścieżce klas jvm.

NoClassDefFoundError

Hierarchia klas

NoClassDefFoundError extends LinkageError  extends Error extends Throwable

Podczas debugowania

  1. Problem z dynamicznym ładowaniem klasy, która została poprawnie skompilowana
  2. Problem z blokami statycznymi, konstruktorami, metodami init () klasy zależnej, a rzeczywisty błąd jest zawijany przez wiele warstw [szczególnie gdy używasz sprężyny, hibernacja faktyczny wyjątek jest zawijany i otrzymasz NoClassDefError]
  3. Gdy napotkasz „ClassNotFoundException” pod statycznym blokiem klasy zależnej
  4. Problem z wersjami klasy. Dzieje się tak, gdy masz dwie wersje v1, v2 tej samej klasy w różnych słoikach / pakietach, które zostały pomyślnie skompilowane przy użyciu v1, a v2 jest ładowane w czasie wykonywania, który nie ma odpowiednich metod / vars i zobaczysz ten wyjątek. [Raz rozwiązałem ten problem, usuwając duplikat klasy pokrewnej log4j w wielu słoikach, które pojawiły się w ścieżce klasy]
Sankarganesh Eswaran
źródło
-1

ClassNotFoundException i NoClassDefFoundError występują, gdy konkretna klasa nie zostanie znaleziona w czasie wykonywania, jednak występują one w różnych scenariuszach.

ClassNotFoundException to wyjątek występujący podczas próby załadowania klasy w czasie wykonywania przy użyciu metod Class.forName () lub loadClass (), a wspomnianych klas nie można znaleźć w ścieżce klasy.

    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 to błąd występujący, gdy dana klasa jest obecna w czasie kompilacji, ale jej brakowało w czasie wykonywania.

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

Podczas kompilacji powyższego programu zostaną wygenerowane dwa pliki .class. Jeden to A.class, a drugi to B.class. Jeśli usuniesz plik A.class i uruchomisz plik B.class, Java Runtime System wyrzuci NoClassDefFoundError jak poniżej:

    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
źródło