"주요 클래스를 찾거나로드 할 수 없습니다"는 무엇을 의미합니까?


1370

새로운 Java 개발자가 경험하는 일반적인 문제는 프로그램이 오류 메시지와 함께 실행되지 않는다는 것입니다. Could not find or load main class ...

이것은 무엇을 의미하며, 원인은 무엇이며 어떻게 수정해야합니까?


37
이것은 "자체 답변"질문이며 새로운 Java 사용자를위한 일반적인 참조 Q & A를위한 것입니다. 이를 적절하게 다루는 기존 Q & A를 찾을 수 없습니다 (IMO).
Stephen C

답변:


1230

그만큼 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명령으로 인해 명령이 다음을 수행하게됩니다.

  1. 컴파일 된 버전의 com.acme.example.ListUsers클래스를 검색하십시오 .
  2. 클래스를로드하십시오.
  3. 클래스가 가지고 있는지 확인 main과 방법 서명 , 반환 형식수정 에 의해 주어진을 public static void main(String[]). (메소드 인수의 이름은 서명의 일부 가 아닙니다 .)
  4. 해당 메소드를 명령 행 인수 ( "fred", "joe", "bert")로 전달하십시오 String[].

Java가 클래스를 찾을 수없는 이유

"주 클래스를 찾거나로드 할 수 없습니다 ..."라는 메시지가 표시되면 첫 번째 단계가 실패했음을 의미합니다. java명령은 클래스를 찾을 수 없습니다. 실제로 메시지의 "..." 는 찾고있는 정규화 된 클래스 이름 입니다 java.

그렇다면 왜 수업을 찾지 못할 수 있습니까?

이유 # 1-클래스 이름 인수로 실수를했습니다.

첫 번째 원인은 잘못된 클래스 이름을 제공했을 수 있습니다. 또는 올바른 클래스 이름이지만 잘못된 형식입니다. 위의 예를 고려 하여 클래스 이름을 지정 하는 다양한 잘못된 방법 이 있습니다.

  • 예제 # 1-간단한 클래스 이름 :

    java ListUser

    클래스가와 같은 패키지에 선언 되면 명령에 패키지 이름을 포함한com.acme.example 전체 클래스 이름 사용해야합니다 java. 예 :

    java com.acme.example.ListUser
  • 예제 # 2-클래스 이름이 아닌 파일 이름 또는 경로 이름 :

    java ListUser.class
    java com/acme/example/ListUser.class
  • 예제 # 3-대소 문자가 잘못된 클래스 이름 :

    java com.acme.example.listuser
  • 사례 # 4-오타

    java com.acme.example.mistuser
  • 예제 # 5-소스 파일 이름 (Java 11 이상 제외, 아래 참조)

    java ListUser.java
  • 예제 # 6-클래스 이름을 완전히 잊었다

    java lots of arguments

이유 # 2-응용 프로그램의 클래스 경로가 잘못 지정되었습니다.

두 번째 원인은 클래스 이름이 정확하지만 java명령이 클래스를 찾을 수 없기 때문입니다. 이를 이해하려면 "classpath"의 개념을 이해해야합니다. 이것은 Oracle 문서에 설명되어 있습니다 .

따라서 ... 클래스 이름을 올바르게 지정한 경우 다음으로 확인해야 할 것은 클래스 경로를 올바르게 지정한 것입니다.

  1. 위에 링크 된 3 개의 문서를 읽으십시오. (예 ... 읽어보십시오! Java 프로그래머 는 Java 클래스 경로 메커니즘의 작동 방식에 대한 기본 사항을 이해 하는 것이 중요 합니다.)
  2. 명령 줄 및 / 또는 CLASSPATH 환경 변수를 확인하십시오. java . 디렉토리 이름과 JAR 파일 이름이 올바른지 확인하십시오.
  3. 이 경우 상대 가 당신이 실행할 때 적용되는 현재 디렉토리에서 ... 제대로 해결하는 클래스 경로에서 경로 이름, 검사 java명령.
  4. 오류 메시지에 언급 된 클래스가 유효 클래스 경로 에 있는지 확인하십시오 .
  5. 클래스 경로 구문은 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에서 다음을 찾아야합니다.

(참고 : 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 다시 시작, 프로젝트 다시 작성 등과 같은 다른 작업을 시도해 볼 가치가 있습니다.


다른 참고 문헌


43
타사 라이브러리로 클래스를 실행하려고 할 때이 문제가 발생했습니다. 다음과 같이 java를 호출했습니다. java -cp ../third-party-library.jar com.my.package.MyClass; 이것은 작동하지 않습니다. 대신 클래스 경로에 로컬 폴더를 추가해야합니다 (으로 구분 :: java -cp ../third-party-library.jar:. com.my.package.MyClass다음 과 같이 작동합니다)
lanoxx

23
수년간의 자바 프로그래밍 후에도 나는 여전히이 페이지에서 끝났다. 나에게 문제는 클래스 패스 구문이 OS에 따라 다르다는 것 입니다. 저는 Windows 프로그래밍에 익숙하지 않으며 전혀 몰랐습니다.
keyser

5
추가 메모, 포인트 2 저를 구 해주세요! java가져온 클래스를 찾지 못한다고 말하는 것이 슬프지만 대신 실행하려는 기본 클래스입니다. 나는 그 이유가 있다고 확신하지만 오해의 소지가 있습니다. java클래스가 어디에 있는지 정확히 알고 있었지만 가져온 클래스 중 하나를 찾지 못했습니다. 그 말을하는 대신, 나는 나의 주요 반을 찾지 못한다는 불평을했다. 진짜로
MSX

이클립스 에서이 문제가 두 번 발생했습니다. main ()의 서명이 처음 잘못되었습니다. 두 번째로 .jar의 이름을 바꾸고 빌드 경로에 새 경로를 추가했지만 Eclipse가 이전 경로를 찾지 못했기 때문에 프로젝트가 컴파일되지 않았습니다.이 오류가 발생했습니다. 프로젝트> 속성> Java 빌드 경로> 라이브러리에서 .jar 파일을 제거해야했습니다.
GregT

세 번째로 발생했습니다. Windows 10 배치 파일에서 프로그램을 실행하고 .jar 이름을 변수 ( "-cp % jarname %; lib *"로 불림)에 넣었습니다. jarname 끝에 실수로 여분의 공간을 두어 오류가 발생했습니다. 모자 트릭 :)
GregT

239

소스 코드 이름이 HelloWorld.java 인 경우 컴파일 된 코드는입니다 HelloWorld.class.

다음을 사용하여 호출하면 해당 오류가 발생합니다.

java HelloWorld.class

대신 이것을 사용하십시오 :

java HelloWorld

3
문제는이 솔루션이 JAR 파일 종속성없이 기본 패키지에 선언 된 Java 클래스에 대해서만 작동한다는 것입니다. (그리고, 항상 그런 것은 아닙니다.) 대부분의 Java 프로그램은 그렇게 단순하지 않습니다.
Stephen C

1
Stephen이 말했듯이 이것은 "기본 패키지"에서만 작동 합니다. 이는 파일 맨 위에 패키지 선언이 없음 을 의미 합니다. 일부 코드의 빠른 테스트를 위해 javac TestCode.java다음을 수행했습니다.java TestCode
누군가 Somewhere Somewhere

이것은 나를 위해 작동하지 않았습니다. 여전히 "주요 클래스 HelloWorld를 찾거나로드 할 수 없습니다"
Jim

java -jar HelloWorld.jar 또한 옵션입니다
BMaximus

12
해야 할 일java -classpath . HelloWorld
Chris Prince

136

수업이 패키지에 있다면 당신은에 있습니다cd 프로젝트의 루트 디렉토리와 클래스 (packageName.MainClassName)의 정규화 된 이름을 사용하여 실행합니다.

예:

내 수업은 다음과 같습니다.

D:\project\com\cse\

메인 클래스의 정규화 된 이름은 다음과 같습니다.

com.cse.Main

그래서 cd루트 프로젝트 디렉토리로 돌아갑니다.

D:\project

그런 다음 java명령을 발행하십시오 .

java com.cse.Main

이 답변은 일반적인 실수로 인한 좌절에서 초보자 자바 프로그래머를 구출하기위한 것입니다 .Java 클래스 경로에 대한 자세한 지식은 허용되는 답변을 읽는 것이 좋습니다.


2
이 대답은 가정의 전체를 만듭니다. 그리고 이것을 달성하는 다른 방법이 있습니다. 위의 조언을 맹목적으로 따르는 대신 사람들이 Java 클래스 경로의 작동 방식을 설명하는 내 답변의 링크를 읽는 것이 좋습니다. 무엇을하고 있는지 이해하는 것이 좋습니다.
Stephen C

2
이 답변은 내가 필요로 한 정확한 가정을합니다. : .class 파일의 디렉토리에 있었고 java.exe가 작동하지 않았습니다. 위에서 CD를 작성하고 명령 줄에 포함 된 패키지 이름으로 실행하면 작동했습니다.
Nick Constantine

61

에서 메인 클래스와 메인 메소드를 정의하는 경우 클래스package 의 전체 이름을 사용하여 계층 디렉토리에서 실행해야합니다 (packageName.MainClassName )을 .

소스 코드 파일 (Main.java)이 있다고 가정하십시오.

package com.test;

public class Main {

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

이 코드를 실행하려면 Main.Classdirectory와 같은 패키지에 배치해야합니다 ./com/test/Main.Java. 그리고 루트 디렉토리에서을 사용하십시오 java com.test.Main.


1
내 답변의 "추가 메모 # 1"을 참조하십시오. 이 문제에 대한 자세한 설명.
Stephen C

14
@StephenC 예, 귀하의 답변은 더 완전하지만 (물론 +1),이 답변에는 "package"라는 단어가 포함되어있어 필요한 것을 빨리 찾을 수 있습니다. 그리고 효과가있었습니다. 라 자비 +1 StephenC, Java를 처음 접했을 때 필요한 간단한 패키지 예제가 부족합니다.
kmort

5
이것은 정확히 내 문제였습니다. 나는 수많은 Java 문서를 겪어 왔으며이 구체적인 예는 내가 필요한 것입니다
John

1
예, 구체적인 예는 훌륭합니다. 이것은 완벽하게 작동했습니다. 나는 주된 대답이 매우 철저하다고 확신하지만 숲의 나무를보기가 어려웠습니다. 멋진 @Razavi
Pixel

1
나는 받아 들여지는 것보다 짧고 유용한 답을 좋아합니다!
Spara

46

동일한 코드가 한 PC에서 작동하지만 다른 PC에서 오류가 표시되면 내가 찾은 최고의 솔루션은 다음과 같이 컴파일하는 것입니다.

javac HelloWorld.java
java -cp . HelloWorld

2
권장하지 않습니다. 설정되지 않았거나 "."와 일치하는 값을 갖는 CLASSPATH 환경 변수에 따라 다릅니다. 예, 많은 경우에 작동하지만 다른 경우에는 작동하지 않습니다.
Stephen C

확실히 javac -classpath . HelloWorld.java일했을 것 입니다! 그리고 그것은 당신의 경우에 더 나은 해결책입니다.
Stephen C

2
첫 번째 줄로 'package com.some.address'가 있으면 작동하지 않습니다. '패키지 주소'를 주석 처리해야합니다.
Joe

1
@Joe-해킹 (패키지 주석 처리)이 작동하지만 (경우에 따라) 나쁜 생각입니다. 더 좋은 아이디어는 문제의 원인을 배우고 이해하고 올바른 솔루션을 구현하는 것입니다.
Stephen C

36

명령 줄에서 클래스 경로를 지정하는 데 도움이 된 것은 다음과 같습니다.

  1. 새 폴더를 만들고 C:\temp

  2. C:\temp에 다음 클래스와 함께 Temp.java 파일을 작성하십시오 .

    public class Temp {
        public static void main(String args[]) {
            System.out.println(args[0]);
        }
    }
  3. folder에서 명령 행을 열고 C:\temp다음 명령을 작성하여 Temp 클래스를 컴파일하십시오.

    javac Temp.java
  4. 컴파일 된 Java 클래스를 실행하고 -classpathJRE에 클래스를 찾을 위치를 알려주 는 옵션을 추가하십시오 .

    java -classpath C:\temp Temp Hello!

3
우분투에서는 경로도 지정해야했습니다. 기본적으로 현재 작업 디렉토리를 사용할 수없는 이유를 이해하지 마십시오. 키보드 제조업체가 Java를 후원한다고 확신합니다 !!
갔다

1
@gone-그 이유는 "." 기본적으로 $ PATH에 없으면 보안 트랩입니다. seas.upenn.edu/cets/answers/dot-path.html
Stephen C

자바가 환경 변수에서 클래스 경로를 설정 한 후에도 클래스 경로를 찾을 수없는 이유는 확실하지 않지만이 점에 대해 감사드립니다.
akash89

@ akash89 - 가장 가능성있는 이유가되었다 : 1) java당신이 클래스 경로 설정이 아니었다 환경에 설정되어 있지 -classpath 또는 -jar) 또는 2)를 사용하기 때문에 ($ CLASSPATH보고되지 않은 효과 맥락에서 java였다 운영; 예를 들어 오른쪽 쉘에서 setenv 명령을 추가 한 파일을 "소스"하지 않았기 때문입니다.
Stephen C

여전히 오류가 발생했습니다. 주 클래스를 찾거나로드 할 수 없습니다. Temp 누구든지 도울 수 있습니다!
Star

27

오류 메시지 ( "메인 클래스를 찾거나로드 할 수 없습니다")에 따르면 두 가지 범주의 문제가 있습니다.

  1. 메인 클래스를 찾을 수 없습니다
  2. 메인 클래스를 로드 할 수 없습니다 (이 사례는 허용 된 답변에서 완전히 논의되지 않았습니다)

메인 클래스는 할 수없는 발견 이있을 때 오타 나 잘못된 구문이 정규화 된 클래스 이름에 있거나 제공된 클래스 경로에 존재하지 않는 .

클래스를 시작할 수 없을 때 메인 클래스를 로드수 없습니다 . 일반적으로 기본 클래스는 다른 클래스를 확장하고 해당 클래스가 제공된 클래스 경로에 없습니다.

예를 들면 다음과 같습니다.

public class YourMain extends org.apache.camel.spring.Main

낙타 스프링이 포함되어 있지 않으면이 오류가보고됩니다.


"기본적으로"다른 카테고리도 많이 있습니다. 누락 된 수퍼 클래스 문제는 매우 드문 하위 사례입니다. (이 사이트에서 묻는 질문에서 내가 본 적이없는 것은 매우 이상합니다.)
Stephen C

오류에 "주 클래스를 찾을 수 없거나로드 할 수 없습니다"라는 오류가 있기 때문에 두 가지가 있습니다. 다른 카테고리가 있으면 알려주세요. 나는 그것을 보았으므로 다른 누군가가 그것을 필요로 할 것입니다.
Xiao Peng-ZenUML.com 1

1
"이 특정 오류를 피하기 위해 기본 클래스를 시작하는 데 필요한 모든 클래스를 포함해야합니다"와 같이 수정했습니다. 나는 당신을 설득하려고하지 않습니다. 내가보고 싶은 방법 일뿐입니다. 나는 이런 식으로 물건을 읽는 것을 좋아하는 사람들을 위해 여기에 답을 남겼습니다. 이 논의를 더 이상 확장하지 말자 :) 나는 나의 진술을 "허용 된 답변에서 완전히 논의되지 않았다"로 바꾸었고 기분이 나아지기를 바란다.
Xiao Peng-ZenUML.com

5
이 정보는 중요하며 명시적인 언급이 필요합니다 (이것이 언급 한 유일한 답변입니다 extends). 난 그냥 메인 클래스가 실패 할 때하는 어려운 방법 배운 부하 가 될 수있는 또 다른 확장 때문에 발견을 , 자바는 찾을 수 없습니다 실제 어떤 클래스보고하지 않습니다 (달리를 NoClassDefFoundError). 그래서 그렇습니다. 그리고 당신이 이것을 모르는 것은 머리를 찌르는 상황입니다.
Hugues M.

1
이 상황에서 어떤 종속성 클래스가로드에 실패하는지 정확하게 알 수있는 방법이 있습니까?
Carlos A. Ibarra

16

이 경우 이러한 오류가 발생했습니다.

java -cp lib.jar com.mypackage.Main

;Windows 및 :Unix에서 작동합니다 .

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

예. MainJAR 파일에 없기 때문일 가능성이 큽니다 . 즉 현재 디렉토리가 클래스 경로에 포함 된 -cp lib.jar;것과 같은 것을 의미합니다 -cp lib.jar;..
Stephen C

유닉스에 대한 마지막으로 문제를 해결 .. 감사 (와 함께 작동)
Vicky

16

-Xdiag 시도 하십시오 .

Steve C의 대답 은 가능한 경우를 훌륭하게 다루지 만 때로는 클래스를 찾을 수 없거나 로드 할 수 있는지 여부를 결정하는 것이 쉽지 않을 수도 있습니다. java -XdiagJDK 7부터 사용하십시오 . 메시지 Could not find or load main class메시지의 의미에 대한 힌트를 제공하는 멋진 스택 추적을 인쇄 합니다.

예를 들어, 메인 클래스가 사용하지 못하고 메인 클래스가로드되지 못하게하는 다른 클래스를 가리킬 수 있습니다.


16

이 명령을 사용하십시오 :

java -cp . [PACKAGE.]CLASSNAME

예 : 클래스 이름이 Hello.java에서 작성된 Hello.class 인 경우 아래 명령을 사용하십시오.

java -cp . Hello

파일 Hello.java가 com.demo 패키지 안에 있으면 아래 명령을 사용하십시오

java -cp . com.demo.Hello

JDK 8을 사용하면 클래스 파일이 동일한 폴더에 존재하지만 java명령에 클래스 경로가 필요하기 때문에 -cp .현재 폴더를 클래스 경로의 참조로 사용하도록 추가 합니다.


이것은 간단한 경우에만 작동합니다. 더 복잡한 경우에는 더 복잡한 클래스 경로가 필요합니다.
Stephen C

그리고 >> really << 간단한 경우에는 -cp .불필요합니다. $CLASSPATH설정되어 .있지 않으면 기본 클래스 경로입니다.
Stephen C

Windows 기본 클래스 경로에서 여러 번 Stephen이 작동하지 않습니다. 나는 세 가지 다른 컴퓨터에서 시도해 보았습니다.
shaILU

실제로 % CLASSPATH % 환경 변수를 어딘가에 설정했기 때문일 수 있습니다. 그렇게하면 기본 클래스 경로를 사용하지 않는 것입니다. ( echo %CLASSPATH%출력 은 무엇입니까 ?) 그리고 아니요, Windows PC가 없기 때문에 확인할 수 없습니다.
Stephen C

2
커맨드 라인에서 간단한 프로그램을 실행하려고 할 때 이것은 나를 위해 일했다
SnuKies

15

때때로 문제를 일으키는 것은 메인 클래스와 아무 관련이 없으며, 이것을 어려운 방법으로 찾아야했습니다. 내가 옮긴 참조 라이브러리 였고 나에게 다음을 주었다.

주 클래스 xxx Linux를 찾거나로드 할 수 없습니다

방금 해당 참조를 삭제하고 다시 추가 한 후 다시 정상적으로 작동했습니다.


1
문제는 IDE의 프로젝트에서 "참조"가 손상되어 잘못된 클래스 경로가있는 것 같습니다. 그 경우를 다루기 위해 답변을 업데이트하겠습니다.
Stephen C

@StephenC와 EduardoDennis, 여기에도 항아리가 없었으며, 그 항아리에는 기본 클래스가 인스턴스화하기 위해 의존했던 인터페이스가 포함되어있었습니다. 따라서 오류 메시지가 너무 넓습니다. 클래스 파일을 찾을 수 없으면 "찾을 수 없음"이라고 말하고 파일이 아닌 다른 파일이없는 경우 "로드 할 수 없음 (종속 종속성 없음)"이라고 말해야합니다. 그것의 "찾기"부분에 :(
Aquarius Power

@AquariusPower-클래스가 누락되었다는 "원인"예외에 대한 "원인"스택 추적이 추가로 있어야합니다. Java 개발자에게 20 년 이상 동안 오류 메시지가 변경되었다고 제안하고 싶다면 ... (오류 메시지가 정확하다고 생각합니다. 문제는 >> you <<가 잘못된 절로 좁혀 졌다는 것입니다.)
Stephen C

@StephenC는 메인 클래스 파일을 사용할 수 있는지 여부에 관계없이 반드시 정보에 액세스 할 수 있으므로 그러한 파일이 누락되었다는 더 나은 오류 메시지를 표시하지 않는 이유는 무엇입니까? 다른 한편으로, 그들은 그 시점에서 "파일을 찾았지만로드 할 수 없습니다"라고 말할 수도 있습니다. 우리는 반나절을 연구하고 이해하기 위해 테스트하는 대신 의존성에 즉시 집중할 것입니다. 단지 내가 의미 한 것은 :). 그들은 20 년 이상 제한된 방식으로 그것을 할 수 있지만, 그것을 향상시킬 수 있으며 우리는 우리의 비판과 불만을 통해 일어날 것을 인정하기 위해 여기 있습니다! : D
물병 자리 힘 1

>> I <<의 의미를 이해하십시오. 3 살짜리 Q & A에 대한 모호한 의견으로 그것에 대해 불평하는 것은 아무것도 달성하지 못할 것입니다. 귀하의 불만에 대해 명백하게 행동 할 수있는 사람들은이를 알지 못할 것입니다. 건설적인 일을하고 싶다면 패치를 제출하십시오. (나는 당신의 기회를 평가하지 않지만, 당신이 그냥 그것에 대해 휘두르는 것보다 더 클 것입니다.)
Stephen C

10

이 경우에는 다음이 있습니다.

메인 클래스 ? classpath를 찾거나로드 할 수 없습니다

"-classpath"를 사용하고 있기 때문에 대시는 java명령 프롬프트에서 사용하는 대시와 동일하지 않습니다 . 메모장 에서 cmd로 복사하여 붙여 넣는 데 문제가있었습니다 .


2
와! 그것은 완전히 기괴한 원인입니다! (그러나 실제 텍스트 편집기 대신 메모장을 사용하는 것이 좋습니다 :-))
Stephen C

10

나는 같은 문제가 있었고 마침내 내 실수를 발견했다 :) 나는이 명령을 컴파일에 사용했고 올바르게 작동했다.

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

7

필자의 경우 클래스 이름 대신 소스 파일 이름을 제공했기 때문에 오류가 발생했습니다.

메인 메소드를 포함하는 클래스 이름을 인터프리터에게 제공해야합니다.


예. 클래스 이름을 지정하는 잘못된 방법 중 내 예제 # 2를 참조하십시오 !!
Stephen C

7

귀하의 사례가 특히 내 것과 같은 경우 도움이 될 수 있습니다. 초보자로서 Java 프로그램을 실행하려고 할 때도이 문제가 발생했습니다.

나는 이것을 다음과 같이 컴파일했다.

javac HelloWorld.java

그리고 나는 같은 확장으로 실행하려고했습니다.

java Helloworld.java

를 제거하고 .java와 같은 명령을 다시 작성 java HelloWorld하면 프로그램이 완벽하게 실행되었습니다. :)


2
컴파일 된 버전의 .java를 실행하고 있기 때문입니다. 실제로 .class 파일을 실행하고 있습니다
Jason V

기록을 위해, 이것은 내 대답의 이유 # 1, 예 # 5와 같습니다 ...
Stephen C

6

여기에있는 모든 답변은 Windows 사용자를 대상으로합니다. Mac의 경우 클래스 경로 구분 기호는 :아닙니다 ;. 클래스 경로를 사용하여 오류를 설정하면 오류 ;가 발생하지 않으므로 Windows에서 Mac으로 올 경우 발견하기가 어려울 수 있습니다.

해당 Mac 명령은 다음과 같습니다.

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

이 예제에서 패키지가 com.test있고 lib폴더도 클래스 경로에 포함됩니다.


2
Mac에서와 마찬가지로 Linux에서.
Alex78191

/*필요한가요?
Alex78191

와일드 카드 구문입니다. (필수 사항은 아닙니다. 원하는 경우 JAR을 명시 적으로 나열 할 수 있습니다.)
Stephen C

6

여기에 이미지 설명을 입력하십시오

수업 파일 위치 : C : \ test \ com \ company

파일 이름 : Main.class

정규화 된 클래스 이름 : com.company.Main

명령 줄 명령 :

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

클래스 경로에는 \ com \ company가 포함되지 않습니다.


6

나는이 문제를 해결하기 위해 상당한 시간을 보냈다. 어떻게 든 클래스 경로를 잘못 설정했다고 생각했지만 문제는 내가 입력 한 것입니다.

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

대신에:

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

정규화 된 의미는 전체 패키지 이름 대신 전체 경로 이름을 포함하는 것으로 생각했습니다.


그 혼란을 해결하기 위해 답변을 업데이트했습니다.
Stephen C

2
둘 다 맞지 않습니다. 클래스는 utilities.myapp.Cool패키지 이름이 있거나 무엇이든 관계없이 제공되어야합니다 .
user207421

5

먼저이 명령을 사용하여 경로를 설정하십시오.

set path="paste the set path address"

그런 다음 프로그램을로드해야합니다. 저장된 드라이브에 "cd (폴더 이름)"을 입력하고 컴파일하십시오. 예를 들어, 프로그램이 D 드라이브에 저장된 경우 "D :"를 입력하고 Enter를 누르고 "cd (폴더 이름)"을 입력하십시오.


4
도움이되지 않습니다. 이 질문은 일반적인 실행 파일이 아닌 Java 프로그램에 관한 것입니다. Java는 PATH를 사용하여 항목을 찾지 않으며 "cd"가 도움이된다면 판단보다는 운이 도움이됩니다.
Stephen C

if "cd" helps then it by luck rather than by judgement. java .가 기본적으로 현재 디렉토리 를 클래스 경로의 일부로 사용하기 때문에 이것은 잘못입니다 (믿습니다) .
GKFX

2
@GKFX-이것이 바로 그 의미입니다. 기본 클래스 경로 (또는 "."가있는 클래스 경로)를 사용하고 있지 않다면 "cd"는 효과가 없습니다. 이 솔루션은 판단 (예 : "."이 클래스 경로에 있는지 확인)보다 운이 좋게 (즉, "."가 클래스 경로에 있다고 추측 / 바라고) 더 효과적입니다. 또한 기본값에 대해 잘못되었습니다. 자바는 "." 기본적으로 클래스 경로의 일부가 아닌 클래스 경로로 사용됩니다.
Stephen C

5

내 경우 문제를 해결 한 것은 다음과 같습니다.

실행할 프로젝트 / 클래스를 마우스 오른쪽 버튼으로 클릭 한 다음 Run As-> 를 클릭하십시오 Run Configurations. 그런 다음 기존 구성을 수정하거나 다음 방법으로 새 ​​구성을 추가해야합니다.

Classpath탭을 열고 Advanced...버튼을 클릭 한 다음 프로젝트의 bin폴더 를 추가 하십시오.


5

당신이 사용하는 경우 메이븐을 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>

4

이것은 특정한 경우이지만 솔루션을 찾기 위해이 페이지를 방문하여 찾지 못 했으므로 여기에 추가하겠습니다.

Windows (7로 테스트 á)는 클래스 및 패키지 이름에 특수 문자 (예 :)를 허용하지 않습니다 . 그러나 리눅스는 그렇지 않습니다.

.jarNetBeans를 빌드하고 명령 줄에서 실행하려고 시도 했을 때 이것을 발견했습니다 . NetBeans에서 실행되었지만 명령 행에서는 실행되지 않았습니다.


4

Windows .;에서는 처음에 CLASSPATH 값을 입력하십시오.

. (점)은 "현재 디렉토리를 봅니다"를 의미합니다. 이것은 영구적 인 해결책입니다.

또한 set을 사용하여 "한 번만"설정할 수 CLASSPATH=%CLASSPATH%;.있습니다. cmd 창이 열려있는 한 지속됩니다.


1
이 조언은 도움이 될 수도 있고 도움이되지 않을 수도 있습니다. 클래스 트리에 현재 디렉토리의 클래스가 포함되어 있으면 도움이됩니다. 그렇지 않으면 그렇지 않습니다. 나는 실제로 이것을하지 않을 것입니다. 대신 사용자가 "올바른"디렉토리에 있는지 여부에 관계없이 하나의 라이너 래퍼 스크립트를 작성합니다.
Stephen C

4

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]);
            }
        }
    }

그런 다음 cdsrc 폴더로 이동해야하며 실행 해야하는 명령은 다음과 같습니다.

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

2
클래스는 "CommandLine.class"라고 할 수 없습니다. Java 구문 오류입니다. (컴파일 된 클래스를 포함하는 파일은 "CommandLine.class"...입니다.) 또 다른 문제는 소스 디렉토리 트리에서 >> into << 코드를 컴파일 한 경우에만 "소스 디렉토리로 CD"명령이 작동한다는 것입니다. 마지막으로, 컴파일에서 "-cp"인수를 사용한 경우 실행할 때 이에 해당하는 항목이 필요합니다.
Stephen C

내 프로젝트에는 루트에 src 폴더와 bin 폴더가 있습니다. 나는에 있었다 cd으로 src다음 명령을 실행합니다 java ../bin com.blah.blah.MyClass날 위해 일했습니다. 팁 주셔서 감사합니다!
tamj0rd2

3

Java에서 때로는 Java 실행 파일을 사용하여 명령 행에서 JVM을 실행하고 공용 정적 무효 주 (PSVM)를 사용하여 클래스 파일에서 프로그램을 시작하려고 할 때 classpath 매개 변수가 다음과 같은 경우에도 아래 오류가 발생할 수 있습니다. JVM이 정확하고 클래스 파일이 클래스 경로에 있습니다.

Error: main class not found or loaded

PSVM이있는 클래스 파일을로드 할 수없는 경우에 발생합니다. 그 이유 중 하나는 클래스가 인터페이스를 구현하거나 클래스 경로에없는 다른 클래스를 확장 할 수 있기 때문입니다. 일반적으로 클래스가 클래스 경로에 없으면 발생 된 오류가 그와 같이 나타납니다. 그러나 사용중인 클래스가 확장되거나 구현 된 경우 java는 클래스 자체를로드 할 수 없습니다.

참조 : https://www.computingnotes.net/java/error-main-class-not-found-or-loaded/


1
수락 된 답변을 읽었습니까? 당신의 대답은 새로운 것을 추가합니까?
Stephen C

1
@StephenC 나는 "이유"카테고리와 그 요점을보고 당신의 목록에서 이유를 찾으려고 노력했습니다. "이유 # 1"및 "이유 # 2"제목에서 일치하는 지점을 찾을 수 없었습니다 (클래스 경로 자체에 문제가 없음을 확신했기 때문에). 실험을 수행하여 이유를 찾았으며 인터페이스 구현이 클래스 경로에 없기 때문에 "주 클래스를 찾을 수 없음"오류가 표시되는 것에 놀랐습니다. 물론 "포스트에 설명 된 모든 것을 읽어야한다"고 말할 수 있지만, 이유 목록을 개선 할 수있는 것 같습니다.
gumkins

3

Windows PowerShell에서 보급 된 옵션을 사용 하여 javawith를 실행하면 -cp다음과 같은 오류가 발생할 수 있습니다.

The term `ClassName` is not recognized as the name of a cmdlet, function, script ...

PowerShell이 ​​명령을 수락하려면 -cp옵션 의 인수가 다음 과 같이 따옴표로 묶어야합니다.

java -cp 'someDependency.jar;.' ClassName

이런 식으로 명령을 구성하면 Java가 클래스 경로 인수를 올바르게 처리 할 수 ​​있어야합니다.


3

Java MongoDB JDBC 연결을 테스트하는 동안 비슷한 오류가 발생했습니다. 나는 최종 해결책을 간략하게 요약하여 장차 누군가가 두 가지 명령을 직접 볼 수 있고 더 나아갈 수 있다고 생각합니다.

Java 파일 및 외부 종속성 (JAR 파일)이 존재하는 디렉토리에 있다고 가정하십시오.

엮다:

javac -cp mongo-java-driver-3.4.1.jar JavaMongoDBConnection.java
  • -cp- 클래스 경로 인수; 모든 종속 JAR 파일을 하나씩 전달
  • * .java-주요 메소드가있는 Java 클래스 파일입니다. sdsd

운영:

java -cp mongo-java-driver-3.4.1.jar: JavaMongoDBConnection
  • 모든 종속 JAR 파일이 종료 된 후 콜론 (Unix) / 쉼표 (Windows)를 확인하십시오.
  • 마지막으로 확장명이없는 기본 클래스 이름을 확인하십시오 (.class 또는 .java 없음).

이것은 모두 1) JavaMongoDBConnection패키지가 없으며 2) 디렉토리를 변경하지 않는다고 가정합니다 . 말하자면, 깨지기 쉬운 것입니다. 그리고 문제를 설명하지 않으면 초보자가 작동하지 않는 상황 에서이 접근법을 시도 하게됩니다 . 간단히 말해, "부두 프로그래밍 기술"을 권장합니다. en.wikipedia.org/wiki/Voodoo_programming
Stephen C

3

이미 많은 답변이 있지만 파일 권한이 범인이 될 수있는 사례는 아무도 언급하지 않았습니다.

실행시, 사용자는 JAR 파일 또는 경로의 디렉토리 중 하나에 액세스 할 수 없습니다. 예를 들어, 다음을 고려하십시오.

Jar 파일 /dir1/dir2/dir3/myjar.jar

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에 대해서는 여전히 오류가 발생합니다.


2

이 작업을 수행 한 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" />

2

여기에 언급 된 솔루션으로는이 문제를 해결할 수 없었습니다. 나는이 문제에 두 번 직면하고 다른 솔루션을 시도 할 때마다 (Eclipse IDE에서).

  • 첫째, 나는 main프로젝트의 다른 클래스에서 여러 가지 방법을 발견했습니다. 따라서 main후속 클래스 에서 메소드를 삭제했습니다 .
  • 둘째, 다음 해결책을 시도했습니다.
    1. 메인 프로젝트 디렉토리를 마우스 오른쪽 버튼으로 클릭하십시오.
    2. 소스로 이동 한 다음 기본 설정으로 마무리하고 완료하십시오. 백그라운드 작업이 끝나면 기본 프로젝트 디렉토리로 이동합니다.
    3. 그 후 프로젝트를 닫고 다시 열고 붐을 일으켜 마침내 문제를 해결했습니다.

1
main메소드를 삭제 해도 문제가 해결되지 않습니다. 여러 진입 점이있는 응용 프로그램에는 기술적으로 문제가 없습니다.
Stephen C
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.