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ą?

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

Thorbjørn Ravn Andersen
źródło
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.

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

Ram Patra
źródło
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
Juned Ahsan
źródło
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.

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

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

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

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

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

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

Omar Faroque Anik
źródło
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.

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

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

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

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

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

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

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

Shaik Elias
źródło
-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();
}
sharukh
źródło
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