Обычная проблема, с которой сталкиваются новые разработчики Java, заключается в том, что их программы не запускаются с сообщением об ошибке: Could not find or load main class ...
Что это означает, в чем причина и как это исправить?
Обычная проблема, с которой сталкиваются новые разработчики Java, заключается в том, что их программы не запускаются с сообщением об ошибке: Could not find or load main class ...
Что это означает, в чем причина и как это исправить?
java <class-name>
Прежде всего, вам необходимо понять, как правильно запускать программу с помощью команды java
(или javaw
).
Обычный синтаксис 1 следующий:
java [ <options> ] <class-name> [<arg> ...]
, где <option>
- параметр командной строки (начинается с символа «-»), <class-name>
- полное имя класса Java, а <arg>
- произвольный аргумент командной строки, который передается вашему приложению.
1 - Есть некоторые другие синтаксисы, которые описаны в конце этого ответа.
Полное имя (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
с сигнатурой , типом возврата и модификаторами , заданными <469> .173989 (Обратите внимание, что имя аргумента метода - НЕ часть подписи.) String[]
. Когда вы получаете сообщение «Не удалось найти или загрузить основной класс ...», это означает, что первый шаг завершился неудачно. Команде 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 11 или новее; см. Ниже)
java ListUser.java
Пример №6 - вы полностью забыли имя класса
java lots of arguments
Вторая вероятная причина заключается в том, что имя класса правильное, но команда java
не может найти класс. Чтобы понять это, вам нужно понять концепцию «пути к классам». Это объясняется колодцем в документации Oracle:
java
Итак ... если вы правильно указали имя класса, следующее, что нужно проверить, это правильно ли вы указали путь к классам:
java
. Проверьте правильность имен каталогов и файлов JAR. java
. ;
в Windows и :
в остальных. Если вы используете неправильный разделитель для своей платформы, вы не получите явного сообщения об ошибке. Вместо этого вы получите несуществующий файл или каталог на путь, который будет автоматически проигнорирован.) Когда вы помещаете каталог в путь к классам, он условно соответствует корню квалифицированного пространства имен. Классы располагаются в структуре каталогов ниже этого корня, , путем сопоставления полного имени с именем пути . Так, например, если «/ 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 не смогла бы найти класс.
Если FQN вашего класса com.acme.example.Foon
, тогда JVM будет искать "Foon.class" в каталоге "com / acme / example":
Если ваша структура каталогов не соответствует названию пакета согласно приведенному выше шаблону, JVM не найдет ваш класс.
Если вы попытаетесь переименовать класс, переместив его, это тоже не удастся ... но трассировка стека исключений будет другой. Можно сказать что-то вроде этого:
Caused by: java.lang.NoClassDefFoundError: <path> (wrong name: <name>)
, поскольку FQN в файле класса не соответствует тому, что загрузчик классов ожидает найти.
Чтобы дать конкретный пример, предположим, что:
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 должна найти:
(Примечание: спецификации JLS и JVM позволяют JVM в некоторой степени загружать классы «лениво», и это может повлиять на возникновение исключения загрузчика классов.)
Иногда случается, что кто-то помещает файл исходного кода в
неправильная папка в дереве исходного кода, или они не учитывают объявление package
. Если вы сделаете это в IDE, компилятор IDE немедленно сообщит вам об этом. Точно так же, если вы используете достойный инструмент сборки Java, инструмент запустит javac
таким образом, чтобы обнаружить проблему. Однако, если вы создадите свой Java-код вручную, вы можете сделать это таким образом, чтобы компилятор не заметил проблемы, и получившийся файл ".class" оказался не там, где вы ожидали.
Здесь есть что проверить, и легко что-то упустить. Попробуйте добавить параметр -Xdiag
в командную строку java
(в первую очередь после java
). Он выведет различные сведения о загрузке классов, и это может предложить вам ключ к разгадке истинной проблемы.
Также рассмотрите возможные проблемы, вызванные копированием и вставкой невидимых или не-ASCII символов с веб-сайтов, документов и т. Д. И рассмотрим «гомоглифы», где две буквы или символы выглядят одинаково ... но не являются.
Наконец, вы, очевидно, можете столкнуться с этой проблемой, если попытаетесь запустить из файла JAR с неправильными подписями в (META-INF/*.SF)
или если есть синтаксическая ошибка в файле MANIFEST.MF
(см. Https://coderhelper.com / a / 67145190/139985).
java
Есть три альтернативных синтаксиса для запуска программ Java с использованием java command
.
Для запуска «исполняемого» файла JAR используется следующий синтаксис:
java [ <options> ] -jar <jar-file-name> [<arg> ...]
например,
java -Xmx100m -jar /usr/local/acme-example/listuser.jar fred
Имя класса точки входа (т.е. com.acme.example.ListUser
) и путь к классам указаны в МАНИФЕСТЕ файла JAR.
Синтаксис для запуска приложения из модуля (Java 9 и новее) следующий:
java [ <options> ] --module <module>[/<mainclass>] [<arg> ...]
Имя класса точки входа либо определяется самим <module>
, либо задается необязательным <mainclass>
.
Начиная с Java 11, вы можете использовать команду java
для компиляции и запуска одного файла исходного кода, используя следующий синтаксис:
java [ <options> ] <sourcefile> [<arg> ...]
, где <sourcefile>
- (обычно) файл с суффиксом ".java".
Дополнительные сведения см. В официальной документации по команде java
для используемой версии Java.
Типичная Java IDE поддерживает запуск приложений Java в самой JVM IDE или в дочерней JVM. Они обычно невосприимчивы к этому конкретному исключению, потому что IDE использует свои собственные механизмы для создания пути к классам среды выполнения, идентификации основного класса и создания командной строки java
.
Однако это исключение все еще возможно, если вы делаете что-то за спиной IDE. Например, если вы ранее настроили средство запуска приложений для своего Java-приложения в Eclipse, а затем переместили файл JAR, содержащий «основной» класс, в другое место в файловой системе , не сообщая Eclipse , Eclipse непреднамеренно запустит JVM с неправильным путем к классам.
Короче говоря, если вы столкнулись с этой проблемой в среде IDE, проверьте такие вещи, как устаревшее состояние IDE, неработающие ссылки на проекты или неверные конфигурации средства запуска.
IDE также может запутаться. IDE - это чрезвычайно сложные программные продукты, состоящие из множества взаимодействующих частей. Многие из этих частей используют различные стратегии кэширования, чтобы сделать среду IDE отзывчивой. Иногда они могут пойти не так, и одним из возможных симптомов являются проблемы при запуске приложений. Если вы подозреваете, что это могло произойти, стоит попробовать другие вещи, такие как перезапуск IDE, пересборка проекта и т. Д.
У меня возникла эта проблема, когда я пытался запустить класс со сторонней библиотекой. Я вызвал Java так: java -cp ../third-party-library.jar com.my.package.MyClass
; это не работает, вместо этого необходимо добавить локальную папку в путь к классу (разделить :
, например: java -cp ../third-party-library.jar:. com.my.package.MyClass
, тогда он должен работать
После многих лет программирования на Java мне все же удалось оказаться на этой странице. Для меня проблема заключалась в том, что синтаксис пути к классам зависит от ОС. Я новичок в программировании на Windows и понятия не имел.
Дополнительные примечания, пункт 2 спасите меня! Печально видеть, что java
не говорит, что он не находит импортированный класс, а вместо этого указывает основной класс, который вы пытаетесь запустить. Это заблуждение, хотя я уверен, что для этого есть причина. У меня был случай, когда java
точно знал, где находится мой класс, но не смог найти ни одного из импортированных классов. Вместо того, чтобы сказать это, он пожаловался на то, что не нашел мой основной класс. Действительно, раздражает.
У меня дважды возникала эта проблема в Eclipse. В первый раз подпись main () была неправильной. Во второй раз я переименовал .jar, и хотя я добавил новый в путь сборки, Eclipse не нашел старый, поэтому проект не скомпилировался с этой ошибкой. Мне пришлось удалить файл .jar из Project> Properties> Java Build Path> Libraries.
Я столкнулся с этим в третий раз. Я запустил программу из командного файла Windows 10 и поместил имя .jar в переменную (вызываемую с помощью "-cp% jarname%; lib *"). Я по ошибке поставил лишний пробел в конце имени jarname, и это вызвало ошибку. Хет-трик :)
В моем случае с spark2-submit Error: Could not find or load main class =
без имени класса в заявлении об ошибке было вызвано ошибкой файла spark.properties, где у меня были пробелы вокруг знака =
в spark.driver.extraJavaOptions -Dlog4j.configuration = log4j.properties
, объявленном как часть spark2- отправить параметр строки cmd --files hdfs://.../log4j.properties
. Удаление всех пробелов, исправленных во всех похожих строках, решило эту проблему.
@lanoxx: Я согласен, что это сбивает с толку, поскольку поведение по умолчанию, когда не задан путь к классам, включает текущий каталог. Если вы установите путь к классам, это значение по умолчанию будет перезаписано указанным вами путем к классам. Причина в том, что вы можете не захотеть включать CWD - часто для предотвращения загрузки нежелательного / неизвестного класса.
Мне нужно было включить текущий каталог и использовать; вместо того :
Для меня было откровением, что использования параметра -cp в командной строке самого по себе было недостаточно, если переменная CLASSPATH никогда не была установлена, например на недавно настроенной машине. Как только я определился в оболочке, все заработало. Кто бы мог подумать!
Я прочитал весь этот пост и так много узнал, и что на самом деле сработало для меня, так это самая последняя строчка - «стоит попробовать другие вещи, например, перезапустить вашу IDE». ржу не могу
Невероятно подробный комментарий. Моя проблема была 2c, не мог найти ее в другом месте. Спасибо за помощь.
Очень подробное объяснение. Цените терпение !! Для меня в eclipse IDE очистка и перестройка проекта решили проблему.
Причина № 2b - это то, с чем, вероятно, борются большинство новичков - если вы привыкли к .Net, сначала может показаться странным, что структура каталогов должна иметь значение.
На самом деле, исходя из моих наблюдений (людей, которые задают вопросы, которые закрыты как дубликаты этого), # 2b встречается довольно редко. №2 и №2а встречаются гораздо чаще.
Микаэль Майер - Ваше добавление уже описано в Причине №2, а не в 6. Итак, я откатил его.
Если имя вашего пакета javatpoint и имя пакета com.javatpoint и имя класса Другой ваш класс<566085084, затем скомпилируйте так:
cd C:\Users\JAY GURUDEV\eclipse-workspace\javatpoint\src\com\javatpoint
javac AnotherOne.java
И запустите этот класс, используя
cd C:\Users\JAY GURUDEV\eclipse-workspace\javatpoint\src
java com.javatpoint.AnotherOne
(Здесь следует исключить имя пакета.)
Я отредактировал формат вашего сообщения (исполняемые блоки), поэтому, пожалуйста, следите за форматированием в своих следующих сообщениях. Кроме того, какова добавленная стоимость по сравнению с этим ответом? (тот же пост) coderhelper.com/questions/18093928/…
да, я не видел этого ответа должным образом, поэтому .. спасибо за редактирование @LefterisXris
В основном это означает, что не существует статического метода main(String[] args)
. Это должно разрешить это автоматически. Если нет, то что-то было не так, когда программа создавалась (у нее нет основного метода) или когда программа была упакована (неверная информация в манифесте).
Это работает
public class Hello {
public static void main(String[] args) {
System.out.println("Hello");
}
}
Это не работает
public class Hello {
public Hello() {
System.out.println("Hello");
}
}
Этот ответ вводит в заблуждение. Исключение + сообщение может быть вызвано многими разными причинами. Это НЕ "в основном" вызвано одной вещью.
И... на самом деле... если ваш "основной" класс (Hello
в вашем примере) не содержит подходящего метода main
, вы фактически получите другое исключение + сообщение. Так что ваш ответ даже не по поводу вопроса.
Самый простой способ исправить это - повторно загрузить maven apache здесь: https://maven.apache.org/download.cgi
, чем вы снова задаете свой путь
СИСТЕМНАЯ ПЕРЕМЕННАЯ
укажите путь, по которому вы установили свою папку apache maven, например: C: \ Program Files \ apache-maven-3.8.4 \ bin
Перезагрузите терминал или IDE, и все должно работать.
У меня всегда работает.
Если вы не запускаете проект maven, попробуйте проверить свой java PATH, иногда, если путь java не установлен, ваша программа не запускается, потому что не удается найти основной класс.
Я поднялся на один уровень выше. Итак, теперь файл HelloWorld.class находится в hello \ HelloWorld.class и запускается под командой. Где cp - путь к классам, а. означает проверку только в текущем каталоге.
java -cp . hello.HelloWorld
Вывод
Hello world!
Я столкнулся с этой ошибкой при попытке выполнить этот код, написанный на intellij idea на компиляторе onlinegdb.
Для меня комментарий к этой строке помог мне предотвратить эту ошибку.
//package com.company;
Не хотите ли объяснить, почему он это исправил?
Да, поэтому в основном я пытался запустить java-код за пределами пакета com.company, поэтому, комментируя эту часть, он был отключен, и я также смог запустить его в онлайн-gdb
Если вам нужно это сделать, чтобы он заработал, Online Gdb в основном не работает.
Ожидается лучшее объяснение
Исключение следующих файлов решило проблему.
META-INF / *. SF
META-INF / *. DSA
META-INF / *. RSA
Добавлен следующий код в build.gradle
jar {
from {
configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
}
{
exclude "META-INF/*.SF"
exclude "META-INF/*.DSA"
exclude "META-INF/*.RSA"
}
manifest {
attributes(
'Main-Class': 'mainclass'
)
}
}
Почему это решило проблему? Что ты на самом деле здесь делаешь? Это похоже на взлом, который вы могли бы сделать, если бы вы изменяли подписанный JAR-файл. Пожалуйста, объясните, что вы на самом деле делаете ... чтобы люди могли решить, соответствует ли ваше решение "это работает для меня" тому, что они делают.
Вот как я решил свою проблему.
Я заметил, что если вы включаете файлы jar в свою компиляцию, добавление текущего каталога (./) в путь к классам помогает.
javac -cp "abc.jar; efg.jar" MyClass.java
java -cp "abc.jar; efg.jar" MyClass
VS
javac -cp " ./ ; abc.jar; efg.jar" MyClass.java
java -cp " ./ ; abc.jar; efg.jar" MyClass
Это не должно иметь никакого значения. Обе формы допустимы для Java и эквивалентны.
Я буду редактировать, путь к классам "./" имеет самое большое значение.
Ну да. Неправильный путь к классам - причина №2 принятого ответа. И обратите внимание, что ваше конкретное исправление работает только при некоторых обстоятельствах. (Например, он не будет работать в MacOS или Linux.)
Причина № 2 - неверно указан путь к классам приложения. Прочтите три документа, ссылки на которые приведены выше. (Да ... ПРОЧИТАЙТЕ их! Важно, чтобы программист на Java понимал хотя бы основы того, как работают механизмы пути к классам Java.) Я хочу добавить эту документацию в этот очень хороший пост сверху Общая информация об инструментах и утилитах JDK ( структура файла, путь к классам, способ нахождения классов, изменения) Улучшения (улучшения в JDK 7) Стандартные инструменты и утилиты JDK https://docs.oracle.com/javase/7/docs/technotes/tools/index.html https://docs.oracle.com/javase/7/docs/technotes/tools/findingclasses.html https://docs.oracle.com/javase/7/docs/technotes/ tools / windows / classpath.html Как средство запуска Java находит классы Понимание пути к классам и имен пакетов https://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javac. html
Загрузчик классов в Java Загрузчик классов Java - это часть среды выполнения Java, которая динамически загружает классы Java в виртуальную машину Java. Системе времени выполнения Java не нужно знать о файлах и файловых системах из-за загрузчиков классов.
Классы Java загружаются в память не сразу, а по требованию приложения. На этом этапе JRE вызывает Java ClassLoader, и эти ClassLoader загружают классы в память динамически. https://en.wikipedia.org/wiki/Java_Classloader https://www.geeksforgeeks.org/classloader-in-java/ https: // ru. wikipedia.org/wiki/Java_virtual_machine
Спасибо, но нет. Поведение иерархий загрузчиков классов вряд ли станет причиной проблем читателя. Если вы посмотрите на причину № 2, вы заметите, что она написана как и побуждает читателя пойти куда-нибудь еще для объяснения пути к классам и связанных вещей. Я принял осознанное и взвешенное решение сделать это. (В идеале должен быть еще один канонический вопрос и ответ, описывающий это. Также обратите внимание, что люди уже жалуются, что мой ответ на этот вопрос уже слишком длинный.
[Версия Java: 11]
Если вы используете Java 11, вам не нужно компилировать и запускать файл java.
Просто запустите как
Java ClassName.java
Пример:
class abc{
public static void main(String[] args){
System.out.println("hello Jarvis ");
}
}
Теперь запустите команду
java abc.java
1) Не отвечает на вопрос. 2) Альтернатива №3 «Альтернативные синтаксисы для java».
Сценарий: с использованием командной строки ( CMD в Windows) для компиляции и запуска только <1437141085713> простой программы, которая имеет только <14371410> Файл ' Main.java ' с указанным ' основным пакетом '.
Путь к исходному файлу:
папка-имя-проекта \ src \ main \ Main.java
Целевая папка:
некоторая-папка-имя-проекта \ dest
Путь к целевому файлу (папка \ main и файл \ Main.class будут созданы javac):
папка-имя-проекта \ dest \ main \ Main.class
Main.java выглядит следующим образом:
package main;
public class Main {
public static void main(String[] args) {
System.out.println("Hello world");
}
}
Составление:
// 'javac' compiler will produce 'Main.class' in the 'dest\main' folder.
// 'main' folder is created because in the source file(in our case: 'Main.java') is
// specified 'package main'.
javac -d ./dest ./src/main/Main.java
Запустить скомпилированный файл (в нашем случае: Main.class):
// '-cp'(is the same as '-classpath')
// './dest'(means destination folder, where resides compiled 'Main.class').
// 'main.Main'(means 'package' 'main', which contains class 'Main'('Main.class'))
// WARNING: when run 'java' class, MUST NOT type extension '.class'
// after 'class name
// (in our case: 'main.Main'(<package>.<class-name>) WITHOUT extension
// '.class').
java -cp ./dest main.Main
// Hello world
Говорит то же, что и coderhelper.com/a/26587225/139985 (с 2014 г.)
После двух дней поиска я нашел это решение, и оно работает. Это довольно странно, но у меня работает.
package javaapplication3;
public class JavaApplication3 {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
System.out.println("Hello");
}
}
это моя программа, которую я хочу запустить, которая находится в C: \ Java Projects \ JavaApplication3 \ src \ javaapplication3
Теперь откройте cmd в этом месте и скомпилируйте программу с помощью этой команды
javac JavaApplication3.java
После компиляции перейдите на один каталог вниз, т.е. C: \ Java Projects \ JavaApplication3 \ src
теперь выполните следующую команду для выполнения программы
java javaapplication3.JavaApplication3
Если это сработает для вас, то в вашем исходном коде должен быть оператор package javaapplication3;
, который вы не включили в ответ.
@StephenC Ооо, мне очень жаль, что я включил, что я обновлю свой ответ.
Теперь он говорит по сути то же самое, что и coderhelper.com/a/26587225/139985 (с 2014 г.)
Еще один сценарий, который заставил меня почесать голову, и я не нашел здесь ссылки на него:
package com.me
Public class Awesome extends AwesomeLibObject {
....
public static void main(String[] argv) {
System.out.println("YESS0");
}
}
Где AwesomeLibObject - это класс, определенный во внешней библиотеке. У меня такое же сбивающее с толку сообщение об ошибке:
Error: Could not find or load main class com.Awesome
Решение простое: внешняя библиотека также должна быть в пути к классам!
Причина # 2c - неверный путь к классам / отсутствует зависимость
Если вы используете IntelliJ и получаете сообщение об ошибке при запуске основного метода из IDE, просто убедитесь, что ваш класс находится в пакете java
, а не в kotlin
У меня возникла эта проблема для моей демонстрационной программы, созданной в IntelliJ.
Есть два ключевых момента для решения этой проблемы:
моя демонстрационная программа:
package io.rlx.tij.c2;
public class Ex10 {
public static void main(String[] args) {
// do something
}
}
путь к исходному коду:
../projectRoot/src/main/java/io/rlx/tij/c2/Ex10.java
java
каталог: cd ../projectRoot/src/main/java
javac ./io/rlx/tij/c2/Ex10.java
java io.rlx.tij.c2.Ex10
, если я запускаю программу в ../projectRoot/src/main/java/io/rlx/tij/c2
или запускаю ее без имени пакета, я получаю следующую ошибку: Error: Could not find or load main class
.
Говорит то же, что и coderhelper.com/a/26587225/139985 (с 2014 г.)
Вот еще одна проблема, на которую у меня ушло немного времени: параметр пути к классу в командной строке ведет себя не так, как вы ожидаете. Я использую MacOS и вызываю интерфейс командной строки напрямую, и я включаю в вызов два jar-файла.
Например, оба они сбивали инструмент с толку относительно имени основного класса:
Этот, потому что звездочка заставляла его неправильно анализировать аргументы:
java -cp path/to/jars/* com.mypackage.Main
А этот, потому что - я не уверен, почему:
java -cp "*.jar" com.mypackage.Main
Это сработало:
java -cp "path/to/jars/*" com.mypackage.Main
Явное перечисление двух jar-файлов также работало:
java -cp path/to/jars/jar1.jar:path/to/jars/jar2.jar com.mypackage.Main
«Я не уверен, почему» - потому что *
расширяется оболочкой до списка имен файлов JAR , разделенных пробелами ... если они не заключены в кавычки. Это стандартная оболочка UNIX. Что касается остального: все это в ручном вводе java
, включая использование :
и синтаксис подстановочных знаков ("path/to/jars/*"
).
Это было «не уверен, почему» * .jar «не работает». Первый был более очевидным, потому что с ним возился снаряд.
Второй не работает, потому что команда java
не распознает этот подстановочный знак. Руководство java
объясняет, что в нем понимается.
Это случилось и со мной. В моем случае это произошло только тогда, когда в исходном коде присутствовал класс HttpServlet
(IntelliJ IDEA не выдает ошибку времени компиляции; пакет сервлета был импортирован нормально, однако во время выполнения возникла эта ошибка main class
) .
Мне удалось решить эту проблему. Я зашел в меню Файл → Структура проекта ... :
Затем к Модули :
Была предоставлена область рядом с модулем сервлета. Я изменил его на Скомпилировать :
И это сработало!
Если это Maven проект :
Проблема должна исчезнуть.
У меня была такая же проблема, и я наконец нашел свою ошибку :) Я использовал эту команду для компиляции, и она сработала правильно:
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
Щелкните проект правой кнопкой мыши.
src
как "источники" У меня это сработало.
Хорошо, ответов уже много, но никто не упомянул случай, когда права доступа к файлам могут быть виноваты.
При запуске пользователь может не иметь доступа к файлу JAR или одному из каталогов пути. Например, рассмотрим:
Файл Jar в /dir1/dir2/dir3/myjar.jar
Пользователь1, владеющий файлом JAR, может:
# 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.
Если проблема связана с Eclipse:
Попробуйте добавить проект в путь к классу.
См. Изображение ниже:
Этот метод сработал для меня.
Ответ относительно внешней библиотеки -
Компиляция:
javac -cp ./<external lib jar>: <program-name>.java
Выполнить:
java -cp ./<external lib jar>: <program-name>
Приведенная выше схема хорошо работает в системах OS X и Linux. Обратите внимание на :
в пути к классам.
У меня был странный вопрос:
Ошибка: не удалось найти или загрузить основной класс mypackage.App
Оказалось, что у меня была ссылка на POM (родительский), закодированную в файле pom.xml
моего проекта (pom.xml
моего проекта указывал на родительский pom.xml
) и <20920> было выключено / неправильно.
Ниже приведена часть файла pom.xml
моего проекта:
<parent>
<groupId>myGroupId</groupId>
<artifactId>pom-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../badPathHere/pom.xml</relativePath>
</parent>
Как только я разрешил POM relativePath, ошибка исчезла.
Иди на цифру.
Я также столкнулся с подобными ошибками при тестировании соединения Java MongoDB JDBC. Я думаю, что было бы хорошо вкратце резюмировать мое окончательное решение, чтобы в будущем любой мог непосредственно изучить две команды и продолжить работу.
Предположим, вы находитесь в каталоге, в котором существует ваш файл Java и внешние зависимости (файлы JAR).
Компиляция:
javac -cp mongo-java-driver-3.4.1.jar JavaMongoDBConnection.java
Выполнить:
java -cp mongo-java-driver-3.4.1.jar: JavaMongoDBConnection
Все это предполагает, что 1) JavaMongoDBConnection
не имеет пакета и 2) вы не меняете каталог. Это, мягко говоря, хрупкое. И, не объясняя проблемы, это побудит новичков попробовать этот подход в ситуациях, когда он не будет работать . Короче говоря, он поощряет «техники программирования вуду»: en.wikipedia.org/wiki/Voodoo_programming
Прочитав все ответы, я заметил, что большинство из них у меня не работает. Итак, я провел небольшое исследование и вот что у меня получилось. Попробуйте это сделать, только если шаг 1 не работает.
Откройте, перейдите в C: \ Program Files (x86) \ Java или C: \ Program Files \ Java
jdk
, а затем папку bin
. ii. Скопируйте путь и добавьте его в переменные среды. Убедитесь, что вы разделяете переменные точкой с запятой, ;
. Например, « C: \ Yargato \ bin; C: \ java \ bin; ». Если вы этого не сделаете, это вызовет больше ошибок.
iii. Перейдите в папку jre
и откройте ее папку bin
.
iv. Здесь найдите файл rt.jar . Мой:
C: \ Program Files (x86) \ Java \ jre1.8.0_73 \ lib \ rt.jar Скопируйте и в переменной среды и найдите переменную пути к классам и вставьте его туда.
Это чепуха вуду. %JAVA_HOME\bin%
действительно должен быть на %PATH%
, но это вызывает другую ошибку. %JAVA_HOME\lib\rt.jar%
не нужно добавлять в путь к классам. Он автоматически добавляется в путь к загрузочному классу всеми необходимыми инструментами JRE или JDK.
Ошибка появляется когда не добавляется. Вот почему шаг 1 очень важен.
Просто попробуйте, потому что сейчас это сработало для моих друзей в классе
Я знаю, что вам нужно установить Java (да!) И поместить ее в свой% PATH%. Но если вы этого не сделаете, вы получите другое сообщение об ошибке . Например, «java не распознается как внутренняя или внешняя команда». Я повторяю, "решения", которые вы предлагаете, не решают >> эту << проблему.
вам нужно завершить последнюю переменную среды точкой с запятой. перед добавлением нового пути. То есть "C: \ Yargato \ bin; C: \ java \ bin; C: \ Programfiles \ java ......; также заканчивайте его точкой с запятой
Вы должны нам ссылку на YouTube ... Вы можете просто добавить 11 символов после «watch?v=
» в URL-адрес (например, yVRtJbXQsL8
для https://www.youtube.com/watch?v=yVRtJbXQsL8) и кто-нибудь может добавить реальный URL позже.
@dassanctity - Ваше утверждение, что путь к классам должен заканчиваться точкой с запятой, неверно согласно документации Oracle : docs.oracle.com/javase/8/docs/technotes/tools/windows/…
Согласно окнам, точка с запятой отделяет один путь среды от другого. Таким образом, он не должен заканчиваться точкой с запятой, но обязательно поставьте точку с запятой перед добавлением новой, иначе вы вызовете больше ошибок. Это не согласно определениям oracle, а windows
@dassanctity - Ваш комментарий от 25 мая противоречит вашим предыдущим комментариям. «вам нужно заканчивать последнюю переменную среды точкой с запятой». по сравнению с «Таким образом, она не должна заканчиваться точкой с запятой» . (ИМО, лучше всего удалить этот ответ. В нем слишком много ошибок, и он не добавляет ничего, о чем уже не говорят другие ответы.)
@StephenC позвольте мне использовать пример. Допустим, я хочу добавить этот новый env. path "C:\Program Files\Cisco Packet Tracer 7.0\bin"
тогда, когда я перейду в свой env. paths, и я вижу другие пути, мне нужно убедиться, что другой путь заканчивается точкой с запятой, прежде чем добавлять новый путь. Это для Windows 8.1 или более ранней версии.
Это НЕ то, что показывает пример в вашем ответе. Это показывает точку с запятой в конце. И в ваших различных комментариях говорится, что точка с запятой в конце обязательна или не обязательна. И это лишь одна из многих проблем с этим Ответом.
В моем случае я получил ошибку, потому что я смешал имена пакетов в верхнем и нижнем регистре в системе Windows 7. Изменение имен пакетов на все строчные буквы решило проблему. Также обратите внимание, что в этом сценарии у меня не было ошибок при компиляции файла .java в файл .class; он просто не запускался бы из того же (подподподпод-) каталога.
В контексте разработки IDE (Eclipse, NetBeans или что-то еще) вам необходимо настроить свойства проекта так, чтобы у вас был основной класс, чтобы ваша IDE знала, где находится основной класс, который будет выполняться, когда вы нажмете «Play».
Однако вы не получите вышеупомянутые сообщения об ошибках, если попытаетесь запустить приложение без правильного main
из IDE. (А для некоторых IDE вам не нужно настраивать программу запуска, чтобы это произошло; например, Eclipse run
найдет класс с методом main
.
Фактически, если вы запустите приложение без этого параметра, вы получите точное сообщение в исходном вопросе: Could not find or load main class ...
. Так я попал на этот пост :)
Не в «Затмении» этого не произойдет. В Eclipse, если IDE не может идентифицировать ни один из классов с помощью main
, вам просто не будет предложена опция «Выполнить»> «Приложение Java» в контекстном меню.
Иногда в некоторых онлайн-компиляторах, которые вы, возможно, пробовали, вы получаете эту ошибку, если вы не пишете public class [Classname]
, а просто class [Classname]
.
Примеры (оскорбляющих компиляторов), пожалуйста. Хотя создание класса «точки входа» public
является обычным / нормальным, спецификации Java этого не требуют, как и стандартная команда Oracle / OpenJDK java
.
Если вы используете 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.
Я скомпилировал это так:
javac HelloWorld.java
И я пробовал работать с тем же расширением:
java Helloworld.java
Когда я удалил .java
и переписал команду как java HelloWorld
, программа работала отлично. :)
Это потому, что вы выполняете скомпилированную версию вашего .java. Фактически он выполняет файл .class
Для записи, это то же самое, что и Причина № 1, Пример № 5 в моем Ответе ...
При запуске 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 правильно обрабатывать аргументы пути к классам.
По умолчанию Java использует .
, текущий рабочий каталог, в качестве значения по умолчанию CLASSPATH
. Это означает, что когда вы вводите команду в командной строке, например. java MyClass
, команда интерпретируется так, как если бы вы набрали java -cp . MyClass
. Вы видели точку между -cp
и MyClass
? ( cp - это сокращение от более длинного варианта classpath )
Этого достаточно в большинстве случаев, и кажется, что все работает нормально, пока вы не попытаетесь добавить каталог в свой CLASSPATH
. В большинстве случаев, когда программистам это нужно, они просто запускают команду типа set CLASSPATH=path\to\some\dir
. Эта команда создает новую переменную среды с именем CLASSPATH
со значением path\to\some\dir
или заменяет ее значение на path\to\some\dir
, если CLASSPATH
уже был установлен ранее.
Когда это будет сделано, у вас теперь есть переменная среды CLASSPATH
, и Java больше не использует путь к классам по умолчанию (.
), а тот, который вы установили. Итак, на следующий день вы открываете свой редактор, пишете какую-нибудь java-программу cd
в каталог, в котором вы ее сохранили, компилируете и пытаетесь запустить с помощью команды java MyClass
, и вы получаете приятный результат: Не удалось найти или загрузить основной класс ... (Если раньше ваши команды работали хорошо и теперь вы получаете этот результат, то это может быть ваш случай).
Что происходит, когда вы запускаете команду java MyClass
, Java ищет файл класса с именем MyClass
в каталоге или каталогах, которые вы установили в своем CLASSPATH
, а не в текущем рабочем каталоге, поэтому это не так. Я не нашел там ваш файл класса и, следовательно, жалуется.
Вам нужно снова добавить .
в путь к классу, что можно сделать с помощью команды set CLASSPATH=%CLASSPATH%;.
(обратите внимание на точку после точки с запятой). На простом английском языке эта команда гласит: «Выберите то, что изначально было значением CLASSPATH
(%CLASSPATH%
), добавьте к нему .
(;.
) и присвойте результат обратно CLASSPATH
».
И вуаля , вы снова можете использовать свою команду java MyClass
как обычно.
Расположение файла класса: C: \ test \ com \ company
Имя файла: Main.class
Полное имя класса: com.company.Main
Команда командной строки:
java -classpath "C:\test" com.company.Main
Обратите внимание, что путь к классу НЕ включает \ com \ company
Используйте эту команду:
java -cp . [PACKAGE.]CLASSNAME
Пример: Если ваше имя класса Hello.class, созданный из Hello.java, используйте следующую команду:
java -cp . Hello
Если ваш файл Hello.java находится внутри пакета com.demo, используйте команду ниже
java -cp . com.demo.Hello
В JDK 8 часто случается, что файл класса присутствует в той же папке, но команда java
ожидает путь к классам, и по этой причине мы добавляем -cp .
, чтобы взять текущую папку в качестве ссылка на путь к классам.
Это работает только в простых случаях. Более сложные случаи требуют более сложного пути к классам.
И для >> действительно << простых случаев -cp .
не нужен, потому что, если $CLASSPATH
не задано, то .
- путь к классам по умолчанию.
Нет, Стивен, во многих случаях путь к классам по умолчанию в Windows не работает. Я пробовал это на трех разных машинах, вы тоже можете попробовать.
Вероятно, это потому, что вы действительно где-то установили переменную среды% CLASSPATH%. Если вы это сделаете, значит, вы не используете путь к классам по умолчанию. (Что выводит echo %CLASSPATH%
?) И нет, я не могу проверить, потому что у меня нет ПК с Windows.
В официальном руководстве Oracle для команды "java" (версия для Windows) говорится следующее: "Если -classpath
и -cp
не используются и CLASSPATH
не задан, то путь к классу пользователя состоит из текущего каталог (.
). " Ссылка - docs.oracle.com/javase/7/docs/technotes/tools/windows/java.html
Да, в общем, когда вы устанавливаете такие инструменты, как Websphere MQ или erlang и т. Д., Которые сейчас распространены, CLASSPATH создает как переменную среды. Вот почему парень, задавший этот вопрос, возможно, не сможет скомпилировать.
Нет никакого «парня». Это было написано (мной!) Как общие вопросы и ответы, предназначенные для обучения людей, чтобы они понимали причину проблемы и знали, как ее исправить. Простые ответы «сделай это, и это может сработать» (ИМО) бесполезны, потому что они побуждают людей не тратить время на изучение и понимание
У меня это сработало, когда я попытался запустить простую программу из командной строки.
Похоже, когда у меня была эта проблема, она была уникальной.
Как только я удалил объявление пакета в верхней части файла, все заработало отлично.
Помимо этого, похоже, не было никакого способа запустить простой HelloWorld.java на моей машине, независимо от папки, в которой происходила компиляция, CLASSPATH или PATH, параметров или папки, из которой вызывается.
Есть много способов заставить его работать. Все сводится к >> пониманию << того, как использовать механизм пути к классам Java. Пожалуйста, прочтите мой ответ и ресурсы, на которые он ссылается.
И если вы доведете это «решение» до его логического завершения, то в конечном итоге вы объявите все свои классы в пакете по умолчанию, что является очень плохой идеей для программ значительного размера.
Я получал вот это для подключения к базе данных. Я только что добавил в путь к классам следующее:
export CLASSPATH=<path>/db2jcc4.jar:**./**
Здесь я добавил ./ в последнюю очередь, чтобы мой класс также идентифицировался при загрузке.
Теперь просто запустите:
java ConnectionExample <args>
Он работал отлично.
Это не удастся, если вы не находитесь в каталоге, в котором вы скомпилировали классы.
Кажется, все ответы здесь адресованы пользователям Windows. Для Mac разделителем пути к классам является :
, а не ;
. Поскольку при установке пути к классам с использованием ;
ошибка не выбрасывается, это может быть трудно обнаружить при переходе с Windows на Mac.
Вот соответствующая команда Mac:
java -classpath ".:./lib/*" com.test.MyClass
Если в этом примере пакет - com.test
, а папка lib
также должна быть включена в путь к классам.
В Linux так же, как и на Mac.
Зачем нужен /*
?
Это синтаксис с подстановочными знаками. (Это не обязательно. Вы можете явно указать JAR-файлы, если хотите.)
У меня в этом случае была такая ошибка:
java -cp lib.jar com.mypackage.Main
Он работает с ;
для Windows и :
для Unix:
java -cp lib.jar; com.mypackage.Main
да. Скорее всего, потому, что вашего Main
нет в файле JAR. -cp lib.jar;
означает то же самое, что и -cp lib.jar;.
, т.е. текущий каталог включен в путь к классам.
Наконец-то исправлена проблема для unix .. спасибо (работает с :)
Попробуйте -Xdiag .
Ответ Стива С хорошо описывает возможные случаи, но иногда бывает непросто определить, не может ли класс быть найден или загружен . Используйте java -Xdiag
(начиная с JDK 7). Это распечатает красивую трассировку стека, которая подсказывает, что означает сообщение Could not find or load main class
.
Например, он может указывать вам на другие классы, используемые основным классом, которые не могут быть найдены и которые препятствуют загрузке основного класса.
Вам действительно нужно сделать это из папки 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
Класс нельзя назвать «CommandLine.class». Это было бы синтаксической ошибкой Java. (Вы имеете в виду, что файл, содержащий скомпилированный класс, называется "CommandLine.class" ...). Другая проблема заключается в том, что ваша инструкция «cd to the source directory» работает только в том случае, если вы скомпилировали код >> в << дерево исходных каталогов. Наконец, если в вашей компиляции использовался аргумент «-cp», вам понадобится эквивалент при запуске.
В моем проекте у меня есть папка src и папка bin в корне. Мне пришлось ввести cd
в src
, а затем запустить команду java ../bin com.blah.blah.MyClass
, которая сработала для меня. Так что спасибо за подсказку!
Мне не удалось решить эту проблему с помощью указанных здесь решений (хотя указанный ответ, без сомнения, прояснил мои представления). Я сталкивался с этой проблемой два раза, и каждый раз пробовал разные решения (в Eclipse IDE).
main
в разных классах моего проекта. Итак, я удалил метод main
из последующих классов. Удаление методов main
не решит проблему. Нет ничего технически неправильного в приложении, имеющем несколько точек входа.
Что решило проблему в моем случае:
Щелкните правой кнопкой мыши проект / класс, который хотите запустить, затем Run As
-> Run Configurations
. Затем вы должны либо исправить существующую конфигурацию, либо добавить новую следующим образом:
откройте вкладку Classpath
, нажмите кнопку Advanced...
, затем добавьте bin
папку вашего проекта.
Это конкретный случай, но поскольку я пришел на эту страницу в поисках решения и не нашел его, я добавлю его сюда.
Windows (проверено с 7) не принимает специальные символы (например, á
) в именах классов и пакетов. А вот в Linux есть.
Я обнаружил это, когда построил .jar
в NetBeans и попытался запустить его из командной строки. Он работал в NetBeans, но не в командной строке.
Я получил эту ошибку после выполнения mvn eclipse:eclipse
Это немного испортило мой файл .classpath
.
Пришлось изменить строки в .classpath
с
<classpathentry kind="src" path="src/main/java" including="**/*.java"/>
<classpathentry kind="src" path="src/main/resources" excluding="**/*.java"/>
до
<classpathentry kind="src" path="src/main/java" output="target/classes" />
<classpathentry kind="src" path="src/main/resources" excluding="**" output="target/classes" />
В Windows поместите .;
в значение CLASSPATH в начале.
. (точка) означает «посмотреть в текущем каталоге». Это постоянное решение.
Также вы можете установить его "один раз" с помощью набора CLASSPATH=%CLASSPATH%;.
. Это будет длиться, пока открыто ваше окно cmd.
Этот совет может помочь, а может и не помочь. Это поможет, если дерево классов содержит классы в текущем каталоге. Если нет, то не будет. На самом деле я бы этого не сделал. Вместо этого я бы создал однострочный сценарий-оболочку, который работал бы вне зависимости от того, находится ли пользователь в «правильном» каталоге.
В 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/
Вы прочитали принятый ответ? Ваш ответ добавляет что-нибудь новое?
@StephenC Я попытался найти причину в вашем списке, просмотрев категории "Причина" и их точки. Я не смог найти совпадающую точку в «Причина № 1», а заголовок «Причина № 2» не подходил для моего случая (потому что я был уверен, что с самим путем к классам проблем нет). Я нашел причину, выполнив эксперименты, и был удивлен, что в моем случае была показана ошибка «основной класс не найден», потому что реализация интерфейса не была на пути к классу. Конечно, вы можете сказать: «Вам следует прочитать все, что описано в сообщении», но мне кажется, что ваш список причин можно улучшить.
Согласно сообщению об ошибке («Не удалось найти или загрузить основной класс») существует две категории проблем:
Основной класс не может быть найден , когда есть опечатка или неправильный синтаксис в полном имени класса или не существует в указанном пути к классам42584070.
Основной класс не может быть загружен , когда класс не может быть инициирован , обычно основной класс расширяет другой класс, и этот класс не существует в указанном пути к классам.
Например:
public class YourMain extends org.apache.camel.spring.Main
Если верблюжья пружина не включена, будет сообщено об этой ошибке.
«В основном» есть и другие категории. Проблема с отсутствующим суперклассом - очень необычный случай. (Настолько необычно, что я никогда не видел этого ... в вопросах, задаваемых на этом сайте.)
Их ДВА, потому что ошибка говорит: «Не удалось НАЙТИ или ЗАГРУЗИТЬ основной класс». Если есть другие категории, сообщите, пожалуйста. Я видел это, поэтому просто хочу поделиться им здесь, может быть, это понадобится кому-то другому.
да. Я это понимаю. Но вы читали мой ответ? Разве он не охватывает все упомянутые вами случаи? На самом деле я хочу сказать, что ваш ответ не добавляет ничего нового ... и, поскольку он не учитывает все многие другие причины, он на самом деле будет препятствием для многих читателей.
Ваш ответ хорош. Я прочитал и собираюсь прочитать ссылки. Спасибо! Он довольно хорошо покрывает первый пункт. Что касается второго пункта, я думаю, что он не совсем правильный (очень рад, если я ошибаюсь). В своем ответе вы сказали: «Путь к классам должен включать все другие (несистемные) классы». На самом деле, чтобы избежать ошибки, в этом нет необходимости. Будут другие ошибки и исключения (например, NullPionter), но вы не увидите «Coud не найдет или не загрузит основной класс», пока основной класс найден и загружен.
Определенно существуют сценарии, в которых отсутствующий класс приведет к другому исключению. Однако я считаю, что вы получите это исключение, если какой-либо отсутствующий класс приведет к сбою загрузки основного класса. Не просто отсутствующий суперкласс. Это может быть любой тип, упомянутый в загружаемом вами классе ... или любой из его суперклассов / интерфейсов.
Я имел в виду, что в некоторых (большинстве) случаев вы не видите ЭТОЙ ошибки, когда зависимости не указаны в пути к классам. Возможно, вы захотите пересмотреть «Путь к классам должен включать все другие классы». Полностью зависит от вас. Не обидно.
Но факт остается фактом: путь к классам ДОЛЖЕН включать все другие классы. Утверждение верно, и вы не убедили меня, что есть какая-то ценность в его пересмотре. (В самом деле, если вы подумаете об этом, если бы я изменил его, чтобы сказать что-то вроде «Вам не нужны >> все << классов в пути к классам, чтобы избежать этой конкретной ошибки, но в некоторых случаях вы получите разные ошибки, поэтому вы все равно лучше надеть их. "... тогда типичный читатель этого ответа, вероятно, запутается еще больше, чем он / она уже есть.)
Я бы изменил его на что-то вроде «Вам нужно включить все классы, которые требуются для запуска основного класса, чтобы избежать этой конкретной ошибки». Я не пытаюсь вас убедить. Это просто путь, который я хотел бы увидеть. Я оставил ответ здесь только для людей, которым может понравиться читать подобным образом. Давайте не будем распространять это обсуждение дальше :) Я изменил свое утверждение на «не полностью обсуждено в принятом ответе» и надеюсь, что вы почувствуете себя лучше.
Эта информация имеет решающее значение и заслуживает отдельного упоминания (это единственный ответ, в котором упоминается extends
). Я только что на собственном опыте узнал, что, когда основной класс не может загрузить , потому что он расширяет другой, который не может быть найден , java не сообщает, какой фактический класс не был найден (в отличие от NoClassDefFoundError
). Так что да, это действительно происходит, и это непростая ситуация, когда вы этого не знаете.
В этой ситуации есть ли способ точно определить, какой класс зависимости не загружается?
@carlos Использование флага -Xdiag
может дать вам подсказку.
Я потратил приличное количество времени, пытаясь решить эту проблему. Я думал, что каким-то образом неправильно установил свой путь к классам, но проблема заключалась в том, что я набрал:
java -cp C:/java/MyClasses C:/java/MyClasses/utilities/myapp/Cool
вместо:
java -cp C:/java/MyClasses utilities/myapp/Cool
Я думал, что значение полного имени означает включение полного имени пути вместо полного имени пакета.
Я обновил свой ответ, чтобы попытаться устранить эту путаницу.
Ни то, ни другое неверно. Класс должен быть указан как utilities.myapp.Cool
или любое другое имя его пакета, если таковое имеется.
Когда один и тот же код работает на одном ПК, но показывает ошибку на другом, лучшее решение, которое я когда-либо находил, - это компиляция следующего вида:
javac HelloWorld.java
java -cp . HelloWorld
Это не очень хорошая рекомендация. Вы зависите от того, не задана ли переменная среды CLASSPATH или имеет значение, соответствующее символу ".". Да, во многих случаях это работает, в других - нет.
Ну конечно javac -classpath . HelloWorld.java
сработало бы! И это лучшее решение в вашем случае.
Если у вас в первой строке указано package com.some.address - это не сработает. Вам нужно будет прокомментировать «адрес пакета».
@Joe - Этот хак (комментирование пакета) будет работать (в некоторых случаях), но это плохая идея. Лучшая идея - узнать / понять, что вызвало проблему, и реализовать правильное решение.
отключение переменной пути к классам в основном сработало для меня.
В этом случае у вас есть:
Не удалось найти или загрузить основной класс ? Classpath
Это потому, что вы используете «-classpath», но тире не то же самое, что используется java
в командной строке. У меня возникла проблема с копированием и вставкой из Блокнота в cmd.
Ух ты! Это совершенно странная причина! (Но он служит вам для использования Блокнота вместо настоящего текстового редактора :-))
Если ваши классы находятся в пакетах , вам необходимо cd
перейти в корневой каталог вашего проекта и запустить его, используя полное имя класса (packageName.MainClassName).
Пример:
Мои классы здесь:
D:\project\com\cse\
Полное имя моего основного класса:
com.cse.Main
Итак, я cd
вернулся в корневой каталог проекта:
D:\project
Затем введите java
команду:
java com.cse.Main
Этот ответ предназначен для спасения начинающих программистов Java от разочарования, вызванного распространенной ошибкой, я рекомендую вам прочитать принятый ответ, чтобы получить более подробные сведения о пути к классам Java.
Этот ответ состоит из множества предположений. Есть и другие способы добиться этого. Вместо того, чтобы слепо следовать приведенному выше совету, я бы порекомендовал людям найти время, чтобы прочитать ссылки в моем ответе, которые объясняют, как работает путь к классам Java. Лучше ПОНИМАТЬ, что делаешь ...
Этот ответ делает точные предположения, которые мне нужны :) Я находился в каталоге файла .class, и java.exe не работал. Как только я сделал cd-ed выше и запустил с именем пакета, включенным в командную строку, все заработало.
Я согласен с Ником Константином. То же самое. Это был точный пример того, что я сделал, и он тоже сработал для меня. Обработка пути к классам java имеет определенную логику, но я бы точно не спроектировал ее таким образом.
Спасибо, ваш ответ помог мне понять, что я использовал Main с верхним регистром _ !
Я пишу этот комментарий после того, как попробовал это, но это не сработало. У меня есть проект под названием Helloworld, который состоит только из 1 файла java, Helloworld / src / com / firstpackage / Test.java (windows 10. intellij idea). У меня нет переменной окружения CLASSPATH, я хочу установить путь к классам специально для этого проекта. запуск java com.firstpackage.Test
внутри каталога Helloworld не работает, и команда java -classpath C:\Users\matuagkeetarp\IdeaProjects\Helloworld\src\com\firstpackage Test.java
также не устанавливает переменную пути к классам. Вы можете помочь?
Если у вас есть ключевое слово package
в исходном коде (основной класс определен в пакете) , вы должны запустить его в иерархическом каталоге, используя полное имя класса (packageName.MainClassName
).
Предположим, существует файл исходного кода (Main.java):
package com.test;
public class Main {
public static void main(String[] args) {
System.out.println("salam 2nya\n");
}
}
Для запуска этого кода вы должны поместить Main.Class
в пакет, например, каталог:
C: \ Users \ workspace \ testapp \ com \ test \ Main.Java
Затем измените текущий каталог терминала на корневой каталог проекта:
cd C:\Users\workspace\testapp
И, наконец, введите код:
java com.test.Main
Если у вас нет пакета с именем вашего исходного кода, возможно, вы ошиблись с неправильной командой. Предположим, что имя вашего java-файла Main.java
, после компиляции:
javac Main.java
ваш скомпилированный код будет Main.class
Вы получите эту ошибку, если вызовете ее с помощью:
java Main.class
Вместо этого используйте это:
java Main
См. «Дополнительные примечания №1» моего ответа. Для лучшего объяснения этой проблемы.
@StephenC Да, ваш ответ более полный (и, конечно, +1), но в этом конкретном ответе было слово «пакет», что позволило мне быстро найти то, что мне нужно. И это сработало. Итак +1 Разави. StephenC, у вас отсутствует простой пример пакета, который мне нужен, поскольку я новичок в Java.
Это была моя проблема. Я пробирался через тонны документов Java, и этот конкретный пример - то, что мне нужно
Лучше сделать Runnable JAR File для выполнения файла класса.
Да, конкретный пример хорош, это отлично сработало. Я уверен, что основной ответ очень обстоятельный, но за лесом дерево было трудно увидеть. Хорошенький @Razavi
Мне нравится этот более короткий и полезный ответ вместо принятого!
Ух ты! Спасибо.
Очень хорошо объяснено. Большое спасибо. У меня это сработало.
Мне помогло указание пути к классам в командной строке, например:
Создать новую папку, 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!
В Ubuntu мне также пришлось указать путь. Не понимаю, почему он не может использовать текущий рабочий каталог по умолчанию. Я убежден, что Java спонсируется производителями клавиатур !!
@gone - Причина, по которой "." не входит в $ PATH по умолчанию, потому что это ловушка безопасности. sea.upenn.edu/cets/answers/dot-path.html
Большое спасибо за это ... даже при том, что не уверен, почему java не смогла узнать путь к классам даже после установки его в переменных среды.
@ akash89 - Наиболее вероятными причинами были: 1) java
не смотрел на $ CLASSPATH (потому что вы использовали -classpath или -jar) или 2) параметр пути к классам не был установлен в среде, которая не была в эффект в контексте, в котором java
был запущен; например потому что вы не «исходили» из файла, в который были добавлены команды setenv в правой оболочке.
У меня все еще есть ошибка: не удалось найти или загрузить основной класс Temp, может кто-нибудь помочь!
Под окнами с использованием classpath
, подобного этому, java -classpath c:\folder\subfoler\myCodeFolder Main
также работал у меня для запуска Main.class
.
Если имя вашего исходного кода - HelloWorld.java, ваш скомпилированный код будет иметь вид HelloWorld.class
.
Вы получите эту ошибку, если вызовете ее с помощью:
java HelloWorld.class
Вместо этого используйте это:
java HelloWorld
Проблема в том, что это решение работает только для классов Java, объявленных в пакете по умолчанию, без зависимостей файлов JAR. (И даже тогда не всегда.) Большинство программ на Java не так просты.
как сказал Стивен, это работает только с «пакетом по умолчанию» - что означает без объявления пакета в верхней части файла. Для быстрого тестирования кода я сделал: javac TestCode.java
, за которым следует java TestCode
У меня это не сработало. Он по-прежнему говорит: «Не удалось найти или загрузить основной класс HelloWorld».
java -jar HelloWorld.jar также является вариантом
Мне нужно было сделать java -classpath . HelloWorld
@ Джим - ты читал мой комментарий? Если это не сработает, значит, одно или несколько предварительных условий не выполнены. Посмотрите на ответ, получивший наибольшее количество голосов.
@ChrisPrince - Да ... это срабатывает ... иногда. Чтобы понять, когда это работает, а когда нет, прочитайте ответ, получивший наибольшее количество голосов.
@BMaximus - это вариант, только если у вас есть исполняемый файл JAR ...
В моем случае ошибка возникла из-за того, что я указал имя исходного файла вместо имени класса.
Нам нужно предоставить интерпретатору имя класса, содержащего основной метод.
да. См. Мой пример №2 неправильного указания имени класса !!
Сначала задайте путь с помощью этой команды;
set path="paste the set path address"
Затем вам нужно загрузить программу. Введите «cd (имя папки)» в сохраненный диск и скомпилируйте его. Например, если моя программа хранится на диске D, введите «D:», нажмите «Ввод» и введите «cd (имя папки)».
Это не помогает. Этот вопрос касается программ Java, а не обычных исполняемых файлов. Java не использует PATH для поиска чего-либо, и если "cd" помогает, то это скорее удача, чем оценка.
if "cd" helps then it by luck rather than by judgement
. Это неправильно (я считаю), поскольку java по умолчанию использует текущий каталог .
как часть пути к классам.
@GKFX - Вот что я имею в виду. Если вы не знаете, что используете путь к классам по умолчанию (или путь к классам с "." На нем), "cd" не будет иметь никакого эффекта. Это решение работает скорее благодаря удаче (т.е. угадыванию / надежде, что "." Находится в пути к классам), чем по суждению (т.е. проверке того, что "." Находится в пути к классам). Кроме того, вы ошиблись по поводу значения по умолчанию. Java использует "." как путь к классам по умолчанию, а не как часть пути к классам по умолчанию.
Иногда то, что могло быть причиной проблемы, не имеет ничего общего с основным классом, и мне приходилось выяснять это на собственном горьком опыте. Это была библиотека, на которую я переместил ссылку, и она дала мне:
Не удалось найти или загрузить основной класс xxx Linux
Я просто удалил эту ссылку, добавил ее снова, и она снова заработала нормально.
Похоже, проблема заключалась в том, что у вас был неправильный путь к классам из-за неработающей «ссылки» в вашем проекте в вашей среде IDE. Я обновлю свой ответ, чтобы охватить этот случай.
@StephenC и EduardoDennis, здесь тоже отсутствовала банка, эта банка содержала интерфейс, от которого зависел основной класс для создания экземпляра. Итак, сообщение об ошибке слишком широкое. Я должен сказать «не удалось найти», если файл класса не найден и «не удалось загрузить (отсутствуют зависимости)», если чего-то еще не хватает, но не самого файла, поэтому слишком широкое сообщение об ошибке вводит в заблуждение, если вы сосредотачиваетесь только на по части "найти" :(
@AquariusPower - Должна была быть дополнительная трассировка стека «вызвано» для исключения «причина», в котором указано, что какой-то класс отсутствует. Если вы хотите предложить разработчикам Java изменить сообщение об ошибке, в котором говорилось, что это уже более 20 лет ... не стесняйтесь. (Я думаю, что сообщение об ошибке правильное. Проблема заключалась в том, что >> вы << сузили неправильное предложение.)
@StephenC я имел в виду, что у них наверняка есть доступ к информации, доступен ли основной файл класса или нет, так почему бы не показать нам лучшее сообщение об ошибке, в котором говорится, что такой файл отсутствует. С другой стороны, они также могут сказать: «Файл найден, но не может быть загружен» в этот момент, и мы сразу же сосредоточимся на зависимостях, вместо того, чтобы терять полдня на изучение и тестирование вещей, чтобы понять. Я как раз это имел в виду :). Они могут делать это ограниченным образом в течение 20 с лишним лет, но они могут улучшить это, и мы здесь, чтобы гарантировать, что это произойдет благодаря нашей критике и жалобам! : D
Пожалуйста, поймите, что имел в виду >> I <<. Жаловаться на это в каком-то непонятном комментарии к вопросам и ответам трехлетней давности ничего не добьешься. Люди, которые могли бы разумно отреагировать на ваши жалобы, этого не заметят. Если вы хотите сделать что-то конструктивное, отправьте патч. (Я не оцениваю ваши шансы, но они будут больше, чем если бы вы просто жаловались на это.)
Обратите внимание, что это вопрос для самостоятельного ответа, который предназначен для использования в качестве общих справочных вопросов и ответов для новых пользователей Java. Я не смог найти существующие вопросы и ответы, которые адекватно освещают это (ИМО).