[SpringBoot 2.5↑] 빌드 시 2가지 jar가 생성되는 현상 (executable jar & plain jar)
FRAMEWORK/Spring

[SpringBoot 2.5↑] 빌드 시 2가지 jar가 생성되는 현상 (executable jar & plain jar)

반응형

들어가기 전에

기존에 쓰던 springboot 2.4.11 버전을 빌드할 때에는 문제가 없었지만, springboot 2.5 버전 이후를 사용하니 빌드 시 jar가 2개 생겨 github action을 통해 진행하는 CD 프로세스가 제대로 작동하지 않았습니다.

SpringBoot 2.6.1 버전(왼쪽)과 SpringBoot 2.4.11 버전(오른쪽)

이번 포스팅에서는 빌드 시 jar가 2가지 생겼던 원인과 실제로 작동해야 할 jar만 빌드되도록 하는 방법에 대해 알아보도록 하겠습니다.

SpringBoot 2.4.11과 SpringBoot 2.5.0 차이

SpringBoot 2.4.11 Document를 보면, 하기 사진과 같이 jar or war tasks are disabled라고 적혀있습니다. 즉, 따로 설정을 변경하지 않는 한 jar task가 SKIP됩니다.

SpringBoot 2.4.11의 경우 jar 또는 war task가 default로 SKIP됩니다.

반면, SpringBoot 2.5.0 이후 버전부터는 하기 사진과 같이 Jar 또는 War task는 plain jar 또는 war를 생성하게 됩니다.

SpringBoot 2.5.0의 경우 jar 또는 war task가 default로 실행됩니다.

BootJar에 의해 생성된 jar와 Jar에 의해 생성된 jar는 무엇이 다를까?

BootJar에 의해 생성된 jar는 java -jar [ jar 파일명 ]으로 실행 시, 문제 없이 실행됩니다. 즉, BootJar에 의해 생성된 jar는 executable jar(실행 가능한 jar)입니다. 반면, Jar에 의해 생성된 jar를 java -jar [ jar 파일명 ]으로 실행시키면 하기와 같이 기본 Manifest 속성이 없다는 오류와 함께 실행되지 않습니다.

BootJar에 의해 생성된 jar와 Jar에 의해 생성된 jar 실행해보기

Jar에 의해 생성된 jar (*-plain.jar, Plain Archive)

Jar에 의해 생성된 jar는 plain archive라고 하며, 어플리케이션 실행에 필요한 모든 의존성을 포함하지 않고 소스코드의 클래스 파일과 리소스 파일만 포함합니다.

  • 의존성을 제대로 포함하고 있지 않기 때문에 java -jar 명령어로 실행이 제대로 이루어지지 않는 것입니다.

BootJar에 의해 생성된 jar (Executable Archive)

BootJar에 의해 생성된 jar는 executable archive라고 하며, 어플리케이션 실행에 필요한 모든 의존성을 함께 빌드합니다. 따라서, 해당 jar 파일은 java -jar 명령어를 통해 실행이 가능합니다.

SpringBoot 2.5.0 이후 환경에서 github action을 통해 Elastic Beanstalk에 배포 시, 오류가 안나려면 어떻게 해야할까? (cp: target 'deploy/application.jar' is not a directory 해결법)

아래 코드는 AWS Elastic Beanstalk에 배포하는 Github Action CD 로직 중 일부입니다.

      - name: Grant execute permission for gradlew
        run: chmod +x gradlew

      - name: Build with Gradle
        run: ./gradlew build -x test

...

      - name: Generate deployment package
        run: |
          mkdir -p deploy
          cp build/libs/*.jar deploy/application.jar
          cp Procfile deploy-dev/Procfile
          cp -r .ebextensions deploy-dev/.ebextensions
          cp -r .platform deploy-dev/.platform
          cd deploy-dev && zip -r deploy-dev.zip .

만약, SpringBoot 2.5.0 이상 버전을 따로 설정 변경 없이 사용한다면, 하기와 같이 cp: target 'deploy/application.jar' is not a directory라는 에러를 볼 수 있습니다.

cp: target 'deploy/application.jar' is not a directory

위 에러는 Gradle을 통한 빌드 시, BootJarJar task가 모두 실행되어 build/libs 위치에 jar가 2개 생겨 두 개의 파일을 cp하는 명령어로 사용되어 문제가 발생하는 것입니다.

Jar task를 통해 생성되는 plain archive가 필요하지 않다면, build.gradle에 하기와 같이 작성하여 Jar task를 SKIP할 수 있습니다. 이렇게 SKIP하게 되면 문제 없이 배포가 가능합니다.

jar {
    enabled = false
}

참고 자료

반응형