Jak rozwiązać ClassNotFoundException?


106

Próbuję uruchomić aplikację Java, ale pojawia się ten błąd:

java.lang.ClassNotFoundException:

Po dwukropku pojawia się lokalizacja brakującej klasy. Wiem jednak, że ta lokalizacja nie istnieje, ponieważ klasa znajduje się w innym miejscu. Jak mogę zaktualizować ścieżkę tej klasy? Czy ma to coś wspólnego ze ścieżką klasową?


1
Musisz dodać słoik z brakującą klasą do classptah
— Crom

jeśli twoja klasa ma pakiet, przejdź do folderu zawierającego klasę. np. jeśli pakiet to pakiet test.abc, przejdź do folderu przed testem, a następnie wykonaj java -cp. test.abc.CLASSNAME (bez .class). Jeśli nie ma pakietu, przejdź do folderu zawierającego klasę i powiedz java -cp. CLASSNAME
— opcjonalnie

Albo klasa nie została wdrożona w twoim środowisku wykonawczym (na przykład brakujący plik jar) lub klasa nie jest widoczna w danym programie ładującym klas, sprawdź to narzędzie, które pomaga rozwiązać te problemy: jhades.org
— Angular University

1
Czasami też na to wpadam. Ten wyjątek wyraźnie narusza zasadę podawania całego niezbędnego kontekstu w komunikacie o wyjątku. Powinien wspomnieć, gdzie próbował szukać rzeczy, co jest na twojej ścieżce klas. Proszę o lepsze komunikaty o wyjątkach. Nie każ nam szukać informacji, które mogą pomóc w rozwiązaniu problemu.
— masterxilo

Odpowiedzi:


32

Twoja ścieżka klas jest zepsuta (co jest bardzo częstym problemem w świecie Java).

W zależności od tego, jak uruchomisz aplikację, musisz zmienić argument -cp, wpis Class-Path w pliku MANIFEST.MF lub układ dysku.


34
Czy możesz bardziej szczegółowo określić zaćmienie? Co mam do zrobienia?
— user2426316

24
Twoje pytanie nie zawiera wystarczających informacji, aby udzielić bardziej szczegółowej odpowiedzi. Rozważ dodanie tego.
— Thorbjørn Ravn Andersen

Niedopasowanie rozwiązania zależności / wersji jest bardzo częstym problemem w praktycznie wszystkich środowiskach programistycznych. Moglibyśmy powiedzieć, że wszystko, co kiedykolwiek robi każdy program, rozwiązuje takie definicje ... zawsze pojawia się pytanie, co / gdzie jest definicja i którą wersję masz na myśli?
— masterxilo

2
Podkreślam tylko, że poza światem Javy całe oprogramowanie walczy o zapewnienie znalezienia prawidłowych wersji zależności. Mogę wspomnieć o dll-hell, menadżerach pakietów, menadżerach wersji, liście materiałów rozruchowych i kontenerach docker jako przykłady tego problemu i możliwych rozwiązań. Im większa część obcego kodu, tym większy problem.
— masterxilo

@masterxilo Tak, ale to niekoniecznie jest tutaj problemem i być może szczekasz na niewłaściwe drzewo. Można tylko powiedzieć, że ścieżka klas jest zepsuta.
— Thorbjørn Ravn Andersen

45

Ścieżka klas to lista lokalizacji, z których mają być ładowane klasy.

Te „lokalizacje” mogą być katalogami lub plikami jar.

W przypadku katalogów maszyna JVM będzie postępować zgodnie z oczekiwanym wzorcem ładowania klasy. Jeśli mam katalog C: / myproject / classes w mojej ścieżce klas i spróbuję załadować klasę com.mojafirma.Foo , w katalogu klas będzie szukać katalogu o nazwie com , a następnie w tym katalogu o nazwie mojafirma i w końcu będzie szukał pliku o nazwie Foo.class w tym katalogu.

W drugim przypadku, dla plików jar, przeszuka plik jar dla tej klasy. Plik jar jest w rzeczywistości po prostu spakowaną kolekcją katalogów, jak powyżej. Jeśli rozpakujesz plik jar, otrzymasz kilka katalogów i plików klas zgodnie z powyższym wzorcem.

Zatem maszyna JVM przemierza ścieżkę klasy od początku do końca, szukając definicji klasy, gdy próbuje załadować definicję klasy. Na przykład w ścieżce klas:

C: / mójproject / classes; C: /myproject/lib/stuff.jar; C: /myproject/lib/otherstuff.jar

JVM spróbuje najpierw przeszukać klasy katalogu , następnie stuff.jar, a na końcu otherstuff.jar .

Gdy otrzymasz ClassNotFoundException, oznacza to, że maszyna JVM przeszła przez całą ścieżkę klas i nie znalazła klasy, do której próbujesz się odwołać. Rozwiązaniem, jak to często bywa w świecie Java, jest sprawdzenie ścieżki klas.

Definiujesz ścieżkę klasy w wierszu poleceń, mówiąc java -cp, a następnie swoją ścieżkę klasy. W IDE, takim jak Eclipse, będziesz mieć opcję menu do określenia ścieżki klas.


13

To najlepsze rozwiązanie, jakie do tej pory znalazłem.

Załóżmy, że mamy pakiet o nazwie org.mypackagezawierający klasy:

  • HelloWorld (klasa główna)
  • SupportClass
  • UtilClass

a pliki definiujące ten pakiet są fizycznie przechowywane w katalogu D:\myprogram(w systemie Windows) lub /home/user/myprogram(w systemie Linux).

Struktura pliku będzie wyglądać następująco: wprowadź opis obrazu tutaj

Kiedy wzywamy Java, możemy określić nazwę aplikacji do uruchomienia: org.mypackage.HelloWorld. Jednak musimy również powiedzieć Javie, gdzie ma szukać plików i katalogów definiujących nasz pakiet. Aby więc uruchomić program, musimy użyć następującego polecenia: wprowadź opis obrazu tutaj

UWAGA: Musisz wykonać powyższe javapolecenie bez względu na twoje bieżące położenie. Ale tak nie jest javac. W celu kompilacji możesz nawet przejść bezpośrednio do katalogu, w którym masz swoje .javapliki i bezpośrednio wykonać javac ClassName.java.


6

Jeśli znasz ścieżkę klasy lub jar zawierający klasę, dodaj go do swojej ścieżki klas podczas jej uruchamiania. Możesz użyć ścieżki klas, jak wspomniano tutaj:

w systemie Windows

java -classpath .;yourjar.jar YourMainClass

w systemie UNIX / Linux

java -classpath .:yourjar.jar YourMainClass

4

Wypróbuj te, jeśli używasz maven. Używam maven do mojego projektu, a kiedy robię mvn clean installi próbuję uruchomić program, zgłasza wyjątek. Czyszczę projekt i uruchamiam go ponownie, a dla mnie działa.

Używam Eclipse IDE.

W przypadku wyjątku Nie znaleziono klasy podczas uruchamiania testu Junit spróbuj uruchomić mvn clean testraz. Skompiluje wszystkie klasy testowe.


w którym katalogu byłeś, kiedy wykonywałeś "mvn clean test"? czy jest w tym samym katalogu co POM?
— TacoB0t

1
Tak. Uruchomiono go z katalogu, w którym znajduje się plik pom.
— Arun

3

Aby dodać lokalizację klasy do ścieżki klas za pomocą wiersza poleceń, po prostu dodaj -cplub -classpathi lokalizację klasy podczas jej uruchamiania. TO ZNACZY

java -cp "c:/location/of/file" YourProgram

Lub jeśli używasz IDE, takiego jak eclipse, możesz kliknąć prawym przyciskiem myszy project -> build path -> configure build path i dodać zewnętrzny plik JAR zawierający twoją klasę do ścieżki budowania, wtedy powinno działać dobrze.


3

Posługiwać się ';' jako separator. Jeśli zmienne środowiskowe są ustawione poprawnie, powinieneś zobaczyć swoje ustawienia. Jeśli twoje PATH i CLASSPATH są poprawne, Windows powinien rozpoznać te polecenia. NIE musisz ponownie uruchamiać komputera podczas instalacji oprogramowania Java.


5
To jest w
— systemie

3

Dodaj pełną ścieżkę do pliku jar do CLASSPATH. W Linuksie użycia: export CLASSPATH=".:/full/path/to/file.jar:$CLASSPATH". Innym sposobem (bez edycji CLASSPATH) było rozpakowanie pliku jar w bieżącym folderze projektu.

Sposoby nie zadziałały dla mnie:

1) Użycie -cpopcji z pełną ścieżką do pliku jar.

2) Używanie -cptylko z nazwą jar, gdy znajduje się w bieżącym folderze

3) Kopiowanie jar do bieżącego folderu projektu

4) Kopiowanie pliku jar do standardowej lokalizacji plików jar java (/ usr / share / java)

To rozwiązanie jest raportowane dla klasy com.mysql.jdbc.Driver w mysql-connector-java.5 - *. Jar, działające na Linuksie z OpenJDK w wersji 1.7


Tylko rozpakowanie pliku JAR działało dla mnie, żadne inne rozwiązanie nie
— działało

2

Idź na górę i usuń instrukcję importu, jeśli istnieje, i ponownie zaimportuj klasę. Ale jeśli tak nie jest, zrób porządek, a następnie skompiluj. Czy używasz Netbeans czy Eclipse?


2

Wpadłem na to również i wypróbowałem wszystkie inne rozwiązania. Nie miałem pliku .class w folderze HTML, miałem tylko plik .java. Po dodaniu pliku .class program działał dobrze.


2
  1. Może się tak zdarzyć, jeśli ścieżka klas jest nieprawidłowa

  2. Załóżmy, że klasa możliwa do serializacji i klasa deserializowalna pod tą samą nazwą projektu. Uruchamiasz klasę możliwą do serializacji, tworząc obiekt możliwy do serializacji w określonym folderze. Teraz potrzebujesz zdesearializowanych danych. W międzyczasie, jeśli zmienisz nazwę projektu, to nie zadziała. Musisz najpierw uruchomić klasę możliwą do serializacji, a następnie zdeserializować plik.


2

Jeśli używasz mavena, spróbuj zaktualizować wszystkie projekty i wymusić tworzenie migawek. To również wyczyści i odbuduje całą ścieżkę klas. To rozwiązało mój problem.


2

właśnie zrobiłem

1. unieważnij pamięć podręczną i uruchom ponownie

2. Przebudowałem mój projekt, który rozwiązał problem


1

Próbowałem uruchomić .jar z kodu C # przy użyciu Processklasy. Kod java został pomyślnie uruchomiony z eclipse, ale nie pochodzi z C # Visual Studio, a nawet klikając bezpośrednio na plik jar, zawsze zatrzymywał się z ClassNotFoundException:wyjątkiem. Rozwiązaniem dla my, było wyeksportowanie programu java jako „Runnable JAR file” zamiast „JAR File”. Mam nadzieję, że to może komuś pomóc.


1

Może się to zdarzyć w systemie Windows po aktualizacji java, w której brakuje starej wersji java SDK, a jest obecna nowa. Chciałbym sprawdzić, czy twoje IDE używa zainstalowanej wersji java SDK (IntelliJ: CTRL + SHIFT + ALT + S)


1

Jeśli dodano wiele bibliotek (innych firm) ** i klasy aplikacji rozszerzeń **

Wtedy może się to zdarzyć.

W tym celu musisz ustawić multiDexEnabled truei zamienić swoją rozszerzoną Applicationklasę na MultiDexApplication.

To zostanie rozwiązane.


1

Podstawowe pytanie ogólne - najprostsza ogólna odpowiedź;)

Biorąc pod uwagę informacje, zakładam, że możesz wypróbować podstawowe podejście do kodowania, budowania / kompilowania i uruchamiania prostej aplikacji konsolowej, takiej jak „Hello World”, używając prostego edytora tekstu i powłoki poleceń.

Ten błąd występuje w następującym scenariuszu:

..\SomePath>javac HelloWorld.java
..\SomePath>java HelloWorld.class

Innymi słowy, użyj:

..\SomePath>java HelloWorld

PS Dodanie rozszerzenia pliku .class powoduje ten sam błąd. Upewnij się również, że folder bin Javy (JDK / JRE) znajduje się w ścieżce zmiennej środowiskowej systemu operacyjnego (Wyszukaj więcej szczegółów w innych postach na ten temat) PPS Czy moje założenie / a jest poprawne?


1

Jeśli używasz mavena, sprawdź, czy masz tę wtyczkę w pom.xml:

    <build>
        <plugins>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.2.0</version>
                <executions>
                    <!-- Attach the shade goal into the package phase -->
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

        </plugins>
    </build>

Umieści twoją zależność (powód wyjątku) w twoim słoiku.

FYI : będzie to obejmować wszystkie zależności zawyżone w ostatnim słoiku


Dodano @Archit.
— techkuz

0

W moim przypadku klasa wyrzucona jako wyjątek nie znaleziono klasy ma właściwości związane z certyfikatami ssl. Zamknij zaćmienie i otwórz za pomocą „Uruchom jako administrator”, a problem został rozwiązany. Ponieważ eclipse ma uprawnienia związane z wydaniem, zgłosi tego rodzaju wyjątek.


-8

Umieść cały kod w bloku try, a następnie złap wyjątek w bloku catch

try
{
    // code
}
catch(ClassNotFoundException e1)
{
    e1.getmessage();
}

5
Nie rozwiązuje to wyjątku. To ukrywa wyjątek. Co więcej, "e1.getmessage ()" to a) niewłaściwa wielkość liter w getMessage () ib) nie da zbyt wiele, ponieważ zwraca łańcuch z komunikatem, a ty go nie drukujesz, nie rejestrujesz ani nic!
— IBBoard
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.