Что означает "Не удалось найти или загрузить основной класс"?
Общая проблема, с которой сталкиваются новые Java-разработчики, заключается в том, что их программы не запускаются с сообщением об ошибке: Could not find or load main class ...
Что это значит, что вызывает и как это исправить?
67 ответов
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[])
, (Обратите внимание, что имя аргумента метода НЕ является частью подписи.) - Вызовите этот метод, передав ему аргументы командной строки ("fred", "joe", "bert") как
String[]
,
Причины, по которым Java не может найти класс
Когда вы получаете сообщение "Не удалось найти или загрузить основной класс...", это означает, что первый шаг не выполнен. java
Команда не смогла найти класс. И действительно, "..." в сообщении будет полностью определенным именем класса, которое java
ищет.
Так почему же он не может найти класс?
Причина № 1 - вы ошиблись с аргументом имени класса
Первой вероятной причиной является то, что вы, возможно, указали неправильное имя класса. (Или... правильное имя класса, но в неправильной форме.) Рассматривая приведенный выше пример, можно привести множество неправильных способов указания имени класса:
Пример № 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
Пример №6 - вы полностью забыли имя класса
java lots of arguments
Причина № 2 - неверно указан путь к классу приложения
Второй вероятной причиной является то, что имя класса является правильным, но что java
команда не может найти класс. Чтобы понять это, вам нужно понять концепцию "classpath". Это хорошо объясняется документацией Oracle:
java
командная документация- Установка пути к классам.
- Учебник по Java - PATH и CLASSPATH
Итак... если вы правильно указали имя класса, то следует проверить, правильно ли вы указали путь к классу:
- Прочитайте три документа, ссылки на которые приведены выше. (Да... ПРОЧИТАЙТЕ их. Важно, чтобы программист Java понимал хотя бы основы того, как работают механизмы пути классов Java.)
- Посмотрите на командную строку и / или переменную среды CLASSPATH, которая действует при запуске
java
команда. Проверьте правильность имен каталогов и файлов JAR. - Если в пути к классам есть относительные имена путей, проверьте, что они разрешаются правильно... из текущего каталога, который действует при запуске
java
команда. - Убедитесь, что класс (упомянутый в сообщении об ошибке) может быть расположен на эффективном пути к классам.
- Обратите внимание, что синтаксис пути к классам отличается для Windows по сравнению с Linux и Mac OS. (Разделитель пути к классам
;
на Windows и:
на остальных.)
Причина № 2а - неправильный каталог находится на пути к классам
Когда вы помещаете каталог в classpath, он условно соответствует корню квалифицированного пространства имен. Классы расположены в структуре каталогов под этим корнем, сопоставляя полное имя с путевым именем. Так, например, если "/usr/local/acme/classes" находится на пути к классам, то когда JVM ищет класс с именем com.acme.example.Foon
, он будет искать файл ".class" с таким путем:
/usr/local/acme/classes/com/acme/example/Foon.class
Если бы вы поместили "/usr/local/acme/classes/com/acme/example" в путь к классам, то JVM не сможет найти класс.
Причина № 2b - путь к подкаталогу не соответствует FQN
Если ваши классы FQN com.acme.example.Foon
затем JVM будет искать "Foon.class" в каталоге "com/acme/example":
Если ваша структура каталогов не соответствует именам пакетов, как показано выше, JVM не найдет ваш класс.
Если вы попытаетесь переименовать класс, переместив его, это тоже не удастся... но трассировка стека исключений будет другой.
Чтобы привести конкретный пример, предположим, что:
- ты хочешь бежать
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
и так далее.- Тщательно продумайте выбор между абсолютными и относительными путями в classpath. Помните, что относительный путь может "сломаться", если текущий каталог изменится.
Причина № 2c - зависимости отсутствуют в пути к классам
Путь к классам должен включать все другие (не системные) классы, от которых зависит ваше приложение. (Системные классы располагаются автоматически, и вам редко нужно беспокоиться об этом.) Для корректной загрузки основного класса JVM должна найти:
- сам класс.
- все классы и интерфейсы в иерархии суперклассов (например, см. класс Java присутствует в пути к классам, но запуск завершается неудачно с ошибкой: не удалось найти или загрузить основной класс)
- все классы и интерфейсы, на которые ссылаются с помощью объявления переменных или переменных, либо вызова метода или выражений доступа к полю.
(Примечание: спецификации JLS и JVM позволяют некоторой области для JVM загружать классы "лениво", и это может повлиять, когда выдается исключение загрузчика классов.)
Причина № 3 - класс был объявлен в неправильной упаковке
Иногда случается, что кто-то помещает файл с исходным кодом в неправильную папку в своем дереве исходного кода, или они пропускают package
декларация. Если вы сделаете это в 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
) и classpath указываются в МАНИФЕСТЕ файла JAR.
Иды
Типичная Java IDE поддерживает запуск приложений Java в самой JVM IDE или в дочерней JVM. Они, как правило, защищены от этого конкретного исключения, поскольку в среде IDE используются собственные механизмы для создания пути к классам среды выполнения, определения основного класса и создания java
командная строка.
Однако это исключение по-прежнему возможно, если вы делаете что-то за спиной IDE. Например, если вы ранее настроили Application Launcher для своего Java-приложения в Eclipse, а затем переместили файл JAR, содержащий класс "main", в другое место файловой системы, не сообщая Eclipse, Eclipse невольно запустит JVM с неправильным путем к классу.
Короче говоря, если вы столкнулись с этой проблемой в IDE, проверьте наличие таких вещей, как устаревшее состояние IDE, неработающие ссылки на проекты или неработающие конфигурации запуска.
Для IDE также возможно просто запутаться. IDE - это чрезвычайно сложные части программного обеспечения, состоящие из множества взаимодействующих частей. Многие из этих частей используют различные стратегии кэширования, чтобы сделать среду IDE в целом отзывчивой. Иногда они могут пойти не так, и одним из возможных симптомов являются проблемы при запуске приложений. Если вы подозреваете, что это может произойти, стоит перезапустить вашу IDE.
Другие ссылки
- Из Oracle Java Tutorials - Распространенные проблемы (и их решения)
Если ваш исходный код называется HelloWorld.java, ваш скомпилированный код будет HelloWorld.class
,
Вы получите эту ошибку, если позвоните с помощью:
java HelloWorld.class
Вместо этого используйте это:
java HelloWorld
Если ваши классы в пакетах, то вы должны cd
в основной каталог и запустите, используя полное имя класса (packageName.MainClassName).
Пример:
Мои занятия здесь:
D:\project\com\cse\
Полное имя моего основного класса:
com.cse.Main
Так что я cd
вернуться в основной каталог:
D:\project
Тогда выпустите java
команда:
java com.cse.Main
Если ваш метод main находится в классе в пакете, вы должны запустить его в иерархическом каталоге.
Предположим, что существует файл исходного кода (Main.java):
package com.test;
public class Main {
public static void main(String[] args) {
System.out.println("salam 2nya\n");
}
}
Для запуска этого кода, вы должны разместить Main.Class
в пакете как каталог ./com/test/Main.Java
, И в корневом каталоге использовать java com.test.Main
,
Когда один и тот же код работает на одном ПК, но на другом показывает ошибку, лучшее решение, которое я когда-либо нашел, - это компилировать, как показано ниже:
javac HelloWorld.java
java -cp . HelloWorld
Что помогло мне, так это указать classpath в командной строке, например:
Создать новую папку,
C:\temp
Создать файл Temp.java в
C:\temp
со следующим классом в нем:public class Temp { public static void main(String args[]) { System.out.println(args[0]); } }
Откройте командную строку в папке
C:\temp
и напишите следующую команду для компиляции класса Temp:javac Temp.java
Запустите скомпилированный класс Java, добавив
-classpath
возможность сообщить JRE, где найти класс:java -classpath C:\temp Temp Hello!
Согласно сообщению об ошибке ("Не удалось найти или загрузить основной класс"), существуют две категории проблем:
- Основной класс не может быть найден
- Не удалось загрузить основной класс (этот случай не полностью обсужден в принятом ответе)
Основной класс не может быть найден, если в полностью определенном имени класса присутствует опечатка или неправильный синтаксис или он не существует в указанном пути к классам.
Главный класс не может быть загружен, когда класс не может быть инициирован, обычно основной класс расширяет другой класс, и этот класс не существует в предоставленном пути к классам.
Например:
public class YourMain extends org.apache.camel.spring.Main
Если верблюжья пружина не включена, об этой ошибке будет сообщено.
Используйте эту команду:
java -cp . [PACKAGE.]CLASSNAME
Пример: если ваше имя класса - Hello.class, созданный из Hello.java, используйте следующую команду:
java -cp . Hello
Если ваш файл Hello.java находится внутри пакета com.demo, используйте команду ниже
java -cp . com.demo.Hello
С JDK 8 часто случается, что файл класса присутствует в той же папке, но java
команда ожидает classpath и по этой причине мы добавляем -cp .
взять текущую папку в качестве ссылки для classpath.
Попробуй -Xdiag.
Ответ Стива С. хорошо описывает возможные случаи, но иногда определить, не удалось ли найти класс или загрузить его, может быть не так просто. использование java -Xdiag
(начиная с 7 JDK). Это распечатывает красивую трассировку стека, которая дает подсказку к тому, что сообщение Could not find or load main class
сообщение означает.
Например, он может указать вам на другие классы, используемые основным классом, которые не могут быть найдены, и помешал загрузке основного класса.
У меня была такая ошибка в этом случае:
java -cp lib.jar com.mypackage.Main
Работает с ;
для Windows и :
для Unix:
java -cp lib.jar; com.mypackage.Main
Иногда то, что может вызывать проблему, не имеет никакого отношения к основному классу, и мне пришлось найти это трудным путем. Это была ссылочная библиотека, которую я переместил, и она дала мне:
Не удалось найти или загрузить основной класс ххх Linux
Я просто удалил эту ссылку, добавил ее снова, и она снова заработала.
У меня была та же проблема, и в конце концов я нашел свою ошибку:) Я использовал эту команду для компиляции, и она работала правильно.
javac -cp "/home/omidmohebbi/AAAATest/jars/core-1.7.jar:/home/omidmohebbi/AAAATest/jars/javase-1.7.jar:/home/omidmohebbi/AAAATest/jars/qrgen-1.2.jar" qrcode.java
но эта команда не работает для меня (не удалось найти или загрузить основной класс qrcode)
java -cp "/home/omidmohebbi/AAAATest/jars/core-1.7.jar:/home/omidmohebbi/AAAATest/jars/javase-1.7.jar:/home/omidmohebbi/AAAATest/jars/qrgen-1.2.jar" qrcode
Наконец, я просто добавил символ ":" в конец пути к классу, и проблема решена.
java -cp "/home/omidmohebbi/AAAATest/jars/core-1.7.jar:/home/omidmohebbi/AAAATest/jars/javase-1.7.jar:/home/omidmohebbi/AAAATest/jars/qrgen-1.2.jar:" qrcode
)
В этом случае у вас есть:
Не удалось найти или загрузить основной класс ?
Это потому, что вы используете "-classpath", но тире не то же самое, что используется java
в командной строке. У меня была эта проблема копирования и вставки из блокнота в cmd.
Если вы используете Maven для создания JAR-файла, обязательно укажите основной класс в файле 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>
Расположение файла класса: C: \ test \com\company
Имя файла: Main.class
Полностью определенное имя класса: com.company.Main
Команда командной строки:
java -classpath "C:\test" com.company.Main
Обратите внимание, что путь к классу НЕ включает \com\company
Все ответы здесь, похоже, направлены на пользователей Windows. Для Mac разделитель пути к классам :
не ;
, В качестве ошибки при установке classpath используется ;
не выбрасывается, то это может быть трудно обнаружить, переходя с Windows на Mac.
Вот соответствующая команда Mac:
java -classpath ".:./lib/*" com.test.MyClass
Где в этом примере пакет com.test
и lib
папка также должна быть включена в classpath.
В моем случае появилась ошибка, потому что я указал имя исходного файла вместо имени класса.
Нам нужно предоставить имя класса, содержащее метод main, интерпретатору.
Это может помочь вам, если ваш случай особенно похож на мой: как новичок я также столкнулся с этой проблемой, когда пытался запустить программу на Java.
Я скомпилировал это так:
javac HelloWorld.java
И я попытался запустить также с тем же расширением:
java Helloworld.java
Когда я удалил .java
и переписал команду как java HelloWorld
программа работала отлично.:)
Я потратил приличное количество времени, пытаясь решить эту проблему. Я думал, что каким-то образом неправильно устанавливал свой путь к классу, но проблема заключалась в том, что я набрал:
java -cp C:/java/MyClasses C:/java/MyClasses/utilities/myapp/Cool
вместо:
java -cp C:/java/MyClasses utilities/myapp/Cool
Я думал, что значение "полный" означает включение полного пути вместо полного имени пакета.
При запуске java
с -cp
Опция, объявленная в Windows PowerShell, может привести к ошибке, которая выглядит примерно так:
The term `ClassName` is not recognized as the name of a cmdlet, function, script ...
Чтобы PowerShell мог принять команду, аргументы -cp
опция должна содержаться в кавычках как в:
java -cp 'someDependency.jar;.' ClassName
Такое формирование команды должно позволить Java правильно обработать аргументы classpath.
На винду ставь .;
при значении CLASSPATH в начале.
. (точка) означает "смотреть в текущем каталоге". Это постоянное решение.
Также вы можете установить его "один раз" с помощью набора CLASSPATH=%CLASSPATH%;.
, Это будет продолжаться до тех пор, пока ваше окно cmd открыто.
Я также сталкивался с подобными ошибками при тестировании соединения JDBC Java MongoDB. Я думаю, что было бы хорошо кратко изложить мое окончательное решение, чтобы в будущем любой мог непосредственно изучить две команды и был готов продолжить.
Предположим, вы находитесь в каталоге, в котором находятся ваш файл Java и внешние зависимости (файлы JAR).
Обобщение:
javac -cp mongo-java-driver-3.4.1.jar JavaMongoDBConnection.java
- -cp - аргумент пути к классам; передать все зависимые файлы JAR один за другим
- *.java - это файл класса Java, который имеет метод main. SDSD
Бежать:
java -cp mongo-java-driver-3.4.1.jar: JavaMongoDBConnection
- Пожалуйста, соблюдайте двоеточие (Unix) / запятую (Windows) после завершения всех файлов JAR зависимости
- В конце обратите внимание на имя основного класса без каких-либо расширений (без.class или.java)
Сначала установите путь с помощью этой команды;
set path="paste the set path address"
Затем вам нужно загрузить программу. Введите "cd (имя папки)" на сохраненный диск и скомпилируйте его. Например, если моя программа хранится на диске D, введите "D:", нажмите enter и введите "cd (имя папки)".
Что исправило проблему в моем случае:
Щелкните правой кнопкой мыши проект / класс, который вы хотите запустить, затем Run As
->Run Configurations
, Затем вы должны либо исправить существующую конфигурацию, либо добавить новую следующим образом:
Открой Classpath
вкладку, нажмите на Advanced...
кнопку затем добавить bin
папка вашего проекта.
Это особый случай, но, поскольку я пришел на эту страницу в поисках решения и не нашел его, я добавлю его сюда.
Windows (протестировано с 7) не принимает специальные символы (например, á
) в именах классов и пакетов. Linux делает, хотя.
Я узнал об этом, когда построил .jar
в NetBeans и попытался запустить его в командной строке. Он работал в NetBeans, но не в командной строке.
В Java, когда вы иногда запускаете JVM из командной строки, используя исполняемый файл java, и пытаетесь запустить программу из файла класса с общедоступной статической void main (PSVM), вы можете столкнуться с приведенной ниже ошибкой, даже если параметр classpath JVM является точной, и файл класса присутствует в пути к классам:
Error: main class not found or loaded
Это происходит, если файл класса с PSVM не может быть загружен. Одной из возможных причин этого является то, что класс может реализовывать интерфейс или расширять другой класс, который не находится в пути к классам. Обычно, если класс не находится на пути к классам, выброшенная ошибка указывает как таковую. Но если используемый класс расширен или реализован, java не сможет загрузить сам класс.
Ссылка: https://www.computingnotes.net/java/error-main-class-not-found-or-loaded/
Вы действительно должны сделать это из src
папка. Там вы вводите следующую командную строку:
[name of the package].[Class Name] [arguments]
Допустим, ваш класс называется CommandLine.class
и код выглядит так:
package com.tutorialspoint.java;
/**
* Created by mda21185 on 15-6-2016.
*/
public class CommandLine {
public static void main(String args[]){
for(int i=0; i<args.length; i++){
System.out.println("args[" + i + "]: " + args[i]);
}
}
}
Тогда ты должен cd
в папку src и команду, которую нужно запустить, будет выглядеть так:
java com.tutorialspoint.java.CommandLine this is a command line 200 -100
И вывод в командной строке будет:
args[0]: this
args[1]: is
args[2]: a
args[3]: command
args[4]: line
args[5]: 200
args[6]: -100
Хорошо, много ответов уже, но никто не упомянул случай, когда разрешение файла может быть виновником. При запуске пользователь не имеет доступа к файлу jar или одному из каталогов пути. Например, рассмотрим:
Jar файл в /dir1/dir2/dir3/myjar.jar
Пользователь1, которому принадлежит банка, может сделать:
# Running as User1
cd /dir1/dir2/dir3/
chmod +r myjar.jar
Но это все еще не работает:
# Running as User2
java -cp "/dir1/dir2/dir3:/dir1/dir2/javalibs" MyProgram
Error: Could not find or load main class MyProgram
Это связано с тем, что работающий пользователь (User2) не имеет доступа к dir1, dir2, javalibs или dir3. Это может свести с ума кого-то, когда Пользователь1 может видеть файлы и может получить к ним доступ, но ошибка все еще происходит для Пользователя2
Иногда в некоторых онлайн-компиляторах, которые вы могли попробовать, вы получите эту ошибку, если не напишите public class [Classname]
но просто class [Classname]
,
Я не смог решить эту проблему с помощью решений, изложенных здесь (хотя указанный ответ, несомненно, очистил мои концепции). Я сталкивался с этой проблемой два раза и каждый раз пробовал разные решения (в Eclipse IDE).
- Во-первых, я сталкивался с несколькими
main
методы в разных классах моего проекта. Итак, я удалилmain
метод из последующих классов. - Во-вторых, я попробовал следующее решение:
- Щелкните правой кнопкой мыши по моему основному каталогу проекта.
- Идите к источнику, затем очистите и придерживайтесь настроек по умолчанию и на Finish. После некоторых фоновых заданий вы будете перенаправлены в основной каталог проекта.
- После этого я закрываю свой проект, снова открываю его, и бум, я наконец-то решил свою проблему.