본문 바로가기
etc

no main manifest attribute in 에러

by 스르나 2021. 8. 3.

 no main manifest attribute in 에러는 spring 애플리케이션을 빌드한 결과물로 나온 jar파일에서 처음 호출할 Main 메소드를 찾지 못했다는 에러다.

 

주로 jar파일을 "java -jar app.jar" 명령어로 실행을 시킬떄 일어난다. java -jar를 사용해서 jar파일을 실행시킨다면 JVM이 jar파일의 Main메소드를 찾아서 호출한다. 이떄 Main메소드의 위치는 MANIFEST.MF라는 파일에 명시가 되어있다.

 

정상적인 경우 아래와 같이 Start-Class라는 이름의 Main메소드 위치가 나와야한다.

Manifest-Version: 1.0
Created-By: Maven Jar Plugin 3.2.0
Build-Jdk-Spec: 15
Implementation-Title: demo
Implementation-Version: 0.0.1-SNAPSHOT
Main-Class: org.springframework.boot.loader.JarLauncher
Start-Class: com.example.demo.DemoApplication
Spring-Boot-Version: 2.4.2
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Spring-Boot-Classpath-Index: BOOT-INF/classpath.idx
Spring-Boot-Layers-Index: BOOT-INF/layers.idx

 

그런데 no main manifest attribute in에러는 JVM이 MANIFEST.MF파일에서 Main메소드를 찾지 못하는 것이다. 찾지 못하는 이유는 간단하다. 없으니깐!

 

없는 이유는 다양하다. 각자의 프로젝트가 다양한 설정을 하고 있기 때문에 한번에 해결할 수 있는 방법은 없지만 해당 에러는 만나고 해결방법을 찾아본 결과 다음과 같은 해결 방법들이 있다.

 

1. Maven같은 경우 pom.xml에 Main메소드 위치를 명시해주는 방법(비추천)

build>
	<plugins>
		<plugin>
			<groupId>org.apache.maven.plugins</groupId>
			<artifactId>maven-jar-plugin</artifactId>
			<configuration> 
				<archive> 
					<manifest> 
					    <addClasspath>true</addClasspath>
						<mainClass>com.example.demo.DemoApplication</mainClass> 
					</manifest> 
				</archive> 
			</configuration>
		</plugin>
	</plugins>
</build>

위 방식은 실행은 되지만 다른 에러를 일으킨다(ClassNotFound)

 

2. Gradle 또한 build.gradle에 명시를 해주는 방법(비추천)

jar {
    manifest {
        attributes 'Main-Class': 'com.package.app.Class'
    }
}

이 방법또한 실행은 되지만 ClassNotFound를 일으켰다.

 

3. spring-boot-maven-plugin 의존성 추가(추천)

spring boot프로젝트를 jar파일로 만들때 필요한 정보를 MANIFEST.MF에 자동으로 추가해준다.

https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-maven-plugin

위 링크로 들어가서 의존성을 추가하면 된다.

 

4. 번외로 spring boot 2.5.0 이상 버전, gradle을 사용하는 사람들에게 알려주는 방법

spring boot 2.5.0버전 이상부터는 gradle로 빌드를 할때 jar파일이 2개 생성된다.

 

1. 앱이름.jar  -> bootJar Task로 생성된것

2. 앱이름-plain.jar -> build Task로 생성된것

 

첫번째 jar는 해당 프로젝트에 필요한 모든 의존성이 같이 추가된것으로 MANIFEST.MF까지 모두 정상적인 형태로 나온다.

 

하지만 plain.jar는 의존성을 제외하고 딱 프로젝트에 있는 자원들만 jar로 만든것으로 spring 관련 의존성이 빠져 MANIFEST.MF에 Main메소드의 위치가 나오지 않는다.

 

여기서 앱이름-plain.jar를 java -jar로 실행하면 no main manifest attrubute in에러가 발생한다.

 

앱이름-plain.jar를 생성하지 않기 위해서는 아래 명령어를 build.gradle에 추가해 주자

 

jar {
    enabled = false
}