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

общей проблемой, с которой сталкиваются новые разработчики Java, является то, что их программы не запускаются с сообщением об ошибке: Could not find or load main class ...

что это значит, что вызывает это и как вы должны это исправить?

30 ответов


на 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 ... не то, что я просто придумал, чтобы запутать вас: -)

вот пример должно выглядеть так:

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 не может найти класс

когда вы получаете сообщение " не удалось найти или загрузить основной класс ...- это значит, что первый шаг провалился. The java команда не смогла найти класс. И действительно,"..."в сообщении будет полное имя класса это java смотрит для.

так почему он не может найти класс?

Причина #1 - Вы допустили ошибку с аргументом classname

первой вероятной причиной является то, что вы, возможно, указали неправильное имя класса. (Или. .. правильное название класса, но в неправильной форме.) Учитывая приведенный выше пример, здесь разнообразие неправильные способы чтобы указать имя класса:

  • Пример № 1 - простой класс имя:

    java ListUser
    

    когда класс объявлен в пакете, таком как com.acme.example, то вы должны использовать полное имя класса в том числе имя пакета в , например,

    java com.acme.example.ListUser
    
  • Пример #2 - имя файла или путь, а не название класса:

    java ListUser.class
    java com/acme/example/ListUser.class
    
  • Пример #3 - имя класса с неправильным кожуха:

    java com.acme.example.listuser
    
  • Пример #4-a опечатка!--56-->

    java com.acme.example.mistuser
    
  • Пример #5-исходное имя файла

    java ListUser.java
    
  • Пример #6 - вы полностью забыли имя класса

    java lots of arguments
    

Причина #2-неверно указан путь к классам приложения

второй вероятной причиной является то, что имя класса правильно, но java команда не может найти класс. Чтобы понять это, вам нужно понять концепцию "путь класса." Это объясняется хорошо по документации Oracle:

так ... если вы правильно указали имя класса, следующее, что нужно проверить, - это то, что вы указали путь к классу правильно:

  1. прочитайте три документа, связанные выше. (Утвердительный ответ. .. читать их. Важно, чтобы программист Java понимает по крайней мере, основы того, как работают механизмы Java classpath.)
  2. посмотрите на командную строку и / или переменную среды CLASSPATH, которая действует при запуске . Проверьте правильность имен каталогов и файлов JAR.
  3. если есть относительные пути в пути к классам проверьте, правильно ли они разрешены ... из текущего каталога, который действует при запуске .
  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.класс "в каталоге" com/acme / example":

  • если ваша структура каталогов не соответствует пакету именование согласно приведенному выше шаблону, JVM не найдет ваш класс.

  • при попытке переименовать класс, перемещая его, это также потерпит неудачу ... но исключение stacktrace будет другим.

чтобы привести конкретный пример, предположим, что:

  • вы хотите работать 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 и так далее.
  • тщательно подумайте при выборе между абсолютными и относительными путями в classpaths. Помните, что относительный путь может "сломаться", если текущий каталог изменится.

причина #2c - зависимости отсутствует в classpath

путь к классам должен включать все другое (несистемные) классы, от которых зависит ваше приложение. (Системные классы расположены автоматически, и вам редко нужно беспокоиться об этом.) Для правильной загрузки основного класса JVM необходимо найти:

  • сам класс.
  • все классы и интерфейсы в иерархии суперкласса (например, см. этот вопрос)
  • все классы и интерфейсы, на которые ссылаются с помощью объявлений переменных или переменных, или вызова метода или выражений доступа к полю.

(Примечание: спецификации JLS и JVM позволяют некоторой области для JVM загружать классы "лениво", и это может повлиять на то, когда создается исключение classloader.)

Причина № 3 - класс был объявлен в неправильном пакет

иногда случается, что кто-то ставит файл исходного кода в неправильная папка в дереве исходного кода, или они оставляют package декларации. Если вы сделаете это в IDE, компилятор IDE немедленно сообщит вам об этом. Аналогично, если вы используете приличный инструмент сборки Java, инструмент будет работать javac таким образом, чтобы обнаружить проблему. Однако, если вы создадите свой Java-код вручную, вы можете сделать это таким образом, чтобы компилятор не заметил проблему, а в результате ".класс " файл не находится в том месте, где вы ожидайте этого.

все еще не можете найти проблему?

там много вещей, чтобы проверить, и это легко пропустить что-то. Попробуйте добавить до java командная строка (как первое после java). Он выведет различные вещи о загрузке класса, и это может предложить вам подсказки о том, в чем настоящая проблема.

кроме того, рассмотрите возможные проблемы, вызванные копированием и вставкой невидимых или не-ASCII символов с веб-сайтов, документы и так далее. И рассматривать "homoglyphs", две буквы или символы выглядят одинаково ... но нет.


на 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) и путь к классам указаны в манифесте файла JAR.


IDEs

A типичная Java IDE поддерживает запуск Java-приложений в самой IDE JVM или в дочерней JVM. Это вообще иммунный от этого конкретного исключения, потому что IDE использует свои собственные механизмы для построения пути к классам среды выполнения, определения основного класса и создания java командная строка.

однако это исключение все еще возможно, если вы делаете что-то за спиной IDE. Например, если вы ранее настроили приложение Launcher для вашего Java-приложения в Eclipse, а затем вы переместили файл JAR, содержащий класс "main", в другое место в файловой системе не говоря Eclipse, Eclipse невольно запустит JVM с неправильным путем к классам.

короче говоря, если вы получаете эту проблему в 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 com.cse.Main

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

предположим, что есть файл исходного кода (Main.java):

package com.test;

public class Main {

    public static void main(String[] args) {
        System.out.println("salam 2nya\n");
    }
}

для запуска этого кода Вы должны разместить Main.Class в пакете like directory ./com/test/Main.Java. А в корневом каталоге используйте java com.test.Main.


когда тот же код работает на одном ПК, но он показывает ошибку в другом, лучшее решение, которое я когда-либо находил, компилируется следующим образом:

javac HelloWorld.java
java -cp . HelloWorld

что мне помогло, так это указать путь к классам в командной строке, например:

  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

Если camel-spring не включен, эта ошибка будет сообщена.


иногда то, что может быть причиной проблемы, не имеет никакого отношения к основному классу, и мне пришлось выяснить это сложным способом. Это была ссылочная библиотека, которую я переместил, и она дала мне:

не удалось найти или загрузить основной класс xxx Linux

Я просто удалил эту ссылку, добавил ее снова, и она снова работала нормально.


у меня была такая ошибка в этом случае:

java -cp lib.jar com.mypackage.Main

Он работает с ; для Windows и : для Unix:

java -cp lib.jar; com.mypackage.Main

используйте эту команду:

java -cp . [PACKAGE.]CLASSNAME

пример: Если ваше имя Привет.класс, созданный из Здравствуйте.затем java использует следующую команду:

java -cp . Hello

если ваш файл Здравствуйте.java находится внутри пакета com.затем используйте следующую команду

java -cp . com.demo.Hello

С JDK 8 много раз случается, что файл класса присутствует в той же папке, но ожидает classpath и по этой причине мы добавляем -cp . чтобы взять текущую папку как ссылка для пути к классам.


попробовать -Xdiag.

ответ Стива Си охватывает возможные случаи красиво, но иногда, чтобы определить, не может ли класс быть нашел или загружается может быть не так легко. Использовать java -Xdiag (начиная с JDK 7). Это печатает хороший stacktrace, который дает намек на то, что сообщение Could not find or load main class сообщения.

например, он может указывать на другие классы, используемые основным классом, которые не удалось найти и не удалось загрузить основной класс.


в этом случае у вас есть:

не удалось найти или загрузить основной класс ?путь к классу

это потому, что вы используете "- classpath", но тире не то же самое тире, используемое java в командной строке. У меня была эта проблема копирования и вставки из Блокнот к cmd.


в моем случае появилась ошибка, потому что я предоставил имя исходного файла вместо имени класса.

мы должны указать имя класса, содержащего метод main для переводчика.


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

я скомпилировал его такой:

javac HelloWorld.java

и я попытался запустить также с тем же расширением:

java Helloworld.java

когда я убрал .java и переписать команду как java HelloWorld программа отлично бегал. :)


enter image description here

Расположение файла класса: C:\test\com\company

Имя Файла: Main.класс!--5-->

полное имя класса: com.компания.Главная

командную строку:

java  -classpath "C:\test" com.company.Main

обратите внимание, что путь к классу не включает \com\company


Если вы используете 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>

Я потратил приличное количество времени, пытаясь решить эту проблему. Я думал, что я как-то неправильно устанавливаю свой путь к классам, но проблема заключалась в том, что я набрал:

java -cp C:/java/MyClasses C:/java/MyClasses/utilities/myapp/Cool  

вместо:

java -cp C:/java/MyClasses utilities/myapp/Cool   

Я думал, что значение Full qualified означает включать полное имя пути вместо полного имени пакета.


сначала задать путь с помощью этой команды;

set path="paste the set path address"

затем вам нужно загрузить программу. Введите "cd (имя папки)" в сохраненном диске и скомпилируйте его. Например, если моя программа хранится на диске D, введите "D:" нажмите enter и введите " cd (имя папки)".


что решил проблему в моем случае было:

щелкните правой кнопкой мыши на проект класса, который вы хотите запустить, затем Run As ->Run Configurations. Затем вы должны либо исправить существующую конфигурацию или добавить новую следующим образом:

открыть Classpath вкладка, нажмите на добавить bin папку вашего проекта.


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

Windows (тестируется с 7) не принимает специальные символы (например,á) в именах классов и пакетов. Linux, хотя не.

я узнал это, когда я построил .jar в NetBeans и попытался запустить его в командной строке. Он работал в NetBeans, но не в командной строке.


все ответы здесь направлены на пользователей Windows, похоже. Для Mac разделителем пути к классам является :, а не ;. В качестве ошибки установка пути к классам с помощью ; не бросается, то это может быть трудно обнаружить, если из Windows на Mac.

вот соответствующая команда Mac:

java -classpath ".:./lib/*" com.test.MyClass

где в этом примере пакет com.test и lib папка также должна быть включена в classpath.


при выполнении 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 правильно обрабатывать аргументы пути к классам.


иногда в некоторых онлайн-компиляторах, которые вы могли бы попробовать, вы получите эту ошибку, если не напишете public class [Classname], но только class [Classname].


хорошо, многие ответы уже, но никто не упомянул случай, когда разрешение файла может быть виновником. При запуске пользователь не имеет доступа к файлу jar или одному из каталогов пути. Например рассмотрим:

файл Jar в /dir1/dir2/dir3/myjar.jar

User1 кто владеет банку может сделать:

# 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. Он может свести кого-то с ума, когда User1 может видеть файлы и может получить к ним доступ, но ошибка все еще происходит для User2


на Windows поставить .; при значении пути к классам в начале.

The . (точка) означает "искать в текущем каталоге". Это постоянное решение.

Также вы можете установить его "один раз" с set CLASSPATH=%CLASSPATH%;.. Это будет продолжаться до тех пор, пока открыто окно cmd.


вам действительно нужно сделать это из . Там вы вводите следующую командную строку:

[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

в моем случае я получил ошибку, потому что у меня были смешанные имена пакетов верхнего и нижнего регистра в системе Windows 7. Изменение имен пакетов на все строчные буквы решило проблему. Обратите внимание также, что в этом сценарии я не получил ошибки компиляции.java-файл в a .class file; он просто не будет работать из того же (sub-sub-sub-) каталога.


Я также столкнулся с аналогичными ошибками при тестировании соединения Java MongoDB JDBC. Я думаю, что хорошо резюмировать мое окончательное решение вкратце, чтобы в будущем любой мог непосредственно взглянуть на две команды и хорошо продолжить.

предположим, что вы находитесь в каталоге, где существуют ваши Java-файл и внешние зависимости (JAR-файлы).

Compile:

javac -cp mongo-java-driver-3.4.1.jar JavaMongoDBConnection.java
  • - cp - аргумент classpath; передайте все зависимые файлы JAR один за другим
  • *.java-это файл класса Java, который имеет метод main. sdsd

Run:

java -cp mongo-java-driver-3.4.1.jar: JavaMongoDBConnection
  • пожалуйста, соблюдайте двоеточие (Unix) / запятую (Windows) после того, как все файлы jar зависимостей заканчиваются
  • в конце соблюдайте основное имя класса без какого-либо расширения (нет .класс или. java)

У меня был странный.

ошибка: не удалось найти или загрузить основной класс пакета mypackage.App

оказалось, что у меня была настройка pom (parent) в pom моего проекта.xml (pom моего проекта.xml указывал на родительский pom.xml), и относительный путь был выключен/ошибочен.

Ниже приведена часть pom моего проекта.в XML

<parent>
    <groupId>myGroupId</groupId>
    <artifactId>pom-parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <relativePath>../badPathHere/pom.xml</relativePath>
</parent> 

после того как я решен пом и relativepath, ошибка ушла.

идите на фиг.


в Java, когда вы иногда запускаете JVM из командной строки с помощью исполняемого файла java и пытаетесь запустить программу из файла класса с public static void main( PSVM), вы можете столкнуться с приведенной ниже ошибкой, даже если параметр classpath для JVM является точным, и файл класса присутствует на classpath:

Error: main class not found or loaded

это происходит, если не удалось загрузить файл класса с PSVM. Одной из возможных причин этого является то, что класс может реализовать интерфейс или расширение другого класса, который не находится на пути к классам. Обычно, если класс не находится на пути к классам, вызванная ошибка указывает как таковая. Но если используемый класс расширен или реализован, java не может загрузить сам класс.

ссылка:https://www.computingnotes.net/java/error-main-class-not-found-or-loaded/