Често срещан проблем при новите разработчици на Java е, че програмите им не се изпълняват със съобщение за грешка: не може да намери или зареди главния клас ...`
Какво означава това, какво го причинява и как да го отстраните?
java <class-name>
Преди всичко трябва да разберете правилния начин за стартиране на програма с помощта на командата java
(или javaw
).
Нормалният синтаксис1 е следният:
java [ <option> ... ] <class-name> [<argument> ...]
където <option>
е опция от командния ред (започваща със символа "-"), <class-name>
е напълно квалифицирано име на Java клас, а <argument>
е произволен аргумент от командния ред, който се предава на вашето приложение.
1 - Съществува втори синтаксис за "изпълними" JAR файлове, който ще опиша по-надолу.
Напълно квалифицираното име (FQN) за класа се записва условно, както в изходния код на Java; напр.
packagename.packagename2.packagename3.ClassName
Въпреки това някои версии на командата java
позволяват да се използват наклонени черти вместо точки; напр.
packagename/packagename2/packagename3/ClassName
което (объркващо) изглежда като име на файл, но не е такова. Обърнете внимание, че терминът пълно квалифицирано име е стандартна терминология на Java ... а не нещо, което съм измислил, за да ви объркам :-)
Ето един пример за това как трябва да изглежда една команда java
:
java -Xmx100m com.acme.example.ListUsers fred joe bert
Горното ще накара командата java
да направи следното:
com.acme.example.ListUsers
.main
с знак, тип на връщане и модификатори, зададени от public static void main(String[])
. (Обърнете внимание, че името на аргумента на метода не е част от сигнатурата.)String[]
.
Причини, поради които Java не може да намери класаjava
не е успяла да намери класа. И наистина, "..." в съобщението ще бъде пълно квалифицираното име на класа, което java
търси.
Тогава защо тя не може да намери класа?Първата вероятна причина е, че може да сте предоставили грешно име на клас. (Или ... правилното име на клас, но в неправилна форма.) Като се има предвид горният пример, ето различни неправилни начини за задаване на името на класа:
Пример № 1 - просто име на клас:
java ListUser
Когато класът е деклариран в пакет като com.acme.example
, тогава трябва да използвате пълното име на класа включващо името на пакета в командата java
; напр.
java com.acme.example.ListUser
Пример № 2 - име на файл или име на път, а не име на клас: java ListUser.class java com/acme/example/ListUser.class
Пример № 3 - име на клас с неправилен корпус: java com.acme.example.listuser
Пример № 4 - печатна грешка java com.acme.example.mistuser
Пример № 5 - име на изходния файл java ListUser.java
Втората вероятна причина е, че името на класа е правилно, но командата java
не може да намери класа. За да разберете това, трябва да разберете концепцията за "classpath". Това е обяснено добре в документацията на Oracle:
Учебникът по Java - PATH и CLASSPATH И така... ако сте посочили правилно името на класа, следващото нещо, което трябва да проверите, е дали сте посочили правилно classpath:
java
. Проверете дали имената на директориите и имената на JAR файловете са правилни.java
.;
при Windows и :
при останалите. Ако използвате грешен разделител за вашата платформа, няма да получите изрично съобщение за грешка. Вместо това ще получите несъществуващ файл или директория в пътя, които ще бъдат игнорирани безшумно.)
Причина № 2а - грешна директория в пътя на класаКогато поставите директория в classpath, тя условно съответства на корена на квалифицираното пространство от имена. Класовете се намират в структурата от директории под този корен, като се съпостави напълно квалифицираното име с име на път. Така например, ако "/usr/local/acme/classes" е в пътя на класа, тогава, когато JVM търси клас, наречен com.acme.example.Foon
, той ще търси ".class" файл с това име:
/usr/local/acme/classes/com/acme/example/Foon.class
Ако FQN на вашите класове е com.acme.example.Foon
, тогава JVM ще търси "Foon.class" в директорията "com/acme/example":
com.acme.example.Foon
,/usr/local/acme/classes/com/acme/example/Foon.class
,/usr/local/acme/classes/com/acme/example/
,
тогава:# 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
Бележки:
Опцията -classpath
може да бъде съкратена до -cp
в повечето версии на Java. Проверете съответните записи в ръководството за java
, javac
и т.н.
Пътят на класа трябва да включва всички други (несистемни) класове, от които зависи вашето приложение. (Системните класове се намират автоматично и рядко се налага да се занимавате с това). За да се зареди правилно главният клас, JVM трябва да намери:
самия клас.
всички класове и интерфейси в йерархията на суперкласовете (например вижте https://stackoverflow.com/questions/42880748)
пакет
. Ако направите това в някоя IDE, компилаторът на IDE'та веднага ще ви съобщи за това. По същия начин, ако използвате приличен инструмент за изграждане на Java, инструментът ще изпълни javac
по начин, който ще открие проблема. Ако обаче изграждате кода си на Java на ръка, можете да го направите по такъв начин, че компилаторът да не забележи проблема и полученият файл ".class" да не е на мястото, на което очаквате да бъде.
Все още не можете да откриете проблема?-Xdiag
към командния ред java
(като първото нещо след java
). Тя ще изведе различни неща за зареждането на класовете и това може да ви подскаже какъв е истинският проблем.
Също така помислете за възможни проблеми, причинени от копиране и поставяне на невидими или неASCII символи от уебсайтове, документи и т.н. И помислете за "хомоглифите", когато две букви или символи изглеждат еднакво... но не са.java -jar <jar file>
Алтернативният синтаксис, използван за "изпълними" JAR файлове, е следният:
java [ <option> ... ] -jar <jar-file-name> [<argument> ...]
напр.
java -Xmx100m -jar /usr/local/acme-example/listuser.jar fred
com.acme.example.ListUser
) и пътя на класа са посочени в MANIFEST на JAR файла.java
.
Въпреки това е възможно това изключение да се появи, ако правите нещо зад гърба на IDE. Например, ако преди това сте настроили Application Launcher за вашето Java приложение в Eclipse и след това сте преместили JAR файла, съдържащ класа "main", на друго място във файловата система без да кажете на Eclipse, Eclipse несъзнателно ще стартира JVM с неправилен classpath.
Накратко, ако получите този проблем в IDE, проверете за неща като застояло състояние на IDE, нарушени препратки към проекта или нарушени конфигурации на стартиращите устройства.
Възможно е също така IDE просто да се обърка. IDE's са изключително сложни части от софтуера, които се състоят от много взаимодействащи си части. Много от тези части използват различни стратегии за кеширане, за да направят IDE като цяло гъвкава. Понякога те могат да се объркат и един от възможните симптоми са проблеми при стартирането на приложенията. Ако подозирате, че това може да се случи, струва си да опитате да рестартирате IDE и да възстановите проекта.Понякога това, което може да е причина за проблема, няма нищо общо с главния клас, а на мен ми се наложи да разбера това по трудния начин. Беше препратена библиотека, която преместих, и тя ми даде:
Не можа да намери или зареди главния клас xxx Linux
Просто изтрих тази препратка, добавих я отново и всичко отново работи добре.
Първо задайте пътя, като използвате тази команда;
set path="paste the set path address"
След това трябва да заредите програмата. Въведете "cd (име на папка)" в съхраненото устройство и я компилирайте. Например, ако моята програма е съхранена на устройството D, въведете "D:" натиснете Enter и въведете " cd (име на папка)".