본문 바로가기
관리자

Project/Poppin

springboot, kotlin, gradle: no main manifest attribute 에러 intellij 프로젝트

728x90
반응형

문제

intellij로 생성한 spring-boot, kotlin, gradle 구성의 프로젝트가 build 후 jar 명령어로 실행 시 no main manifest attribute라는 에러와 함께 실행이 되지 않았다.

 

원인 및 해결

원인

빌드된 파일을 자바로 실행할 때, 자바는 MANIFEST.MF라는 파일에 있는 설정 정보를 기반으로 파일을 실행한다. 그런데 intellij에서 아무런 추가 설정이 없으면 MANIFEST.MF에 실행할 main 함수의 위치가 어딘지 적어주질 않아서 위와 같이 에러가 발생하는 것이다.

 

intellij로 프로젝트를 생성했을 때와, Spring initializer로 생성했을 때 build.gradle.kts 파일의 속성값을 하나씩 비교해보면서 무슨 차이인지 알게되었다. (PM js님 감사)

 

해결 방법

build.gradle.kts 파일에 아래 항목을 추가해준다.

plugins {
	id("org.springframework.boot") version "3.1.5" //version은 본인이 설정하기 나름
}

 

 

그리고 나서 gradle을 새로 고침해보면 더 많은 tasks가 생성되어 있는 것을 확인할 수 있을 것이다.(bootJar, bootBuildImage 등)

 

이후 clean, build를 하고 다시 실행하면 정상적으로 작동하는 것을 확인할 수 있다. 이는 빌드 시 아래 모든 tasks를 실행하는데, 여기서 bootJar task가 실행되면서 스프링부트로 실행할 수 있는 환경을 만들어주기 때문이다.

 

 

배운점, 개념

 

MANIFEST.MF와 tar -xf 명령어

위에서 설명한대로 자바가 참조하는 매니페스트 파일에 과연 어떤 값들이 적혀있는지 확인해보기 위해서 build/libs/{프로젝트명}-1.0.SNAPSHOT.jar 파일에 접근했다. 그리고 이 파일에 tar -xf {파일명} 명령어를 입력해서 압축을 풀었다. ({파일명}을 직접 기입하지 말고 TAB 키를 눌러서 접근하는게 편하다.)

리눅스의 tar 명령어는 압축 파일을 풀거나 여러 개의 파일을 압축할 때 사용하는 명령어이다.

 

그리고 cat 명령어로 MANIFEST.MF 파일을 확인하거나, intellij에서 조회해보면 속성값들을 볼 수 있다. 아래는 springboot plugin 없이 실행한 뒤 MANIFEST.MF 파일을 열었을 때와 추가 후 열었을 때의 비교 사진이다.springboot plugin의 bootJar Task에 의해서 Main-Class, Start-Class 등의 여러 속성들이 추가되고 BOOT-INF라는 디렉토리도 추가된 것을 확인할 수 있었다.

 

 

plugin과 tasks

그레이들의 tasks는 파일을 컴파일하고 문제가 없는지 테스트 하는 등의 기능을 하는 일련의 작업 조합 모음이다. 특정 라이브러리에 대한 dependency를 선언했다면, 그레이들의 tasks 실행 시 해당 라이브러리의 파일을 자바 또는 코틀린 기반으로 컴파일하고, 문제가 없는지 테스트하는 등의 작업을 하는 것이다. 이런 작업들을 일일이 gradle에 선언하는 것이 아니라 JetBrains에서 만들어놓은 Tasks로 단위별로 묶어놓은 것이다.

 

그리고 plugin은 tasks들의 집합이다. 이 중 bootJar task는 스프링부트 기반으로 실행 및 배포할 수 있도록 파일을 빠르게 패키징해주는 기능을 한다.

 

ref)

https://kotlinworld.com/323

https://blogingming.tistory.com/entry/%EC%95%84%EC%A3%BC-%EA%B0%84%EB%8B%A8%ED%95%9C-Spring-Boot-%EB%B0%B0%ED%8F%AC

 

 

 

 

 

728x90
반응형