Java 'no main manifest attribute' 오류 해결 방법

JavaBeginner
지금 연습하기

소개

Java 애플리케이션을 JAR (Java Archive) 파일로 패키징하고 실행할 때, 개발자는 종종 'no main manifest attribute' 오류를 마주하게 됩니다. 이 오류는 JAR 파일을 실행하려고 할 때 발생하지만, Java Virtual Machine (JVM) 이 애플리케이션을 시작하기 위한 main 메서드를 포함하는 클래스를 결정할 수 없을 때 발생합니다.

이 랩은 이 흔한 오류를 이해하고, 진단하며, 해결하는 과정을 안내합니다. 이 튜토리얼을 마치면, main 클래스를 올바르게 지정하는 매니페스트 파일로 JAR 파일을 적절하게 구성하는 방법을 알게 될 것입니다.

간단한 Java 애플리케이션 생성

JAR 파일로 패키징할 간단한 Java 애플리케이션을 생성하는 것으로 시작해 보겠습니다. 이는 'no main manifest attribute' 오류를 시연하고 나중에 수정하는 데 도움이 될 것입니다.

Java 클래스 생성

먼저, Java 소스 파일을 위한 디렉토리를 생성하고 해당 디렉토리로 이동합니다.

cd ~/project/src/com/example

이제 편집기를 열고 이 디렉토리에 HelloWorld.java라는 새 파일을 생성합니다.

  1. WebIDE 의 왼쪽 사이드바에서 "Explorer" 아이콘을 클릭합니다.
  2. /home/labex/project/src/com/example로 이동합니다.
  3. 마우스 오른쪽 버튼을 클릭하고 "New File"을 선택합니다.
  4. 파일 이름을 HelloWorld.java로 지정합니다.

HelloWorld.java 파일에 다음 코드를 추가합니다.

package com.example;

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}

이것은 실행될 때 콘솔에 "Hello, World!"를 출력하는 main 메서드를 가진 기본적인 Java 프로그램입니다.

Java 클래스 컴파일

이제 Java 클래스를 컴파일해 보겠습니다. 터미널로 돌아가 프로젝트 루트 디렉토리로 이동합니다.

cd ~/project

javac 명령을 사용하여 Java 파일을 컴파일합니다.

javac -d . src/com/example/HelloWorld.java

이 명령은 Java 소스 파일을 컴파일하고 패키지 이름을 기반으로 컴파일된 클래스 파일을 적절한 디렉토리 구조에 배치합니다.

이제 ~/project/com/example/HelloWorld.class에 컴파일된 클래스 파일이 있어야 합니다. 다음 명령으로 확인할 수 있습니다.

ls -l com/example/

출력은 HelloWorld.class 파일을 표시해야 합니다.

total 4
-rw-r--r-- 1 labex labex 426 [date] HelloWorld.class

매니페스트 없이 기본 JAR 파일 생성

이제 매니페스트에서 main 클래스를 지정하지 않고 JAR 파일을 생성해 보겠습니다. 이를 통해 'no main manifest attribute' 오류를 재현할 수 있습니다.

jar cf HelloWorld.jar com/

이 명령은 컴파일된 클래스 파일을 포함하는 HelloWorld.jar라는 JAR 파일을 생성합니다.

JAR 파일 실행 시도

이제 JAR 파일을 생성했으므로 실행해 보겠습니다.

java -jar HelloWorld.jar

다음 오류 메시지가 표시됩니다.

no main manifest attribute, in HelloWorld.jar

이것이 우리가 수정하려는 오류입니다. JAR 의 매니페스트에서 main 클래스를 지정하지 않았기 때문에 JVM 이 실행할 main 클래스를 찾을 수 없습니다.

'no main manifest attribute' 오류 이해

이 단계에서는 'no main manifest attribute' 오류의 원인을 살펴보고 JAR 파일 매니페스트가 어떻게 작동하는지 이해해 보겠습니다.

매니페스트 파일이란 무엇인가요?

JAR 파일에는 META-INF 디렉토리에 MANIFEST.MF라는 특수한 파일이 포함되어 있습니다. 이 매니페스트 파일에는 JAR 및 해당 내용에 대한 메타데이터가 포함되어 있습니다. 매니페스트가 포함할 수 있는 중요한 정보 중 하나는 Main-Class 속성입니다. 이 속성은 JAR 이 실행될 때 실행할 main 메서드를 포함하는 클래스를 JVM 에 알려줍니다.

현재 JAR 파일의 매니페스트를 살펴보겠습니다.

mkdir -p temp_dir
cd temp_dir
jar xf ../HelloWorld.jar META-INF/MANIFEST.MF
cat META-INF/MANIFEST.MF

다음과 유사한 최소 매니페스트가 표시됩니다.

Manifest-Version: 1.0
Created-By: 1.8.0_XXX (Oracle Corporation)

이 매니페스트에는 Main-Class 속성이 없다는 점에 유의하세요. 이것이 JAR 을 실행하려고 할 때 'no main manifest attribute' 오류가 발생하는 이유입니다.

JAR 파일의 내용 보기 방법

JAR 파일을 더 잘 이해하기 위해 내용을 살펴보겠습니다.

cd ~/project
jar tf HelloWorld.jar

이 명령은 JAR 의 모든 파일을 나열합니다. 출력은 다음과 유사해야 합니다.

META-INF/
META-INF/MANIFEST.MF
com/
com/example/
com/example/HelloWorld.class

보시다시피, JAR 에는 예상대로 컴파일된 클래스 파일이 포함되어 있지만, 매니페스트에는 main 클래스를 식별하는 데 필요한 정보가 없습니다.

이 오류는 언제 발생하나요?

'no main manifest attribute' 오류는 일반적으로 다음과 같은 상황에서 발생합니다.

  1. 매니페스트에서 main 클래스를 지정하지 않고 JAR 파일을 생성한 경우
  2. java -jar를 사용하여 JAR 파일을 실행하려고 시도했지만 JAR 이 실행 가능하도록 의도되지 않은 경우
  3. 매니페스트 파일이 존재하지만 Main-Class 속성을 포함하지 않는 경우

이 경우, 오류를 시연하기 위해 main 클래스를 지정하지 않고 의도적으로 JAR 을 생성했습니다.

임시 디렉토리를 정리해 보겠습니다.

cd ~/project
rm -rf temp_dir

이제 오류의 원인을 이해했으므로, 다음 단계에서는 적절한 매니페스트 파일을 생성하여 이를 수정하겠습니다.

매니페스트 파일 생성

이제 문제를 이해했으므로, main 클래스를 지정하는 적절한 매니페스트 파일을 생성하여 이를 수정해 보겠습니다.

매니페스트 파일 생성

먼저, 프로젝트 디렉토리로 다시 이동합니다.

cd ~/project

이제 manifest.txt라는 텍스트 파일을 생성합니다.

  1. WebIDE 의 왼쪽 사이드바에서 "Explorer" 아이콘을 클릭합니다.
  2. /home/labex/project로 이동합니다.
  3. 마우스 오른쪽 버튼을 클릭하고 "New File"을 선택합니다.
  4. 파일 이름을 manifest.txt로 지정합니다.

manifest.txt 파일에 다음 내용을 추가합니다.

Main-Class: com.example.HelloWorld

파일 끝에 줄 바꿈 문자를 추가해야 합니다 (매니페스트 형식은 파일이 줄 바꿈 문자로 끝나야 함). WebIDE 에서는 위 줄을 입력한 후 Enter 키를 누르기만 하면 됩니다.

이 간단한 매니페스트 파일은 com.example.HelloWorld 클래스에 JAR 이 실행될 때 실행되어야 하는 main 메서드가 포함되어 있음을 지정합니다.

매니페스트로 새 JAR 파일 생성

이제 새 JAR 파일을 생성합니다. 이번에는 사용자 지정 매니페스트를 포함합니다.

jar cfm HelloWorldWithManifest.jar manifest.txt com/

이 명령은 컴파일된 클래스 파일을 포함하고 사용자 지정 매니페스트 파일을 사용하는 HelloWorldWithManifest.jar라는 새 JAR 파일을 생성합니다.

이 명령에 사용된 옵션은 다음과 같습니다.

  • c: 새 아카이브 생성
  • f: 아카이브 파일 이름 지정
  • m: 지정된 매니페스트 파일에서 매니페스트 정보 포함
  • 나머지 인수는 JAR 에 포함할 파일/디렉토리입니다.

새 JAR 에서 매니페스트 확인

매니페스트가 JAR 에 올바르게 포함되었는지 확인해 보겠습니다.

mkdir -p temp_check
cd temp_check
jar xf ../HelloWorldWithManifest.jar META-INF/MANIFEST.MF
cat META-INF/MANIFEST.MF

이제 매니페스트에 Main-Class 속성이 포함되어 있는 것을 볼 수 있습니다.

Manifest-Version: 1.0
Created-By: [Java version info]
Main-Class: com.example.HelloWorld

이제 임시 디렉토리를 정리해 보겠습니다.

cd ~/project
rm -rf temp_check

수정된 JAR 파일 실행

이제 main 클래스를 지정하는 적절한 매니페스트가 있는 JAR 파일을 생성했으므로, 이를 실행하고 올바르게 작동하는지 확인해 보겠습니다.

JAR 파일 실행

프로젝트 디렉토리에 있는지 확인합니다.

cd ~/project

이제 java -jar 명령을 사용하여 JAR 파일을 실행합니다.

java -jar HelloWorldWithManifest.jar

이번에는 'no main manifest attribute' 오류 대신 프로그램의 출력이 표시됩니다.

Hello, World!

축하합니다. main 클래스를 지정하는 적절한 매니페스트 파일을 생성하여 'no main manifest attribute' 오류를 성공적으로 수정했습니다.

수정한 내용 이해

오류를 수정하기 위해 수행한 작업을 잠시 살펴보겠습니다.

  1. Main-Class 속성을 포함하는 매니페스트 파일을 생성하여 JVM 에 실행할 main 메서드를 포함하는 클래스를 알렸습니다.
  2. 이 매니페스트 정보를 통합하는 새 JAR 파일을 생성했습니다.
  3. java -jar 명령을 사용하여 JAR 을 실행했고, JVM 은 main 메서드를 찾아서 실행할 수 있었습니다.

Main 클래스를 지정하는 다른 방법

JAR 파일로 작업할 때 main 클래스를 지정하는 다른 몇 가지 방법이 있습니다.

방법 1: JAR 생성 시 Main 클래스 지정

별도의 매니페스트 파일을 생성하는 대신, e 옵션을 사용하여 JAR 을 생성할 때 main 클래스를 직접 지정할 수 있습니다.

jar cfe HelloWorldDirect.jar com.example.HelloWorld com/

이렇게 하면 main 클래스가 com.example.HelloWorld로 지정된 HelloWorldDirect.jar라는 새 JAR 파일이 생성됩니다.

이 JAR 을 실행하여 작동하는지 확인해 보겠습니다.

java -jar HelloWorldDirect.jar

다음 출력이 표시됩니다.

Hello, World!

방법 2: 매니페스트를 사용하지 않고 JAR 실행

적절한 매니페스트가 없는 JAR 파일이 있는 경우, java 명령에서 main 클래스를 직접 지정하여 계속 실행할 수 있습니다.

java -cp HelloWorld.jar com.example.HelloWorld

이 명령은 JVM 에 클래스 경로 (-cp) 에서 HelloWorld.jar를 사용하고 com.example.HelloWorld 클래스를 실행하도록 지시합니다.

다음 출력이 표시됩니다.

Hello, World!

이 접근 방식은 실행할 클래스를 JVM 에 명시적으로 알려줌으로써 매니페스트의 필요성을 우회합니다.

요약

이 Lab 에서는 Java 에서 'no main manifest attribute' 오류에 대해 배우고 이를 해결하는 방법을 배웠습니다. 다룬 내용을 요약해 보겠습니다.

  1. 오류 이해: 'no main manifest attribute' 오류는 JAR 파일에서 실행할 main 클래스를 JVM 이 찾을 수 없을 때 발생합니다. 이는 매니페스트에 main 클래스가 지정되지 않았기 때문입니다.

  2. 적절한 매니페스트 생성: Main-Class 속성을 사용하여 main 클래스를 지정하는 매니페스트 파일을 생성하는 방법을 배웠습니다.

  3. 매니페스트로 JAR 파일 빌드: 매니페스트 정보를 포함하는 JAR 파일을 생성하는 방법을 배웠습니다.

    • 별도의 매니페스트 파일 사용 (jar cfm ...)
    • JAR 생성 시 main 클래스 직접 지정 (jar cfe ...)
  4. JAR 파일 실행: JAR 파일로 패키징된 Java 애플리케이션을 실행하는 다양한 방법을 배웠습니다.

    • 적절하게 구성된 매니페스트와 함께 java -jar 사용
    • 클래스 경로와 main 클래스를 명시적으로 지정하기 위해 java -cp 사용

이러한 기술은 Java 애플리케이션을 JAR 파일로 패키징하고 배포해야 하는 Java 개발자에게 필수적입니다. 매니페스트의 역할과 이를 올바르게 구성하는 방법을 이해함으로써 'no main manifest attribute' 오류를 방지하고 Java 애플리케이션이 원활하게 실행되도록 할 수 있습니다.

적절한 패키징은 훌륭한 코드를 작성하는 것만큼 중요합니다. 빌드 및 패키징을 올바르게 설정하는 데 시간을 할애하면 나중에 사용자와 개발자 모두의 좌절감을 덜 수 있습니다.