Co oznacza „Nie można znaleźć lub załadować głównej klasy”?
1370
Częstym problemem występującym u nowych programistów Java jest to, że ich programy nie działają z komunikatem o błędzie: Could not find or load main class ...
Należy pamiętać, że jest to pytanie „samo-odpowiedzi”, które ma być ogólną referencją dla nowych użytkowników Java. Nie mogłem znaleźć istniejącego pytania i odpowiedzi, które odpowiednio to obejmuje (IMO).
Stephen C
Odpowiedzi:
1230
java <class-name>Składnia polecenia
Przede wszystkim musisz zrozumieć prawidłowy sposób uruchamiania programu za pomocą polecenia java(lub javaw).
Normalna składnia 1 jest następująca:
java [<options>]<class-name>[<arg>...]
gdzie <option>jest opcją wiersza poleceń (zaczynającą się od znaku „-”), <class-name>jest w pełni kwalifikowaną nazwą klasy Java i <arg>jest dowolnym argumentem wiersza poleceń przekazywanym do aplikacji.
1 - Istnieje kilka innych składni opisanych na końcu tej odpowiedzi.
W pełni kwalifikowana nazwa (FQN) dla klasy jest tradycyjnie zapisywana tak jak w kodzie źródłowym Java; na przykład
packagename.packagename2.packagename3.ClassName
Jednak niektóre wersje javapolecenia pozwalają używać ukośników zamiast kropek; na przykład
packagename/packagename2/packagename3/ClassName
który (myląco) wygląda jak ścieżka do pliku, ale nie jest nim. Zwróć uwagę, że termin w pełni kwalifikowana nazwa jest standardową terminologią Java ... a nie czymś, co właśnie wymyśliłem, aby cię zdezorientować :-)
Oto przykład, jak javapowinno wyglądać polecenie:
java -Xmx100m com.acme.example.ListUsers fred joe bert
Powyższe spowoduje, że javapolecenie wykona następujące czynności:
Wyszukaj skompilowaną wersję com.acme.example.ListUsersklasy.
Załaduj klasę.
Sprawdź, czy klasa ma mainmetodę z podpisem , typem zwrotu i modyfikatorami podanymi przez public static void main(String[]). (Uwaga: nazwa argumentu metody NIE jest częścią podpisu).
Wywołaj tę metodę, przekazując jej argumenty wiersza poleceń („fred”, „joe”, „bert”) jako String[].
Powody, dla których Java nie może znaleźć klasy
Gdy pojawi się komunikat „Nie można znaleźć lub załadować głównej klasy ...”, oznacza to, że pierwszy krok nie powiódł się. javaPolecenie nie był w stanie znaleźć klasę. I rzeczywiście, „...” w wiadomości będzie w pełni kwalifikowaną nazwą klasy, której javaszuka.
Dlaczego więc nie może znaleźć klasy?
Powód 1 - popełniłeś błąd przy argumencie nazwy klasy
Pierwszą prawdopodobną przyczyną jest podanie niewłaściwej nazwy klasy. (Lub ... właściwa nazwa klasy, ale w złej formie.) Biorąc pod uwagę powyższy przykład, oto wiele niewłaściwych sposobów określania nazwy klasy:
Przykład 1 - prosta nazwa klasy:
java ListUser
Gdy klasa jest zadeklarowana w pakiecie takim jak np. com.acme.example, Musisz użyć pełnej nazwy klasy wraz z nazwą pakietu w javapoleceniu; na przykład
java com.acme.example.ListUser
Przykład # 2 - nazwa pliku lub ścieżka zamiast nazwy klasy:
Przykład # 5 - nazwa pliku źródłowego (oprócz Java 11 lub nowszego; patrz poniżej)
java ListUser.java
Przykład # 6 - całkowicie zapomniałeś nazwy klasy
java lots of arguments
Powód # 2 - ścieżka klasy aplikacji jest niepoprawnie określona
Drugą prawdopodobną przyczyną jest to, że nazwa klasy jest poprawna, ale javapolecenie nie może znaleźć klasy. Aby to zrozumieć, musisz zrozumieć pojęcie „ścieżki klas”. Wyjaśnia to dobrze dokumentacja Oracle:
Więc ... jeśli poprawnie podałeś nazwę klasy, następną rzeczą do sprawdzenia jest poprawne określenie ścieżki klas:
Przeczytaj trzy dokumenty połączone powyżej. (Tak ... PRZECZYTAJ je! Ważne jest, aby programista Java zrozumiał przynajmniej podstawy działania mechanizmów ścieżki klas Java).
Spójrz na wiersz poleceń i / lub zmienną środowiskową CLASSPATH, która obowiązuje po uruchomieniu javapolecenia. Sprawdź, czy nazwy katalogów i nazwy plików JAR są poprawne.
Jeśli w ścieżce klasy znajdują się względne ścieżki, sprawdź, czy poprawnie rozwiązują ... z bieżącego katalogu, który obowiązuje po uruchomieniu javapolecenia.
Sprawdź, czy klasa (wymieniona w komunikacie o błędzie) może znajdować się w efektywnej ścieżce klasy.
Zauważ, że składnia ścieżki klas jest inna dla Windows niż Linux i Mac OS. (Separator ścieżek klas znajduje się ;w systemie Windows i :innych. Jeśli użyjesz niewłaściwego separatora dla swojej platformy, nie otrzymasz wyraźnego komunikatu o błędzie. Zamiast tego otrzymasz ścieżkę, która nie istnieje, w ścieżce, która zostanie po cichu zignorowana .)
Powód # 2a - niewłaściwy katalog znajduje się w ścieżce klasy
Gdy umieścisz katalog w ścieżce klas, teoretycznie odpowiada on katalogowi głównemu kwalifikowanej przestrzeni nazw. Klasy znajdują się w strukturze katalogów poniżej tego katalogu głównego, poprzez mapowanie w pełni kwalifikowanej nazwy na nazwę ścieżki . Na przykład, jeśli „/ usr / local / acme / klas” znajduje się na ścieżce klasy, to kiedy JVM szuka klasy o nazwie com.acme.example.Foon, będzie szukał pliku „.class” o tej nazwie ścieżki:
Jeśli umieściłeś „/ usr / local / acme / klas / com / acme / example” na ścieżce klasy, JVM nie byłby w stanie znaleźć klasy.
Powód # 2b - ścieżka podkatalogu nie zgadza się z FQN
Jeśli FQN twoich klas com.acme.example.Foon, to JVM będzie szukać „Foon.class” w katalogu „com / acme / example”:
Jeśli struktura katalogów nie odpowiada nazwie pakietu zgodnie z powyższym wzorcem, JVM nie znajdzie twojej klasy.
Jeśli spróbujesz zmienić nazwę klasy, przenosząc ją, to również się nie powiedzie ... ale wyjątek stacktrace będzie inny. Można powiedzieć coś takiego:
ponieważ nazwa FQN w pliku klasy nie zgadza się z tym, czego oczekuje moduł ładujący klasy.
Podając konkretny przykład, załóżmy, że:
chcesz prowadzić com.acme.example.Foonklasę,
pełna ścieżka pliku jest /usr/local/acme/classes/com/acme/example/Foon.class,
Twój bieżący katalog roboczy jest /usr/local/acme/classes/com/acme/example/,
następnie:
# wrong, FQN is needed
java Foon# wrong, there is no `com/acme/example` folder in the current working directory
java com.acme.example.Foon# wrong, similar to above
java -classpath . com.acme.example.Foon# fine; relative classpath set
java -classpath ../../.. com.acme.example.Foon# fine; absolute classpath set
java -classpath /usr/local/acme/classes com.acme.example.Foon
Uwagi:
-classpathOpcja może być skrócony do -cpwiększości wydań Java. Sprawdź odpowiednie wpisy dla manualnych java, javaci tak dalej.
Zastanów się, wybierając między ścieżkami bezwzględnymi i względnymi. Pamiętaj, że względna nazwa ścieżki może „ulec uszkodzeniu”, jeśli zmieni się bieżący katalog.
Powód # 2c - brak zależności w ścieżce klasy
Ścieżka klasy musi zawierać wszystkie inne (niesystemowe) klasy, od których zależy twoja aplikacja. (Klasy systemowe są lokalizowane automatycznie i rzadko trzeba się tym zajmować.) Aby klasa główna poprawnie się załadowała, JVM musi znaleźć:
wszystkie klasy i interfejsy, do których odwołuje się deklaracja zmiennej lub zmiennej, lub wywołanie metody lub wyrażenie dostępu do pola.
(Uwaga: specyfikacje JLS i JVM pozwalają JVM na pewien zakres ładowania klas „leniwie”, co może mieć wpływ, gdy zostanie zgłoszony wyjątek programu ładującego klasy.)
Powód 3 - klasa została zadeklarowana w niewłaściwym pakiecie
Czasami zdarza się, że ktoś umieszcza plik kodu źródłowego w niewłaściwym folderze w drzewie kodu źródłowego lub pomija packagedeklarację. Jeśli zrobisz to w środowisku IDE, kompilator IDE natychmiast o tym powie. Podobnie, jeśli używasz przyzwoitego narzędzia do budowania Java, narzędzie będzie działać javacw sposób, który wykryje problem. Jeśli jednak zbudujesz kod Java ręcznie, możesz to zrobić w taki sposób, aby kompilator nie zauważył problemu, a wynikowy plik „.class” nie znajduje się w miejscu, w którym się spodziewasz.
Nadal nie możesz znaleźć problemu?
Jest wiele rzeczy do sprawdzenia i łatwo coś przeoczyć. Spróbuj dodać -Xdiagopcję do javawiersza poleceń (jako pierwszą rzecz po java). Wyprowadzi różne rzeczy na temat ładowania klas, a to może dać ci wskazówki co do prawdziwego problemu.
Weź również pod uwagę możliwe problemy związane z kopiowaniem i wklejaniem niewidocznych znaków spoza ASCII ze stron internetowych, dokumentów itp. I rozważmy „homoglify”, gdyby dwie litery lub symbole wyglądały tak samo… ale nie są.
Wreszcie, najwyraźniej możesz napotkać ten problem, jeśli spróbujesz uruchomić z pliku JAR z niepoprawnymi podpisami (META-INF/*.SF).
Alternatywne składnie dla java
Istnieją trzy alternatywne składnie do uruchamiania programów Java za pomocą java command.
1) Składnia używana do uruchamiania „wykonywalnego” pliku JAR jest następująca:
java [<options>]-jar <jar-file-name>[<arg>...]
na przykład
java -Xmx100m-jar /usr/local/acme-example/listuser.jar fred
Nazwa klasy punktu wejścia (tj. com.acme.example.ListUser) I ścieżka klasy są określone w pliku MANIFEST pliku JAR.
2) Składnia do uruchamiania aplikacji z modułu (Java 9 i nowsze) jest następująca:
Nazwa klasy punktu wejścia jest albo zdefiniowana przez <module>siebie, albo jest podana opcjonalnie <mainclass>.
3) Począwszy od Java 11, możesz skompilować i uruchomić pojedynczy plik kodu źródłowego i uruchomić go z następującą składnią:
java [<options>]<sourcefile>[<arg>...]
gdzie jest (zazwyczaj) plik z przyrostkiem „.java”.
Aby uzyskać więcej informacji, zapoznaj się z oficjalną dokumentacją javapolecenia używanej wersji Java.
IDE
Typowe środowisko Java IDE obsługuje obsługę aplikacji Java w samej maszynie JVM IDE lub w podrzędnej maszynie JVM. Na ogół są one odporne na ten szczególny wyjątek, ponieważ IDE używa własnych mechanizmów do konstruowania ścieżki klas środowiska wykonawczego, identyfikacji głównej klasy i utworzenia javawiersza poleceń.
Jednak nadal jest możliwe wystąpienie tego wyjątku, jeśli wykonasz czynności za zapleczem IDE. Na przykład, jeśli wcześniej skonfigurowałeś program uruchamiający aplikację dla aplikacji Java w Eclipse, a następnie przeniosłeś plik JAR zawierający klasę „main” w inne miejsce w systemie plików bez informowania Eclipse , Eclipse nieświadomie uruchomiłby JVM z niepoprawną ścieżką klasy.
Krótko mówiąc, jeśli ten problem występuje w środowisku IDE, sprawdź takie rzeczy, jak nieaktualny stan IDE, uszkodzone odwołania do projektu lub uszkodzone konfiguracje programu uruchamiającego.
Możliwe jest również, że IDE po prostu się pomyli. IDE to niezwykle skomplikowane oprogramowanie składające się z wielu interaktywnych części. Wiele z tych części przyjmuje różne strategie buforowania, aby IDE jako całość reagowało. Czasami mogą się nie udać, a jednym z możliwych symptomów są problemy podczas uruchamiania aplikacji. Jeśli podejrzewasz, że tak się dzieje, warto spróbować innych rzeczy, takich jak ponowne uruchomienie IDE, przebudowa projektu i tak dalej.
Miałem ten problem, gdy próbowałem uruchomić klasę z biblioteką innej firmy. Przywołałem java w ten sposób java -cp ../third-party-library.jar com.my.package.MyClass:; to nie działa, zamiast tego należy również dodać folder lokalny do ścieżki klasy (oddzielone :, tak: to java -cp ../third-party-library.jar:. com.my.package.MyClass, to powinno działać
lanoxx
22
Po latach programowania w języku Java nadal udało mi się znaleźć na tej stronie. Dla mnie problemem było to, że składnia ścieżki klas zależy od systemu operacyjnego . Jestem trochę nowy w programowaniu w systemie Windows i nie miałem pojęcia.
keyser
5
Dodatkowe uwagi, punkt 2 uratuj mnie! Przykro mi, że javanie mówi, że nie znajduje klasy importowanej, ale klasę główną, którą próbujesz uruchomić. Jest to mylące, chociaż jestem pewien, że istnieje ku temu powód. Miałem przypadek, w którym javawiedziałem dokładnie, gdzie jest moja klasa, jednak nie mógł znaleźć jednej z zaimportowanych klas. Zamiast tego powiedzieć, że narzekał, że nie znalazł mojej głównej klasy. Naprawdę, annoing.
MSX
Miałem ten problem dwa razy w Eclipse. Pierwszy raz podpis main () był nieprawidłowy. Za drugim razem zmieniłem nazwę pliku .jar i mimo że dodałem nowy do ścieżki kompilacji, Eclipse nie znalazł starej, więc projekt nie skompilował się z tym błędem. Musiałem usunąć plik .jar z Projekt> Właściwości> Ścieżka kompilacji Java> Biblioteki.
GregT
Spotkałem to po raz trzeci. Uruchomiłem program z pliku wsadowego systemu Windows 10 i umieściłem nazwę .jar w zmiennej (wywoływanej przez „-cp% jarname%; lib *”). Przez pomyłkę umieściłem dodatkowe miejsce na końcu nazwy jar, co spowodowało błąd. Hat trick :)
GregT
239
Jeśli nazwa źródłowa to HelloWorld.java, skompilowany kod będzie HelloWorld.class.
Problem polega na tym, że to rozwiązanie działa tylko dla klas Java zadeklarowanych w domyślnym pakiecie bez zależności pliku JAR. (I nawet wtedy nie zawsze). Większość programów Java nie jest taka prosta.
Stephen C
1
jak powiedział Stephen, działa to tylko z „domyślnym pakietem” - co oznacza brak deklaracji pakietu na górze pliku. W celu szybkiego przetestowania jakiegoś kodu zrobiłem: javac TestCode.javaa następniejava TestCode
Someone Somewhere
To mi nie zadziałało. Nadal mówi: „Nie można znaleźć ani załadować głównej klasy HelloWorld”
Jim
java -jar HelloWorld.jar jest również opcją
BMaximus,
12
Musiałem to zrobićjava -classpath . HelloWorld
Chris Prince,
136
Jeśli twoje klasy znajdują się w pakietach , musisz przejść cddo katalogu głównego projektu i uruchomić przy użyciu w pełni kwalifikowanej nazwy klasy (nazwa_pakietu.MainClassName).
Przykład:
Moje zajęcia są tutaj:
D:\project\com\cse\
W pełni kwalifikowana nazwa mojej głównej klasy to:
com.cse.Main
Więc cdwracam do głównego katalogu projektu:
D:\project
Następnie wydaj javapolecenie:
java com.cse.Main
Ta odpowiedź ma na celu uratowanie początkujących programistów Java przed frustracją spowodowaną powszechnym błędem. Zalecam przeczytanie przyjętej odpowiedzi, aby uzyskać bardziej szczegółową wiedzę na temat ścieżki klas języka Java.
Ta odpowiedź stanowi cały ładunek założeń. Są też inne sposoby na osiągnięcie tego. Zamiast ślepo postępować zgodnie z powyższymi wskazówkami, zaleciłbym, aby ludzie poświęcili czas na przeczytanie linków w mojej odpowiedzi, które wyjaśniają, jak działa ścieżka klas Java. Lepiej ZROZUMIEĆ, co robisz ...
Stephen C
2
Ta odpowiedź zawiera dokładne założenia, których potrzebowałem :) Byłem zlokalizowany w katalogu pliku .class i java.exe nie działał. Kiedyś cd-ed powyżej i uruchomiłem z nazwą pakietu zawartą w wierszu poleceń, zadziałało.
Nick Constantine
61
Jeśli zdefiniujesz główną klasę i główną metodę w apackage , powinieneś uruchomić ją w katalogu hierarchicznym, używając pełnej nazwy klasy ( packageName.MainClassName).
Załóżmy, że istnieje plik kodu źródłowego (Main.java):
Aby uruchomić ten kod, powinieneś umieścić go Main.Classw katalogu podobnym do pakietu ./com/test/Main.Java. I użyj katalogu głównego java com.test.Main.
Zobacz „Dodatkowe uwagi nr 1” mojej odpowiedzi. Dla lepszego wyjaśnienia tego problemu.
Stephen C
14
@StephenC Tak, twoja odpowiedź jest bardziej kompletna (i oczywiście +1), ale ta konkretna odpowiedź zawierała słowo „pakiet”, co pozwoliło mi szybko znaleźć to, czego potrzebowałem. I zadziałało. Więc +1 Razavi. StephenC, twojemu brakuje prostego przykładu pakietu, którego potrzebowałem, ponieważ jestem nowy w Javie.
kmort
5
To był dokładnie mój problem. Brnę przez mnóstwo dokumentów Java i ten konkretny przykład jest tym, czego potrzebowałem
John
1
Tak, konkretny przykład jest fajny, działał idealnie. Jestem pewien, że główna odpowiedź jest bardzo dokładna, ale trudno było zobaczyć drzewo do lasu. Nice one @Razavi
Pixel
1
Podoba mi się ta krótsza i przydatna odpowiedź zamiast zaakceptowanej!
Spara,
46
Gdy ten sam kod działa na jednym komputerze, ale pokazuje błąd na innym, najlepszym rozwiązaniem, jakie kiedykolwiek znalazłem, jest kompilacja w następujący sposób:
To nie jest dobra rekomendacja. Jesteś zależny od tego, czy zmienna środowiskowa CLASSPATH jest nieuzbrojona, czy też posiadasz wartość zgodną z „.”. Tak, działa w wielu przypadkach, ale w innych nie.
Stephen C
Cóż, na pewno javac -classpath . HelloWorld.javaby działało! I to jest lepsze rozwiązanie w twoim przypadku.
Stephen C
2
Jeśli masz „pakiet com.some.address” jako pierwszy wiersz - to nie zadziała. Musisz skomentować „adres paczki”.
Joe
1
@Joe - Ten hack (komentowanie pakietu) zadziała (w niektórych przypadkach), ale to zły pomysł. Lepszym pomysłem jest poznanie / zrozumienie przyczyny problemu i wdrożenie prawidłowego rozwiązania.
Stephen C
36
Pomogło mi określenie ścieżki klasy w wierszu poleceń, na przykład:
Stworzyć nowy folder, C:\temp
Utwórz plik Temp.java w C:\temp, zawierający następującą klasę:
W Ubuntu musiałem również określić ścieżkę. Nie rozumiem, dlaczego domyślnie nie może korzystać z bieżącego katalogu roboczego. Jestem przekonany, że Java jest sponsorowana przez producentów klawiatur !!
Wielkie dzięki za to ...... chociaż nie jestem pewien, dlaczego java nie była w stanie znaleźć ścieżki klasy nawet po ustawieniu jej w zmiennych środowiskowych.
akash89
@ akash89 - Najbardziej prawdopodobne powody były: 1) javanie patrzył na $ CLASSPATH (ponieważ użyłeś -classpath lub -jar) lub 2) ustawienie classpath nie został ustawiony w środowisku, które nie było w rzeczywistości w kontekście faktu, że javabył biegać; np. dlatego, że nie „źródłeś” pliku, do którego dodano komendy setenv we właściwej powłoce.
Stephen C
Nadal pojawia się błąd: Nie można znaleźć lub załadować Temp klasy głównej, czy ktoś może pomóc!
Gwiazda
27
Zgodnie z komunikatem o błędzie („Nie można znaleźć lub załadować głównej klasy”) istnieją dwie kategorie problemów:
Nie można znaleźć głównej klasy
Nie można załadować klasy głównej (ten przypadek nie jest w pełni omówiony w zaakceptowanej odpowiedzi)
Nie można znaleźć klasy głównej, jeśli literówka lub niepoprawna składnia występuje w pełnej nazwie klasy lub nie istnieje ona w podanej ścieżce klasy .
Nie można załadować klasy głównej, gdy nie można zainicjować klasy , zazwyczaj klasa główna rozszerza inną klasę i ta klasa nie istnieje w podanej ścieżce klas.
„Zasadniczo” istnieje również wiele innych kategorii. Problem braku nadklasy jest bardzo nietypową podelą. (Tak niezwykłe, że nigdy go nie widziałem ... w pytaniach zadawanych na tej stronie.)
Stephen C
Są DWA, ponieważ błąd mówi „Nie można znaleźć lub załadować głównej klasy”. Jeśli są inne kategorie, proszę o informację. Widziałem to, więc po prostu chcę się tu podzielić, może ktoś inny będzie go potrzebował.
Xiao Peng - ZenUML.com
1
Zmieniłbym to do czegoś takiego jak „Musisz uwzględnić wszystkie klasy, które są wymagane do zainicjowania klasy głównej, aby uniknąć tego konkretnego błędu”. Nie próbuję cię przekonać. To tylko sposób, który chciałbym zobaczyć. Zostawiłem tutaj odpowiedź tylko dla osób, które mogą lubić czytać w ten sposób. Nie przedłużajmy tej dyskusji :) Zmieniłem moje zdanie na „nie do końca omówione w przyjętej odpowiedzi” i mam nadzieję, że poczujesz się lepiej.
Xiao Peng - ZenUML.com 17.09.15
5
Ta informacja jest kluczowa i zasługuje na wyraźną wzmiankę (to jedyna wspomniana odpowiedź extends). Właśnie nauczyłem się na własnej skórze, że gdy klasa główna nie ładuje się, ponieważ rozszerza inną, której nie można znaleźć , java nie zgłasza, która klasa nie została znaleziona (w przeciwieństwie do NoClassDefFoundError). Tak, tak się dzieje, a kiedy się o tym nie wie, jest to sytuacja ciągnąca za włosy.
Hugues M.
1
Czy w tej sytuacji można dokładnie powiedzieć, która klasa zależności nie ładuje się?
Tak. Najprawdopodobniej Mainnie ma go w pliku JAR. -cp lib.jar;oznacza to samo co -cp lib.jar;. np. bieżący katalog jest zawarty w ścieżce klasy.
Stephen C
W końcu naprawiono problem z unixem. Dzięki (działa z :)
Vicky
16
Spróbuj -Xdiag .
Odpowiedź Steve'a C ładnie obejmuje możliwe przypadki, ale czasem ustalenie, czy nie można znaleźć lub załadować klasy, może nie być takie proste. Użyj java -Xdiag(od JDK 7). Wyświetla to ładny ślad stosu, który daje podpowiedź do tego, co Could not find or load main classoznacza komunikat.
Może na przykład wskazywać inne klasy używane przez klasę główną, których nie można znaleźć, i uniemożliwił załadowanie klasy głównej.
Przykład: jeśli twoja nazwa klasy to Hello.class utworzona z Hello.java, użyj następującego polecenia:
java -cp .Hello
Jeśli plik Hello.java znajduje się w pakiecie com.demo, użyj poniższej komendy
java -cp . com.demo.Hello
Z JDK 8 wiele razy zdarza się, że plik klasy znajduje się w tym samym folderze, ale javapolecenie oczekuje ścieżki klasy i dlatego dodajemy, -cp .aby wziąć bieżący folder jako odniesienie do ścieżki klasy.
Działa to tylko w prostych przypadkach. Bardziej skomplikowane przypadki wymagają bardziej skomplikowanej ścieżki klas.
Stephen C
A dla >> naprawdę << prostych przypadków, nie -cp .jest konieczne, ponieważ jeśli nie $CLASSPATHjest ustawione, to .jest domyślna ścieżka klasy.
Stephen C
Nie Stephen, wiele razy w domyślnej ścieżce klas systemu Windows nie działa. Wypróbowałem to na trzech różnych maszynach, możesz też tego wypróbować.
shaILU
Prawdopodobnie dlatego, że gdzieś ustawiłeś zmienną środowiskową% CLASSPATH%. Jeśli to zrobisz, nie będziesz używać domyślnej ścieżki klasy. (Co daje echo %CLASSPATH%wynik?) I nie, nie mogę sprawdzić, ponieważ nie mam komputera z systemem Windows.
Stephen C
2
Działa
15
Czasami to, co może być przyczyną problemu, nie ma nic wspólnego z klasą główną i musiałem to znaleźć na własnej skórze. To była biblioteka, do której się odwołałem, którą przeniosłam i dała mi:
Nie można znaleźć lub załadować głównej klasy xxx Linux
Właśnie usunąłem to odniesienie, dodałem je ponownie i znów zadziałało.
Wygląda na to, że problem polegał na tym, że miałeś niepoprawną ścieżkę klasy z powodu zepsutego „odwołania” w swoim projekcie w twoim IDE. Zaktualizuję moją odpowiedź, aby uwzględnić tę sprawę.
Stephen C,
@StephenC i EduardoDennis, to tutaj także brakowało słoika, który zawierał interfejs, od którego zależała główna instancja. Komunikat o błędzie jest więc zbyt szeroki. Powinienem powiedzieć „nie można znaleźć”, jeśli nie znaleziono pliku klasy i „nie można załadować (brakujących zależności)”, jeśli brakuje czegoś innego, ale nie samego pliku, więc zbyt szeroki komunikat o błędzie jest mylący, jeśli skupisz się tylko w części „znajdź” :(
Aquarius Power
@AquariusPower - Powinien istnieć dodatkowy „spowodowany przez” stacktrace dla wyjątku „przyczyna”, w którym brakowało klasy wht. Jeśli chcesz zasugerować programistom Java, że zmieniają komunikat o błędzie, który mówi, że od ponad 20 lat ... nie krępuj się. (Myślę, że komunikat o błędzie jest poprawny. Problem polegał na tym, że >> zawęziłeś niewłaściwą klauzulę.)
Stephen C
@StephenC miałem na myśli, że z pewnością mają dostęp do informacji, jeśli główny plik klasy jest dostępny, czy nie, więc dlaczego nie pokazać nam lepszego komunikatu o błędzie informującego o braku takiego pliku. Z drugiej strony mogliby również powiedzieć „Plik został znaleziony, ale nie można go załadować”. Natychmiast skupilibyśmy się na zależnościach, zamiast tracić pół dnia na badanie i testowanie rzeczy do zrozumienia. Właśnie to miałem na myśli :). Mogą to robić w ograniczony sposób przez ponad 20 lat, ale mogą to poprawić, a my jesteśmy tutaj, aby to zapewnić dzięki naszej krytyce i skargom! : D
Aquarius Power
Proszę zrozumieć, co >> I << znaczyło. Narzekanie na to w jakimś niejasnym komentarzu do 3-letnich pytań i odpowiedzi nic nie da. Ludzie, którzy mogą podejrzewać twoje skargi, nie zauważą tego. Jeśli chcesz zrobić coś konstruktywnego, prześlij łatkę. (Nie oceniam twoich szans, ale będą one większe niż gdybyś po prostu narzekał na to.)
Stephen C
10
W tym przypadku masz:
Nie można znaleźć lub załadować głównej klasy ? Classpath
Jest tak, ponieważ używasz „-classpath”, ale myślnik nie jest tym samym myślnikiem, którego używasz javaw wierszu polecenia. Miałem problem z kopiowaniem i wklejaniem z Notatnika na cmd.
Tak. Zobacz mój przykład # 2 niewłaściwych sposobów określenia nazwy klasy !!
Stephen C
7
Może ci to pomóc, jeśli twoja sprawa jest dokładnie taka jak moja: jako początkujący napotkałem również ten problem, gdy próbowałem uruchomić program Java.
Skompilowałem to w następujący sposób:
javac HelloWorld.java
Próbowałem też uruchomić to samo rozszerzenie:
java Helloworld.java
Kiedy usunąłem .javai przepisałem polecenie jak java HelloWorld, program działał idealnie. :)
Wynika to z faktu, że uruchamiasz skompilowaną wersję .java. W rzeczywistości wykonuje plik .class
Jason V
Dla przypomnienia, jest to to samo, co powód nr 1, przykład nr 5 w mojej odpowiedzi ...
Stephen C
6
Wszystkie odpowiedzi tutaj są skierowane do użytkowników systemu Windows. W przypadku komputerów Mac separator ścieżki klas :nie jest ;. Ponieważ błąd ustawiania używania ścieżki klasy ;nie jest generowany, może to być trudne do wykrycia, jeśli pochodzi z systemu Windows na komputer Mac.
Oto odpowiednie polecenie Maca:
java -classpath ".:./lib/*" com.test.MyClass
Gdzie w tym przykładzie jest paczka com.testi libfolder ma być również dołączony do ścieżki klasy.
Sporo czasu poświęciłem na rozwiązanie tego problemu. Myślałem, że w jakiś sposób nieprawidłowo ustawiłem ścieżkę klasy, ale problem polegał na tym, że wpisałem:
Zaktualizowałem swoją odpowiedź, aby spróbować rozwiązać ten problem.
Stephen C
2
Żadne z tych nie jest poprawne. Klasa musi być podana jako, utilities.myapp.Coollub jakakolwiek jest nazwa pakietu, jeśli istnieje.
user207421,
5
Najpierw ustaw ścieżkę za pomocą tego polecenia;
set path="paste the set path address"
Następnie musisz załadować program. Wpisz „cd (nazwa folderu)” na zapisanym dysku i skompiluj go. Na przykład, jeśli mój program jest zapisany na dysku D, wpisz „D:” naciśnij enter i wpisz „cd (nazwa folderu)”.
To nie pomaga. To pytanie dotyczy programów Java, a nie zwykłych plików wykonywalnych. Java nie używa PATH do lokalizowania czegokolwiek, a jeśli „cd” pomaga, to raczej przez szczęście niż przez osąd.
Stephen C,
if "cd" helps then it by luck rather than by judgement. To źle (jak sądzę), ponieważ Java .domyślnie używa bieżącego katalogu jako części ścieżki klas.
GKFX
2
@GKFX - o to mi chodzi. O ile nie wiesz, że używasz domyślnej ścieżki klasy (lub ścieżki klasy z „.”), „Cd” nie przyniesie żadnego efektu. To rozwiązanie działa bardziej na szczęście (tj. Zgadując / mając nadzieję, że „.” Znajduje się na ścieżce klasy) niż na podstawie osądu (tj. Sprawdzając, że „.” Znajduje się na ścieżce klasy). Ponadto nie masz racji co do wartości domyślnej. Java używa „.” domyślnie jako ścieżka klasy, a nie jako część ścieżki klasy.
Stephen C
5
Tym, co naprawiło problem w moim przypadku, było:
Kliknij prawym przyciskiem myszy projekt / klasę, którą chcesz uruchomić, a następnie Run As-> Run Configurations. Następnie należy naprawić istniejącą konfigurację lub dodać nową w następujący sposób:
otwórz Classpathkartę, kliknij Advanced...przycisk, a następnie dodaj binfolder swojego projektu.
Jeśli używasz Maven do zbudowania pliku JAR, upewnij się, że określiłeś klasę główną w pliku pom.xml:
<build><plugins><plugin><artifactId>maven-jar-plugin</artifactId><configuration><archive><manifest><mainClass>class name us.com.test.abc.MyMainClass</mainClass></manifest></archive></configuration></plugin></plugins></build>
Ta rada może, ale nie musi, pomóc. Pomoże, jeśli drzewo klas zawierające klasy w bieżącym katalogu. Nie zrobi tego, jeśli nie są. Nie zrobiłbym tego. Zamiast tego stworzyłbym skrypt opakowujący jednowierszowy, który działałby niezależnie od tego, czy użytkownik jest w katalogu „właściwym”.
Stephen C
4
Naprawdę musisz to zrobić z srcfolderu. Tam wpisz następujący wiersz polecenia:
[name of the package].[ClassName][arguments]
Powiedzmy, że twoja klasa jest wywoływana CommandLine.class, a kod wygląda następująco:
package com.tutorialspoint.java;/**
* Created by mda21185 on 15-6-2016.
*/publicclassCommandLine{publicstaticvoid main(String args[]){for(int i=0; i<args.length; i++){System.out.println("args["+ i +"]: "+ args[i]);}}}
Następnie powinieneś cdprzejść do folderu src, a polecenie, które musisz uruchomić, wyglądałoby tak:
java com.tutorialspoint.java.CommandLinethis is a command line 200-100
Dane wyjściowe w wierszu poleceń będą następujące:
args[0]:this
args[1]: is
args[2]: a
args[3]: command
args[4]: line
args[5]:200
args[6]:-100
Klasy nie można nazwać „CommandLine.class”. Byłby to błąd składniowy Java. (Masz na myśli to, że plik zawierający skompilowaną klasę nazywa się „CommandLine.class” ...). Innym problemem jest to, że twoja instrukcja „cd do katalogu źródłowego” działa tylko wtedy, gdy skompilowałeś kod >> do << drzewa katalogu źródłowego. Na koniec, jeśli twój kompilator użył argumentu „-cp”, to potrzebujesz odpowiednika podczas uruchamiania.
Stephen C
W moim projekcie mam folder src i folder bin w katalogu głównym. Musiałem cdsię src, a następnie uruchomić komendę java ../bin com.blah.blah.MyClassktóry pracował dla mnie. Dziękuję za podpowiedź!
tamj0rd2
3
W Javie, gdy czasami uruchamiasz JVM z wiersza poleceń za pomocą pliku wykonywalnego java i próbujesz uruchomić program z pliku klasy z publicznym statycznym void main (PSVM), możesz napotkać poniższy błąd, mimo że parametr classpath to JVM jest dokładny, a plik klasy jest obecny w ścieżce klasy:
Error: main class not found or loaded
Dzieje się tak, jeśli nie można załadować pliku klasy z PSVM. Jednym z możliwych powodów jest to, że klasa może implementować interfejs lub rozszerzać inną klasę, która nie znajduje się w ścieżce klas. Zwykle, jeśli klasa nie znajduje się w ścieżce klasy, zgłoszony błąd wskazuje jako taki. Ale jeśli używana klasa zostanie rozszerzona lub zaimplementowana, java nie będzie mogła załadować samej klasy.
Czy przeczytałeś zaakceptowaną odpowiedź? Czy twoja odpowiedź dodaje coś nowego?
Stephen C
1
@StephenC Próbowałem znaleźć powód na twojej liście, patrząc na kategorie „Powód” i ich punkty. Nie mogłem znaleźć pasującego tytułu w tytule „Powód nr 1” i „Powód nr 2” nie wyglądały tak blisko mojej sprawy (ponieważ byłem pewien, że nie ma problemu z samą ścieżką klasy). Znalazłem przyczynę, przeprowadzając eksperymenty i byłem zaskoczony, że w moim przypadku pojawił się błąd „nie znaleziono głównej klasy”, ponieważ interfejs implementacji nie znajdował się na ścieżce klasy. Jasne, że możesz powiedzieć „powinieneś przeczytać wszystko opisane w poście”, ale wydaje mi się, że Twoja lista przyczyn może zostać ulepszona.
gumkins
3
Podczas uruchamiania javaz -cpopcją opisaną w Windows PowerShell może pojawić się błąd, który wygląda mniej więcej tak:
The term `ClassName` is not recognized as the name of a cmdlet, function, script ...
Aby program PowerShell mógł zaakceptować polecenie, argumenty -cpopcji muszą być zawarte w cudzysłowach, jak w:
java -cp 'someDependency.jar;.'ClassName
Formowanie polecenia w ten sposób powinno pozwolić Java poprawnie przetwarzać argumenty ścieżki klasy.
Napotkałem również podobne błędy podczas testowania połączenia JDBC Java MongoDB. Myślę, że dobrze jest streścić moje ostateczne rozwiązanie w skrócie, aby w przyszłości każdy mógł bezpośrednio przyjrzeć się dwóm poleceniom i kontynuować.
Załóżmy, że znajdujesz się w katalogu, w którym istnieje plik Java i zależności zewnętrzne (pliki JAR).
To wszystko zakłada, że 1) JavaMongoDBConnectionnie ma pakietu i 2) nie zmieniasz katalogu. Jest to, delikatnie mówiąc, kruche. Nie wyjaśniając problemów, sprawi, że nowicjusze wypróbują to podejście w sytuacjach, w których nie będzie działać . Krótko mówiąc, zachęca do „technik programowania voodoo”: en.wikipedia.org/wiki/Voodoo_programming
Stephen C
3
W porządku, jest już wiele odpowiedzi, ale nikt nie wspomniał o przypadku, w którym winowajcą mogą być uprawnienia do plików.
Podczas działania użytkownik może nie mieć dostępu do pliku JAR lub jednego z katalogów ścieżki. Rozważ na przykład:
Plik jar w /dir1/dir2/dir3/myjar.jar
Użytkownik 1, który jest właścicielem pliku JAR, może:
#Running as User1
cd /dir1/dir2/dir3/
chmod +r myjar.jar
Ale nadal nie działa:
#Running as User2
java -cp "/dir1/dir2/dir3:/dir1/dir2/javalibs"MyProgramError:Could not find or load main classMyProgram
Jest tak, ponieważ działający użytkownik (Użytkownik2) nie ma dostępu do katalogu 1, katalogu 2 lub javalibs lub katalogu 3. Może doprowadzić kogoś do szału, gdy Użytkownik1 może zobaczyć pliki i uzyskać do nich dostęp, ale błąd nadal występuje dla Użytkownika2.
Nie udało mi się rozwiązać tego problemu za pomocą podanych tutaj rozwiązań (chociaż podana odpowiedź niewątpliwie oczyściła moje koncepcje). Napotkałem ten problem dwa razy i za każdym razem próbowałem różnych rozwiązań (w środowisku Eclipse IDE).
Po pierwsze, spotkałem się z wieloma mainmetodami w różnych klasach mojego projektu. Usunąłem więc mainmetodę z kolejnych klas.
Po drugie, wypróbowałem następujące rozwiązanie:
Kliknij prawym przyciskiem myszy mój główny katalog projektu.
Udaj się do źródła, a następnie posprzątaj i pozostań przy ustawieniach domyślnych i po zakończeniu. Po kilku zadaniach w tle zostaniesz przekierowany do głównego katalogu projektu.
Następnie zamykam projekt, otwieram go ponownie i bum, w końcu rozwiązałem swój problem.
Odpowiedzi:
java <class-name>
Składnia poleceniaPrzede wszystkim musisz zrozumieć prawidłowy sposób uruchamiania programu za pomocą polecenia
java
(lubjavaw
).Normalna składnia 1 jest następująca:
gdzie
<option>
jest opcją wiersza poleceń (zaczynającą się od znaku „-”),<class-name>
jest w pełni kwalifikowaną nazwą klasy Java i<arg>
jest dowolnym argumentem wiersza poleceń przekazywanym do aplikacji.1 - Istnieje kilka innych składni opisanych na końcu tej odpowiedzi.
W pełni kwalifikowana nazwa (FQN) dla klasy jest tradycyjnie zapisywana tak jak w kodzie źródłowym Java; na przykład
Jednak niektóre wersje
java
polecenia pozwalają używać ukośników zamiast kropek; na przykładktóry (myląco) wygląda jak ścieżka do pliku, ale nie jest nim. Zwróć uwagę, że termin w pełni kwalifikowana nazwa jest standardową terminologią Java ... a nie czymś, co właśnie wymyśliłem, aby cię zdezorientować :-)
Oto przykład, jak
java
powinno wyglądać polecenie:Powyższe spowoduje, że
java
polecenie wykona następujące czynności:com.acme.example.ListUsers
klasy.main
metodę z podpisem , typem zwrotu i modyfikatorami podanymi przezpublic static void main(String[])
. (Uwaga: nazwa argumentu metody NIE jest częścią podpisu).String[]
.Powody, dla których Java nie może znaleźć klasy
Gdy pojawi się komunikat „Nie można znaleźć lub załadować głównej klasy ...”, oznacza to, że pierwszy krok nie powiódł się.
java
Polecenie nie był w stanie znaleźć klasę. I rzeczywiście, „...” w wiadomości będzie w pełni kwalifikowaną nazwą klasy, którejjava
szuka.Dlaczego więc nie może znaleźć klasy?
Powód 1 - popełniłeś błąd przy argumencie nazwy klasy
Pierwszą prawdopodobną przyczyną jest podanie niewłaściwej nazwy klasy. (Lub ... właściwa nazwa klasy, ale w złej formie.) Biorąc pod uwagę powyższy przykład, oto wiele niewłaściwych sposobów określania nazwy klasy:
Przykład 1 - prosta nazwa klasy:
Gdy klasa jest zadeklarowana w pakiecie takim jak np.
com.acme.example
, Musisz użyć pełnej nazwy klasy wraz z nazwą pakietu wjava
poleceniu; na przykładPrzykład # 2 - nazwa pliku lub ścieżka zamiast nazwy klasy:
Przykład # 3 - nazwa klasy z niepoprawną obudową:
Przykład # 4 - literówka
Przykład # 5 - nazwa pliku źródłowego (oprócz Java 11 lub nowszego; patrz poniżej)
Przykład # 6 - całkowicie zapomniałeś nazwy klasy
Powód # 2 - ścieżka klasy aplikacji jest niepoprawnie określona
Drugą prawdopodobną przyczyną jest to, że nazwa klasy jest poprawna, ale
java
polecenie nie może znaleźć klasy. Aby to zrozumieć, musisz zrozumieć pojęcie „ścieżki klas”. Wyjaśnia to dobrze dokumentacja Oracle:java
poleceniaWięc ... jeśli poprawnie podałeś nazwę klasy, następną rzeczą do sprawdzenia jest poprawne określenie ścieżki klas:
java
polecenia. Sprawdź, czy nazwy katalogów i nazwy plików JAR są poprawne.java
polecenia.;
w systemie Windows i:
innych. Jeśli użyjesz niewłaściwego separatora dla swojej platformy, nie otrzymasz wyraźnego komunikatu o błędzie. Zamiast tego otrzymasz ścieżkę, która nie istnieje, w ścieżce, która zostanie po cichu zignorowana .)Powód # 2a - niewłaściwy katalog znajduje się w ścieżce klasy
Gdy umieścisz katalog w ścieżce klas, teoretycznie odpowiada on katalogowi głównemu kwalifikowanej przestrzeni nazw. Klasy znajdują się w strukturze katalogów poniżej tego katalogu głównego, poprzez mapowanie w pełni kwalifikowanej nazwy na nazwę ścieżki . Na przykład, jeśli „/ usr / local / acme / klas” znajduje się na ścieżce klasy, to kiedy JVM szuka klasy o nazwie
com.acme.example.Foon
, będzie szukał pliku „.class” o tej nazwie ścieżki:Jeśli umieściłeś „/ usr / local / acme / klas / com / acme / example” na ścieżce klasy, JVM nie byłby w stanie znaleźć klasy.
Powód # 2b - ścieżka podkatalogu nie zgadza się z FQN
Jeśli FQN twoich klas
com.acme.example.Foon
, to JVM będzie szukać „Foon.class” w katalogu „com / acme / example”:Jeśli struktura katalogów nie odpowiada nazwie pakietu zgodnie z powyższym wzorcem, JVM nie znajdzie twojej klasy.
Jeśli spróbujesz zmienić nazwę klasy, przenosząc ją, to również się nie powiedzie ... ale wyjątek stacktrace będzie inny. Można powiedzieć coś takiego:
ponieważ nazwa FQN w pliku klasy nie zgadza się z tym, czego oczekuje moduł ładujący klasy.
Podając konkretny przykład, załóżmy, że:
com.acme.example.Foon
klasę,/usr/local/acme/classes/com/acme/example/Foon.class
,/usr/local/acme/classes/com/acme/example/
,następnie:
Uwagi:
-classpath
Opcja może być skrócony do-cp
większości wydań Java. Sprawdź odpowiednie wpisy dla manualnychjava
,javac
i tak dalej.Powód # 2c - brak zależności w ścieżce klasy
Ścieżka klasy musi zawierać wszystkie inne (niesystemowe) klasy, od których zależy twoja aplikacja. (Klasy systemowe są lokalizowane automatycznie i rzadko trzeba się tym zajmować.) Aby klasa główna poprawnie się załadowała, JVM musi znaleźć:
(Uwaga: specyfikacje JLS i JVM pozwalają JVM na pewien zakres ładowania klas „leniwie”, co może mieć wpływ, gdy zostanie zgłoszony wyjątek programu ładującego klasy.)
Powód 3 - klasa została zadeklarowana w niewłaściwym pakiecie
Czasami zdarza się, że ktoś umieszcza plik kodu źródłowego w niewłaściwym folderze w drzewie kodu źródłowego lub pomija
package
deklarację. Jeśli zrobisz to w środowisku IDE, kompilator IDE natychmiast o tym powie. Podobnie, jeśli używasz przyzwoitego narzędzia do budowania Java, narzędzie będzie działaćjavac
w sposób, który wykryje problem. Jeśli jednak zbudujesz kod Java ręcznie, możesz to zrobić w taki sposób, aby kompilator nie zauważył problemu, a wynikowy plik „.class” nie znajduje się w miejscu, w którym się spodziewasz.Nadal nie możesz znaleźć problemu?
Jest wiele rzeczy do sprawdzenia i łatwo coś przeoczyć. Spróbuj dodać
-Xdiag
opcję dojava
wiersza poleceń (jako pierwszą rzecz pojava
). Wyprowadzi różne rzeczy na temat ładowania klas, a to może dać ci wskazówki co do prawdziwego problemu.Weź również pod uwagę możliwe problemy związane z kopiowaniem i wklejaniem niewidocznych znaków spoza ASCII ze stron internetowych, dokumentów itp. I rozważmy „homoglify”, gdyby dwie litery lub symbole wyglądały tak samo… ale nie są.
Wreszcie, najwyraźniej możesz napotkać ten problem, jeśli spróbujesz uruchomić z pliku JAR z niepoprawnymi podpisami
(META-INF/*.SF)
.Alternatywne składnie dla
java
Istnieją trzy alternatywne składnie do uruchamiania programów Java za pomocą
java command
.1) Składnia używana do uruchamiania „wykonywalnego” pliku JAR jest następująca:
na przykład
Nazwa klasy punktu wejścia (tj.
com.acme.example.ListUser
) I ścieżka klasy są określone w pliku MANIFEST pliku JAR.2) Składnia do uruchamiania aplikacji z modułu (Java 9 i nowsze) jest następująca:
Nazwa klasy punktu wejścia jest albo zdefiniowana przez
<module>
siebie, albo jest podana opcjonalnie<mainclass>
.3) Począwszy od Java 11, możesz skompilować i uruchomić pojedynczy plik kodu źródłowego i uruchomić go z następującą składnią:
gdzie jest (zazwyczaj) plik z przyrostkiem „.java”.
Aby uzyskać więcej informacji, zapoznaj się z oficjalną dokumentacją
java
polecenia używanej wersji Java.IDE
Typowe środowisko Java IDE obsługuje obsługę aplikacji Java w samej maszynie JVM IDE lub w podrzędnej maszynie JVM. Na ogół są one odporne na ten szczególny wyjątek, ponieważ IDE używa własnych mechanizmów do konstruowania ścieżki klas środowiska wykonawczego, identyfikacji głównej klasy i utworzenia
java
wiersza poleceń.Jednak nadal jest możliwe wystąpienie tego wyjątku, jeśli wykonasz czynności za zapleczem IDE. Na przykład, jeśli wcześniej skonfigurowałeś program uruchamiający aplikację dla aplikacji Java w Eclipse, a następnie przeniosłeś plik JAR zawierający klasę „main” w inne miejsce w systemie plików bez informowania Eclipse , Eclipse nieświadomie uruchomiłby JVM z niepoprawną ścieżką klasy.
Krótko mówiąc, jeśli ten problem występuje w środowisku IDE, sprawdź takie rzeczy, jak nieaktualny stan IDE, uszkodzone odwołania do projektu lub uszkodzone konfiguracje programu uruchamiającego.
Możliwe jest również, że IDE po prostu się pomyli. IDE to niezwykle skomplikowane oprogramowanie składające się z wielu interaktywnych części. Wiele z tych części przyjmuje różne strategie buforowania, aby IDE jako całość reagowało. Czasami mogą się nie udać, a jednym z możliwych symptomów są problemy podczas uruchamiania aplikacji. Jeśli podejrzewasz, że tak się dzieje, warto spróbować innych rzeczy, takich jak ponowne uruchomienie IDE, przebudowa projektu i tak dalej.
Inne referencje
źródło
java -cp ../third-party-library.jar com.my.package.MyClass
:; to nie działa, zamiast tego należy również dodać folder lokalny do ścieżki klasy (oddzielone:
, tak: tojava -cp ../third-party-library.jar:. com.my.package.MyClass
, to powinno działaćjava
nie mówi, że nie znajduje klasy importowanej, ale klasę główną, którą próbujesz uruchomić. Jest to mylące, chociaż jestem pewien, że istnieje ku temu powód. Miałem przypadek, w którymjava
wiedziałem dokładnie, gdzie jest moja klasa, jednak nie mógł znaleźć jednej z zaimportowanych klas. Zamiast tego powiedzieć, że narzekał, że nie znalazł mojej głównej klasy. Naprawdę, annoing.Jeśli nazwa źródłowa to HelloWorld.java, skompilowany kod będzie
HelloWorld.class
.Ten błąd pojawi się, jeśli wywołasz go za pomocą:
Zamiast tego użyj tego:
źródło
javac TestCode.java
a następniejava TestCode
java -classpath . HelloWorld
Jeśli twoje klasy znajdują się w pakietach , musisz przejść
cd
do katalogu głównego projektu i uruchomić przy użyciu w pełni kwalifikowanej nazwy klasy (nazwa_pakietu.MainClassName).Przykład:
Moje zajęcia są tutaj:
W pełni kwalifikowana nazwa mojej głównej klasy to:
Więc
cd
wracam do głównego katalogu projektu:Następnie wydaj
java
polecenie:Ta odpowiedź ma na celu uratowanie początkujących programistów Java przed frustracją spowodowaną powszechnym błędem. Zalecam przeczytanie przyjętej odpowiedzi, aby uzyskać bardziej szczegółową wiedzę na temat ścieżki klas języka Java.
źródło
Jeśli zdefiniujesz główną klasę i główną metodę w a
package
, powinieneś uruchomić ją w katalogu hierarchicznym, używając pełnej nazwy klasy (packageName.MainClassName
).Załóżmy, że istnieje plik kodu źródłowego (Main.java):
Aby uruchomić ten kod, powinieneś umieścić go
Main.Class
w katalogu podobnym do pakietu./com/test/Main.Java
. I użyj katalogu głównegojava com.test.Main
.źródło
Gdy ten sam kod działa na jednym komputerze, ale pokazuje błąd na innym, najlepszym rozwiązaniem, jakie kiedykolwiek znalazłem, jest kompilacja w następujący sposób:
źródło
javac -classpath . HelloWorld.java
by działało! I to jest lepsze rozwiązanie w twoim przypadku.Pomogło mi określenie ścieżki klasy w wierszu poleceń, na przykład:
Stworzyć nowy folder,
C:\temp
Utwórz plik Temp.java w
C:\temp
, zawierający następującą klasę:Otwórz wiersz polecenia w folderze
C:\temp
i napisz następujące polecenie, aby skompilować klasę Temp:Uruchom skompilowaną klasę Java, dodając
-classpath
opcję, aby JRE wiedział, gdzie znaleźć klasę:źródło
java
nie patrzył na $ CLASSPATH (ponieważ użyłeś -classpath lub -jar) lub 2) ustawienie classpath nie został ustawiony w środowisku, które nie było w rzeczywistości w kontekście faktu, żejava
był biegać; np. dlatego, że nie „źródłeś” pliku, do którego dodano komendy setenv we właściwej powłoce.Zgodnie z komunikatem o błędzie („Nie można znaleźć lub załadować głównej klasy”) istnieją dwie kategorie problemów:
Nie można znaleźć klasy głównej, jeśli literówka lub niepoprawna składnia występuje w pełnej nazwie klasy lub nie istnieje ona w podanej ścieżce klasy .
Nie można załadować klasy głównej, gdy nie można zainicjować klasy , zazwyczaj klasa główna rozszerza inną klasę i ta klasa nie istnieje w podanej ścieżce klas.
Na przykład:
Jeśli nie uwzględniono sprężyny wielbłąda, ten błąd zostanie zgłoszony.
źródło
extends
). Właśnie nauczyłem się na własnej skórze, że gdy klasa główna nie ładuje się, ponieważ rozszerza inną, której nie można znaleźć , java nie zgłasza, która klasa nie została znaleziona (w przeciwieństwie doNoClassDefFoundError
). Tak, tak się dzieje, a kiedy się o tym nie wie, jest to sytuacja ciągnąca za włosy.Miałem taki błąd w tym przypadku:
Działa z
;
systemami Windows i:
Unix:źródło
Main
nie ma go w pliku JAR.-cp lib.jar;
oznacza to samo co-cp lib.jar;.
np. bieżący katalog jest zawarty w ścieżce klasy.Spróbuj -Xdiag .
Odpowiedź Steve'a C ładnie obejmuje możliwe przypadki, ale czasem ustalenie, czy nie można znaleźć lub załadować klasy, może nie być takie proste. Użyj
java -Xdiag
(od JDK 7). Wyświetla to ładny ślad stosu, który daje podpowiedź do tego, coCould not find or load main class
oznacza komunikat.Może na przykład wskazywać inne klasy używane przez klasę główną, których nie można znaleźć, i uniemożliwił załadowanie klasy głównej.
źródło
Użyj tego polecenia:
Przykład: jeśli twoja nazwa klasy to Hello.class utworzona z Hello.java, użyj następującego polecenia:
Jeśli plik Hello.java znajduje się w pakiecie com.demo, użyj poniższej komendy
Z JDK 8 wiele razy zdarza się, że plik klasy znajduje się w tym samym folderze, ale
java
polecenie oczekuje ścieżki klasy i dlatego dodajemy,-cp .
aby wziąć bieżący folder jako odniesienie do ścieżki klasy.źródło
-cp .
jest konieczne, ponieważ jeśli nie$CLASSPATH
jest ustawione, to.
jest domyślna ścieżka klasy.echo %CLASSPATH%
wynik?) I nie, nie mogę sprawdzić, ponieważ nie mam komputera z systemem Windows.Czasami to, co może być przyczyną problemu, nie ma nic wspólnego z klasą główną i musiałem to znaleźć na własnej skórze. To była biblioteka, do której się odwołałem, którą przeniosłam i dała mi:
Właśnie usunąłem to odniesienie, dodałem je ponownie i znów zadziałało.
źródło
W tym przypadku masz:
Jest tak, ponieważ używasz „-classpath”, ale myślnik nie jest tym samym myślnikiem, którego używasz
java
w wierszu polecenia. Miałem problem z kopiowaniem i wklejaniem z Notatnika na cmd.źródło
Miałem ten sam problem i w końcu znalazłem swój błąd :) Użyłem tego polecenia do kompilacji i działało poprawnie:
Ale to polecenie nie działało dla mnie (nie mogłem znaleźć ani załadować głównej klasy
qrcode
):W końcu właśnie dodałem znak „:” na końcu ścieżki klas i problem został rozwiązany:
źródło
W moim przypadku wystąpił błąd, ponieważ podałem nazwę pliku źródłowego zamiast nazwy klasy.
Musimy podać interpreterowi nazwę klasy zawierającą główną metodę.
źródło
Może ci to pomóc, jeśli twoja sprawa jest dokładnie taka jak moja: jako początkujący napotkałem również ten problem, gdy próbowałem uruchomić program Java.
Skompilowałem to w następujący sposób:
Próbowałem też uruchomić to samo rozszerzenie:
Kiedy usunąłem
.java
i przepisałem polecenie jakjava HelloWorld
, program działał idealnie. :)źródło
Wszystkie odpowiedzi tutaj są skierowane do użytkowników systemu Windows. W przypadku komputerów Mac separator ścieżki klas
:
nie jest;
. Ponieważ błąd ustawiania używania ścieżki klasy;
nie jest generowany, może to być trudne do wykrycia, jeśli pochodzi z systemu Windows na komputer Mac.Oto odpowiednie polecenie Maca:
Gdzie w tym przykładzie jest paczka
com.test
ilib
folder ma być również dołączony do ścieżki klasy.źródło
/*
jest to konieczne?Lokalizacja pliku klasy: C: \ test \ com \ company
Nazwa pliku: Main.class
W pełni kwalifikowana nazwa klasy: com.company.Main
Polecenie z wiersza poleceń:
Zauważ, że ścieżka klasy NIE zawiera \ com \ company
źródło
Sporo czasu poświęciłem na rozwiązanie tego problemu. Myślałem, że w jakiś sposób nieprawidłowo ustawiłem ścieżkę klasy, ale problem polegał na tym, że wpisałem:
zamiast:
Pomyślałem, że znaczenie w pełni kwalifikowane ma obejmować pełną nazwę ścieżki zamiast pełnej nazwy pakietu.
źródło
utilities.myapp.Cool
lub jakakolwiek jest nazwa pakietu, jeśli istnieje.Najpierw ustaw ścieżkę za pomocą tego polecenia;
Następnie musisz załadować program. Wpisz „cd (nazwa folderu)” na zapisanym dysku i skompiluj go. Na przykład, jeśli mój program jest zapisany na dysku D, wpisz „D:” naciśnij enter i wpisz „cd (nazwa folderu)”.
źródło
if "cd" helps then it by luck rather than by judgement
. To źle (jak sądzę), ponieważ Java.
domyślnie używa bieżącego katalogu jako części ścieżki klas.Tym, co naprawiło problem w moim przypadku, było:
Kliknij prawym przyciskiem myszy projekt / klasę, którą chcesz uruchomić, a następnie
Run As
->Run Configurations
. Następnie należy naprawić istniejącą konfigurację lub dodać nową w następujący sposób:otwórz
Classpath
kartę, kliknijAdvanced...
przycisk, a następnie dodajbin
folder swojego projektu.źródło
Jeśli używasz Maven do zbudowania pliku JAR, upewnij się, że określiłeś klasę główną w pliku pom.xml:
źródło
Jest to szczególny przypadek, ale ponieważ wszedłem na tę stronę w poszukiwaniu rozwiązania i nie znalazłem go, dodam go tutaj.
Windows (testowany z 7) nie akceptuje znaków specjalnych (np
á
) w nazwach klas i pakietów. Linux tak.Dowiedziałem się tego, gdy zbudowałem
.jar
NetBeans i próbowałem uruchomić go w wierszu poleceń. Działał w NetBeans, ale nie w wierszu poleceń.źródło
W systemie Windows
.;
na początku ustaw wartość CLASSPATH.The. (kropka) oznacza „zajrzyj do bieżącego katalogu”. To jest trwałe rozwiązanie.
Możesz także ustawić „jednorazowo” za pomocą zestawu
CLASSPATH=%CLASSPATH%;.
. Trwa to tak długo, jak długo okno cmd jest otwarte.źródło
Naprawdę musisz to zrobić z
src
folderu. Tam wpisz następujący wiersz polecenia:Powiedzmy, że twoja klasa jest wywoływana
CommandLine.class
, a kod wygląda następująco:Następnie powinieneś
cd
przejść do folderu src, a polecenie, które musisz uruchomić, wyglądałoby tak:Dane wyjściowe w wierszu poleceń będą następujące:
źródło
cd
sięsrc
, a następnie uruchomić komendęjava ../bin com.blah.blah.MyClass
który pracował dla mnie. Dziękuję za podpowiedź!W Javie, gdy czasami uruchamiasz JVM z wiersza poleceń za pomocą pliku wykonywalnego java i próbujesz uruchomić program z pliku klasy z publicznym statycznym void main (PSVM), możesz napotkać poniższy błąd, mimo że parametr classpath to JVM jest dokładny, a plik klasy jest obecny w ścieżce klasy:
Dzieje się tak, jeśli nie można załadować pliku klasy z PSVM. Jednym z możliwych powodów jest to, że klasa może implementować interfejs lub rozszerzać inną klasę, która nie znajduje się w ścieżce klas. Zwykle, jeśli klasa nie znajduje się w ścieżce klasy, zgłoszony błąd wskazuje jako taki. Ale jeśli używana klasa zostanie rozszerzona lub zaimplementowana, java nie będzie mogła załadować samej klasy.
Odniesienie: https://www.computingnotes.net/java/error-main-class-not-found-or-loaded/
źródło
Podczas uruchamiania
java
z-cp
opcją opisaną w Windows PowerShell może pojawić się błąd, który wygląda mniej więcej tak:Aby program PowerShell mógł zaakceptować polecenie, argumenty
-cp
opcji muszą być zawarte w cudzysłowach, jak w:Formowanie polecenia w ten sposób powinno pozwolić Java poprawnie przetwarzać argumenty ścieżki klasy.
źródło
Napotkałem również podobne błędy podczas testowania połączenia JDBC Java MongoDB. Myślę, że dobrze jest streścić moje ostateczne rozwiązanie w skrócie, aby w przyszłości każdy mógł bezpośrednio przyjrzeć się dwóm poleceniom i kontynuować.
Załóżmy, że znajdujesz się w katalogu, w którym istnieje plik Java i zależności zewnętrzne (pliki JAR).
Skompilować:
Biegać:
źródło
JavaMongoDBConnection
nie ma pakietu i 2) nie zmieniasz katalogu. Jest to, delikatnie mówiąc, kruche. Nie wyjaśniając problemów, sprawi, że nowicjusze wypróbują to podejście w sytuacjach, w których nie będzie działać . Krótko mówiąc, zachęca do „technik programowania voodoo”: en.wikipedia.org/wiki/Voodoo_programmingW porządku, jest już wiele odpowiedzi, ale nikt nie wspomniał o przypadku, w którym winowajcą mogą być uprawnienia do plików.
Podczas działania użytkownik może nie mieć dostępu do pliku JAR lub jednego z katalogów ścieżki. Rozważ na przykład:
Plik jar w
/dir1/dir2/dir3/myjar.jar
Użytkownik 1, który jest właścicielem pliku JAR, może:
Ale nadal nie działa:
Jest tak, ponieważ działający użytkownik (Użytkownik2) nie ma dostępu do katalogu 1, katalogu 2 lub javalibs lub katalogu 3. Może doprowadzić kogoś do szału, gdy Użytkownik1 może zobaczyć pliki i uzyskać do nich dostęp, ale błąd nadal występuje dla Użytkownika2.
źródło
Wystąpił ten błąd po zrobieniu
mvn eclipse:eclipse
To.classpath
trochę popsuło mój plik.Musiałem zmienić linie
.classpath
zdo
źródło
Nie udało mi się rozwiązać tego problemu za pomocą podanych tutaj rozwiązań (chociaż podana odpowiedź niewątpliwie oczyściła moje koncepcje). Napotkałem ten problem dwa razy i za każdym razem próbowałem różnych rozwiązań (w środowisku Eclipse IDE).
main
metodami w różnych klasach mojego projektu. Usunąłem więcmain
metodę z kolejnych klas.źródło
main
metod nie rozwiąże problemu. Nie ma nic technicznie złego w aplikacji, która ma wiele punktów wejścia.