Что означает "Не удалось найти или загрузить основной класс"?

Общая проблема, с которой сталкиваются новые 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 Команда сделать следующее:

  1. Поиск скомпилированной версии com.acme.example.ListUsers учебный класс.
  2. Загрузите класс.
  3. Проверьте, что у класса есть main метод с сигнатурой, типом возвращаемого значения и модификаторами, заданными public static void main(String[]), (Обратите внимание, что имя аргумента метода НЕ является частью подписи.)
  4. Вызовите этот метод, передав ему аргументы командной строки ("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:

Итак... если вы правильно указали имя класса, то следует проверить, правильно ли вы указали путь к классу:

  1. Прочитайте три документа, ссылки на которые приведены выше. (Да... ПРОЧИТАЙТЕ их. Важно, чтобы программист Java понимал хотя бы основы того, как работают механизмы пути классов Java.)
  2. Посмотрите на командную строку и / или переменную среды CLASSPATH, которая действует при запуске java команда. Проверьте правильность имен каталогов и файлов JAR.
  3. Если в пути к классам есть относительные имена путей, проверьте, что они разрешаются правильно... из текущего каталога, который действует при запуске java команда.
  4. Убедитесь, что класс (упомянутый в сообщении об ошибке) может быть расположен на эффективном пути к классам.
  5. Обратите внимание, что синтаксис пути к классам отличается для 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 должна найти:

(Примечание: спецификации 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.


Другие ссылки

Если ваш исходный код называется 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 в командной строке, например:

  1. Создать новую папку, C:\temp

  2. Создать файл Temp.java в C:\tempсо следующим классом в нем:

    public class Temp {
        public static void main(String args[]) {
            System.out.println(args[0]);
        }
    }
    
  3. Откройте командную строку в папке C:\tempи напишите следующую команду для компиляции класса Temp:

    javac Temp.java
    
  4. Запустите скомпилированный класс Java, добавив -classpath возможность сообщить JRE, где найти класс:

    java -classpath C:\temp Temp Hello!
    

Согласно сообщению об ошибке ("Не удалось найти или загрузить основной класс"), существуют две категории проблем:

  1. Основной класс не может быть найден
  2. Не удалось загрузить основной класс (этот случай не полностью обсужден в принятом ответе)

Основной класс не может быть найден, если в полностью определенном имени класса присутствует опечатка или неправильный синтаксис или он не существует в указанном пути к классам.

Главный класс не может быть загружен, когда класс не может быть инициирован, обычно основной класс расширяет другой класс, и этот класс не существует в предоставленном пути к классам.

Например:

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 метод из последующих классов.
  • Во-вторых, я попробовал следующее решение:
    1. Щелкните правой кнопкой мыши по моему основному каталогу проекта.
    2. Идите к источнику, затем очистите и придерживайтесь настроек по умолчанию и на Finish. После некоторых фоновых заданий вы будете перенаправлены в основной каталог проекта.
    3. После этого я закрываю свой проект, снова открываю его, и бум, я наконец-то решил свою проблему.
Другие вопросы по тегам