새로운 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
과 방법 서명 , 반환 형식 및 수정 에 의해 주어진을public static void main(String[])
. (메소드 인수의 이름은 서명의 일부 가 아닙니다 .) - 해당 메소드를 명령 행 인수 ( “fred”, “joe”, “bert”)로 전달하십시오
String[]
.
Java가 클래스를 찾을 수없는 이유
“주 클래스를 찾거나로드 할 수 없습니다 …”라는 메시지가 표시되면 첫 번째 단계가 실패했음을 의미합니다. java
명령은 클래스를 찾을 수 없습니다. 실제로 메시지의 “…” 는 찾고있는 정규화 된 클래스 이름 입니다 java
.
그렇다면 왜 수업을 찾지 못할 수 있습니까?
이유 # 1-클래스 이름 인수로 실수를했습니다.
첫 번째 원인은 잘못된 클래스 이름을 제공했을 수 있습니다. 또는 올바른 클래스 이름이지만 잘못된 형식입니다. 위의 예를 고려 하여 클래스 이름을 지정 하는 다양한 잘못된 방법 이 있습니다.
-
예제 # 1-간단한 클래스 이름 :
java ListUser
클래스가와 같은 패키지에 선언 되면 명령에 패키지 이름을 포함한
com.acme.example
전체 클래스 이름 을 사용해야합니다java
. 예 :java com.acme.example.ListUser
-
예제 # 2-클래스 이름이 아닌 파일 이름 또는 경로 이름 :
java ListUser.class java com/acme/example/ListUser.class
-
예제 # 3-대소 문자가 잘못된 클래스 이름 :
java com.acme.example.listuser
-
사례 # 4-오타
java com.acme.example.mistuser
-
예제 # 5-소스 파일 이름 (Java 11 이상 제외, 아래 참조)
java ListUser.java
-
예제 # 6-클래스 이름을 완전히 잊었다
java lots of arguments
이유 # 2-응용 프로그램의 클래스 경로가 잘못 지정되었습니다.
두 번째 원인은 클래스 이름이 정확하지만 java
명령이 클래스를 찾을 수 없기 때문입니다. 이를 이해하려면 “classpath”의 개념을 이해해야합니다. 이것은 Oracle 문서에 잘 설명되어 있습니다 .
java
명령 문서- 클래스 경로 설정 .
- 자바 튜토리얼 -PATH 및 CLASSPATH
따라서 … 클래스 이름을 올바르게 지정한 경우 다음으로 확인해야 할 것은 클래스 경로를 올바르게 지정한 것입니다.
- 위에 링크 된 3 개의 문서를 읽으십시오. (예 … 읽어보십시오! Java 프로그래머 는 Java 클래스 경로 메커니즘의 작동 방식에 대한 기본 사항을 이해 하는 것이 중요 합니다.)
- 명령 줄 및 / 또는 CLASSPATH 환경 변수를 확인하십시오.
java
. 디렉토리 이름과 JAR 파일 이름이 올바른지 확인하십시오. - 이 경우 상대 가 당신이 실행할 때 적용되는 현재 디렉토리에서 … 제대로 해결하는 클래스 경로에서 경로 이름, 검사
java
명령. - 오류 메시지에 언급 된 클래스가 유효 클래스 경로 에 있는지 확인하십시오 .
- 클래스 경로 구문은 Windows와 Linux 및 Mac OS에서 다릅니다 . 클래스 경로 구분 기호는
;
Windows 및:
기타에 있습니다. 플랫폼에 잘못된 구분 기호를 사용하면 명시적인 오류 메시지가 표시되지 않고 경로에 존재하지 않는 파일이나 디렉토리가 자동으로 무시됩니다. .)
이유 # 2a-클래스 경로에 잘못된 디렉토리가 있습니다.
클래스 경로에 디렉토리를 놓으면, 규정 된 이름 공간의 루트에 해당됩니다. 정규화 된 이름을 pathname에 매핑하여 클래스는 해당 루트 아래의 디렉토리 구조에 있습니다. 예를 들어, “/ 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은 “com / acme / example”디렉토리에서 “Foon.class”를 찾습니다.
-
디렉토리 구조가 위 패턴에 따라 패키지 이름과 일치하지 않으면 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
,javac
등등을.- 클래스 경로에서 절대 경로 이름과 상대 경로 이름을 선택할 때 신중하게 생각하십시오. 현재 디렉토리가 변경되면 상대 경로 이름이 “깨질 수 있습니다”.
이유 # 2c-클래스 경로에서 누락 된 종속성
클래스 경로에는 응용 프로그램이 의존 하는 다른 (시스템이 아닌) 클래스가 모두 포함 되어야합니다. (시스템 클래스는 자동으로 위치하므로 이에 대해 거의 신경 쓸 필요가 없습니다.) 기본 클래스가 올바르게로드 되려면 JVM에서 다음을 찾아야합니다.
- 클래스 자체.
- 수퍼 클래스 계층 구조의 모든 클래스와 인터페이스 (예 : Java 클래스가 클래스 경로에 있지만 시작이 오류와 함께 실패 함 : 메인 클래스를 찾거나로드 할 수 없음 참조)
- 변수 또는 변수 선언 또는 메소드 호출 또는 필드 액세스 표현식을 통해 참조되는 모든 클래스 및 인터페이스
(참고 : JLS 및 JVM 스펙에서는 JVM이 클래스를 “지연하게”로드 할 수있는 일부 범위가 있으며 이는 클래스 로더 예외가 발생하는 경우 영향을 줄 수 있습니다.
이유 # 3-클래스가 잘못된 패키지로 선언되었습니다
누군가가 소스 코드 파일을 소스 코드 트리의 잘못된 폴더에 넣거나 package
선언을 생략하는 경우가 있습니다. IDE에서이 작업을 수행하면 IDE의 컴파일러에서이를 즉시 알려줍니다. 마찬가지로 적절한 Java 빌드 도구를 사용하는 경우 도구는 javac
문제점을 감지하는 방식으로 실행 됩니다. 그러나 Java 코드를 직접 작성하는 경우 컴파일러가 문제점을 인식하지 못하는 방식으로 수행 할 수 있으며 결과 “.class”파일이 예상 한 위치에 있지 않습니다.
여전히 문제를 찾을 수 없습니까?
확인할 사항이 많으며 놓치기 쉽습니다. 명령 행에 -Xdiag
옵션을 추가하십시오 java
(첫 번째로 java
). 클래스 로딩에 대한 다양한 것들을 출력 할 것이고, 이것은 실제 문제가 무엇인지에 대한 단서를 제공 할 수 있습니다.
또한 웹 사이트, 문서 등에서 보이지 않거나 ASCII가 아닌 문자를 복사하여 붙여 넣을 때 발생할 수있는 문제를 고려하십시오. 그리고 “상형 문자”를 고려하면 두 글자 또는 기호가 동일하게 보이지만 그렇지 않습니다.
마지막으로에서 잘못된 서명을 가진 JAR 파일에서 시작하려고하면 분명히이 문제가 발생할 수 있습니다 (META-INF/*.SF)
.
에 대한 대체 구문 java
를 사용하여 Java 프로그램을 시작하기위한 세 가지 대체 구문이 java command
있습니다.
1) “실행 가능”JAR 파일을 시작하는 데 사용되는 구문은 다음과 같습니다.
java [ <options> ] -jar <jar-file-name> [<arg> ...]
예 :
java -Xmx100m -jar /usr/local/acme-example/listuser.jar fred
진입 점 클래스 이름 (예 com.acme.example.ListUser
🙂 및 클래스 경로는 JAR 파일의 MANIFEST에 지정되어 있습니다.
2) 모듈 (Java 9 이상)에서 응용 프로그램을 시작하는 구문은 다음과 같습니다.
java [ <options> ] --module <module>[/<mainclass>] [<arg> ...]
진입 점 클래스의 이름은 <module>
자체적으로 정의 되거나 optional에 의해 제공됩니다 <mainclass>
.
3) Java 11부터 단일 소스 코드 파일을 컴파일 및 실행하고 다음 구문으로 실행할 수 있습니다.
java [ <options> ] <sourcefile> [<arg> ...]
여기서 (일반적으로) 접미사가 “.java”인 파일입니다.
자세한 내용 java
은 사용중인 Java 릴리스 명령에 대한 공식 문서를 참조하십시오 .
십오 일
일반적인 Java IDE는 IDE JVM 자체 또는 하위 JVM에서 Java 응용 프로그램을 실행하도록 지원합니다. 이들은 일반적으로 IDE에서, 런타임 클래스 경로를 구성 메인 클래스를 확인하고 작성하는 자체 메커니즘을 사용하기 때문에,이 예외에서 면역 java
명령 줄을.
그러나 IDE 뒤에서 작업을 수행하면이 예외가 여전히 발생할 수 있습니다. 예를 들어, 이전에 Eclipse에서 Java 앱에 대한 Application Launcher를 설정 한 후 Eclipse에 알리지 않고 “main”클래스를 포함하는 JAR 파일을 파일 시스템의 다른 위치로 이동 한 경우 Eclipse는 자신도 모르게 JVM을 시작합니다. 클래스 경로가 잘못되었습니다.
요컨대, IDE에서이 문제가 발생하면 오래된 IDE 상태, 손상된 프로젝트 참조 또는 깨진 실행기 구성과 같은 사항을 확인하십시오.
IDE가 단순히 혼란 스러울 수도 있습니다. IDE는 많은 상호 작용하는 부분으로 구성된 매우 복잡한 소프트웨어입니다. 이러한 많은 부분은 IDE를 전체적으로 반응시키기 위해 다양한 캐싱 전략을 채택합니다. 때때로 잘못 될 수 있으며 응용 프로그램을 시작할 때 발생 가능한 증상 중 하나입니다. 이 문제가 발생할 수 있다고 생각되면 IDE 다시 시작, 프로젝트 다시 작성 등과 같은 다른 작업을 시도해 볼 가치가 있습니다.
다른 참고 문헌
- Oracle Java Tutorials- 일반적인 문제 및 솔루션
답변
소스 코드 이름이 HelloWorld.java 인 경우 컴파일 된 코드는입니다 HelloWorld.class
.
다음을 사용하여 호출하면 해당 오류가 발생합니다.
java HelloWorld.class
대신 이것을 사용하십시오 :
java HelloWorld
답변
수업이 패키지에 있다면 당신은에 있습니다cd
프로젝트의 루트 디렉토리와 클래스 (packageName.MainClassName)의 정규화 된 이름을 사용하여 실행합니다.
예:
내 수업은 다음과 같습니다.
D:\project\com\cse\
메인 클래스의 정규화 된 이름은 다음과 같습니다.
com.cse.Main
그래서 cd
루트 프로젝트 디렉토리로 돌아갑니다.
D:\project
그런 다음 java
명령을 발행하십시오 .
java com.cse.Main
이 답변은 일반적인 실수로 인한 좌절에서 초보자 자바 프로그래머를 구출하기위한 것입니다 .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
directory와 같은 패키지에 배치해야합니다 ./com/test/Main.Java
. 그리고 루트 디렉토리에서을 사용하십시오 java com.test.Main
.
답변
동일한 코드가 한 PC에서 작동하지만 다른 PC에서 오류가 표시되면 내가 찾은 최고의 솔루션은 다음과 같이 컴파일하는 것입니다.
javac HelloWorld.java
java -cp . HelloWorld
답변
명령 줄에서 클래스 경로를 지정하는 데 도움이 된 것은 다음과 같습니다.
-
새 폴더를 만들고
C:\temp
-
C:\temp
에 다음 클래스와 함께 Temp.java 파일을 작성하십시오 .public class Temp { public static void main(String args[]) { System.out.println(args[0]); } }
-
folder에서 명령 행을 열고
C:\temp
다음 명령을 작성하여 Temp 클래스를 컴파일하십시오.javac Temp.java
-
컴파일 된 Java 클래스를 실행하고
-classpath
JRE에 클래스를 찾을 위치를 알려주 는 옵션을 추가하십시오 .java -classpath C:\temp Temp Hello!
답변
오류 메시지 ( “메인 클래스를 찾거나로드 할 수 없습니다”)에 따르면 두 가지 범주의 문제가 있습니다.
- 메인 클래스를 찾을 수 없습니다
- 메인 클래스를 로드 할 수 없습니다 (이 사례는 허용 된 답변에서 완전히 논의되지 않았습니다)
메인 클래스는 할 수없는 발견 이있을 때 오타 나 잘못된 구문이 정규화 된 클래스 이름에 있거나 제공된 클래스 경로에 존재하지 않는 .
클래스를 시작할 수 없을 때 메인 클래스를 로드 할 수 없습니다 . 일반적으로 기본 클래스는 다른 클래스를 확장하고 해당 클래스가 제공된 클래스 경로에 없습니다.
예를 들면 다음과 같습니다.
public class YourMain extends org.apache.camel.spring.Main
낙타 스프링이 포함되어 있지 않으면이 오류가보고됩니다.