Computer >> 컴퓨터 >  >> 문제 해결 >> Windows 오류

Java '기본 클래스를 찾거나 로드할 수 없습니다' 오류 완벽 해결 가이드

명령 프롬프트에서 java 명령어를 사용해 Java 프로그램을 실행할 때 'Could not find or load main class(기본 클래스를 찾거나 로드할 수 없습니다)' 오류가 발생하는 경우가 있습니다. 이 오류는 대부분 시스템 문제가 아니라 사용자가 클래스를 선언하는 과정에서 발생한 실수 때문에 나타납니다.

이 오류는 앞서 언급했듯이 대부분 시스템과는 무관하며, 아래에서 설명할 여러 상황에서 사용자의 실수로 인해 발생합니다. 본격적으로 살펴보기 전에 독자 여러분이 Java 프로그래밍 언어의 기본 개념과 작동 방식을 이해하고 있다고 가정합니다.

Java에서 'Could not find or load main class' 오류의 원인은?

'Could not find or load main class' 메시지는 Java 엔진이 실행할 클래스를 가져오는 첫 번째 단계가 실패했음을 의미합니다. 즉, java 명령어가 해당 클래스를 올바른 디렉터리에서 찾지 못한 것입니다.

일부 경우에는 올바른 파일 경로를 추가하고 Java 터미널이 정확한 위치를 가리키도록 설정해야 합니다. 명령줄 터미널에서 직접 명령을 실행하기 때문에 컴퓨터는 클래스가 어디에 있는지 알지 못합니다. 반면 IDE(Integrated Development Environment)에서는 현재 작업 디렉터리를 자동으로 추적하는 포인터를 유지하기 때문에 이런 문제가 발생하지 않습니다.

'java <클래스명>' 구문이란?

문제 해결에 들어가기 전에 먼저 명령어 구문을 제대로 이해해야 합니다. 잘못된 구문을 사용하면 이 오류를 피할 수 없습니다.

java 명령어의 기본 구문은 다음과 같습니다:

java [ <option> ... ] <class-name> [<argument> ...]

여기서 <option>은 명령줄 옵션, <class-name>은 패키지를 포함한 완전한 한정 이름(FQN)의 Java 클래스명, <argument>는 컴파일된 애플리케이션에 전달되는 명령줄 인수입니다.

유효한 명령어의 예시는 다음과 같습니다:

java -Xmx100m com.acme.example.ListAppuals kevin arrows bart

위 명령어를 실행하면 java 명령어는 다음 작업을 순차적으로 수행합니다:

  • 컴파일된 'com.acme.example.ListAppuals' 클래스를 검색합니다.
  • 검색 후 해당 클래스를 로드합니다.
  • 클래스가 로드되면 유효한 시그니처, 접근 제어자, 반환 타입을 가진 'main' 메서드가 있는지 확인합니다. main 메서드의 표준 형태는 다음과 같습니다:
public static void main(String[])
  • 마지막으로 'kevin', 'arrows', 'bart'라는 인수를 String[] 형태로 전달하며 메서드를 호출합니다.

'Could not find or load main class' 오류 해결 방법

해결 방법 1: 클래스명 인수 확인

사용자들이 가장 흔히 저지르는 실수는 잘못된 형식의 클래스명을 인수로 전달하는 것입니다. 명령줄에서 매개변수를 직접 입력하기 때문에 클래스명을 잘못된 형식으로 넘길 가능성이 높습니다. 흔히 발생하는 실수 사례들을 정리했습니다.

  • 단순 클래스명만 사용하는 경우: 클래스가 'com.acme.example' 같은 패키지 안에 선언되어 있다면, Java 명령어에 반드시 패키지를 포함한 전체 클래스명(FQN)을 사용해야 합니다.
# 올바른 예
java com.acme.example.ListAppuals

# 잘못된 예
java ListAppuals
  • 파일명이나 경로명 대신 클래스명을 선언해야 합니다: Java는 경로명이나 파일명으로는 클래스를 찾지 못합니다. 다음은 모두 잘못된 입력 예시입니다:
java ListAppuals.class

java com/acme/example/ListAppuals.class
  • 대소문자 구분에 주의해야 합니다: Java 명령어는 대소문자를 엄격하게 구분합니다. 단 한 글자만 틀려도 기본 클래스를 로드할 수 없습니다. 잘못된 예시는 다음과 같습니다:
java com.acme.example.listappuals
  • 소스 파일명을 선언하지 않아야 합니다: 앞서 언급했듯이 올바른 전체 클래스명 형식으로만 클래스를 지정해야 합니다. 실수 예시는 다음과 같습니다:
java ListAppuals.java
  • 오타를 내거나 클래스명을 아예 입력하지 않은 경우에도 동일한 오류가 발생합니다.

클래스명 선언 과정에서 부주의한 실수를 했다면 이를 수정한 후 프로그램을 다시 실행해 보세요.

해결 방법 2: 클래스패스(Classpath) 확인

클래스명을 올바르게 선언했는데도 오류가 계속된다면, java 명령어가 지정된 경로에서 해당 클래스를 찾지 못했을 가능성이 큽니다. 클래스패스(classpath)란 Java 런타임이 리소스 및 클래스 파일을 검색하는 경로를 말합니다. 클래스패스는 아래 두 가지 방법으로 쉽게 설정할 수 있습니다:

C:> sdkTool -classpath classpath1;classpath2...

C:> set CLASSPATH=classpath1;classpath2...

클래스패스에 대해 더 자세히 알고 싶다면 다음 공식 문서를 참고하세요.

- Java 명령어 공식 문서
- Oracle 클래스패스 설정 가이드

해결 방법 3: 디렉터리 구조 확인

디렉터리를 클래스패스로 지정하면 그 디렉터리는 항상 네임스페이스의 루트(root)에 해당합니다. 예를 들어 '/usr/local/acme/classes'가 클래스패스에 있다면, Java는 'com.acme.example.Appuals' 클래스를 찾을 때 다음 경로를 탐색합니다:

/usr/local/acme/classes/com/acme/example/Appuals.class

따라서 본질적으로 아래와 같은 주소를 클래스패스에 넣으면 Java는 클래스를 찾지 못합니다:

/usr/local/acme/classes/com/acme/example

또한 하위 디렉터리 구조가 FQN(완전 한정 클래스명)과 일치하는지도 확인해야 합니다. 클래스의 FQN이 'com.acme.example.Appuals'라면, Java는 'com/acme/example' 디렉터리 안에서 'Appuals.class' 파일을 찾습니다.

구체적인 예시를 통해 살펴보겠습니다. 다음과 같은 상황을 가정합니다:

  • 실행하려는 클래스: com.acme.example.Appuals
  • 전체 파일 경로: /usr/local/acme/classes/com/acme/example/Appuals.class
  • 현재 작업 디렉터리: /usr/local/acme/classes/com/acme/example/

이때 각 명령어의 실행 결과는 다음과 같습니다:

# 오류: FQN(전체 클래스명)이 필요함
java Appuals

# 오류: 현재 작업 디렉터리에 `com/acme/example` 폴더가 없음
java com.acme.example.Appuals

# 오류: 위와 유사한 상황
java -classpath . com.acme.example.Appuals

# 성공: 상대 경로 클래스패스 설정됨
java -classpath ../../.. com.acme.example.Appuals

# 성공: 절대 경로 클래스패스 설정됨
java -classpath /usr/local/acme/classes com.acme.example.Appuals

참고: 클래스패스에는 애플리케이션이 필요로 하는 다른 모든 비시스템(non-system) 클래스들도 포함되어야 합니다.

해결 방법 4: 클래스 패키지 선언 확인

위의 모든 해결 방법을 적용했는데도 문제가 해결되지 않는다면, 소스 코드가 올바른 폴더에 위치해 있는지 확인해야 합니다. 또한 소스 코드 상단에 package 선언이 정확하게 되어 있는지도 점검이 필요합니다. IDE에서 코드를 실행한다면 IDE가 이런 문제를 자동으로 감지하고 알려주지만, 명령 프롬프트에서 실행하는 경우 실수가 그대로 드러나지 않고 결국 본문에서 다룬 클래스 오류로 이어지게 됩니다.