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
}
'etc' 카테고리의 다른 글
linux 명령어 모음 (0) | 2021.06.12 |
---|---|
CORS (0) | 2021.03.14 |
도커 푸시 (0) | 2021.01.18 |
메이븐 Using 'UTF-8' encoding to copy filtered resources. [INFO] Using 'UTF-8' encoding to copy filtered properties files.에러 해결 (0) | 2021.01.14 |
웹서버 VS WAS (0) | 2020.09.05 |