이번 글에서는 maven의 많은 plugin 중 shade-plugin을 이용하여 'uber-jar'를 만들어 보겠다.
'uber' 라는 말은 독일어로서, 'over' 라는 뜻이 있다고 한다.
영어로 따지자면 'over-jar' 인 것이다.
'uber-jar' 라는 것은 자바 어플리케이션의 모든 패키지와 그에 의존관계에 있는 패키지 라이브러리 까지
모두 하나의 'jar'에 담겨져 있는 것을 말한다.
'uber-jar'를 사용하면 어플리케이션을 배포할 때 의존관계를 생각할 필요가 없다.
왜냐하면 이미 필요한 의존관계 라이브러리를 가지고 있기 때문이다.
이러한 'uber-jar'를 생성할 때, 해당 어플리케이션의 모든 의존관계까지 포함하다 보니
어플리케이션 배포시에 필요없는 라이브러리까지 몽땅 패키징되는 경우가 있다.
shade plugin의 강력함은 배포시에 필요한 라이브러리들을 'exclude/include' 시킬 수 있고,
라이브러리 레벨 뿐만 아니라 class 파일 레벨로도 jar 파일을 minimize 함으로서
보다 가벼운 jar파일을 생성할 수 있다는 것이다.
이제부터 shade 플러그인의 사용법을 알아보자.
아래는 기본적인 사용법이다.
메이븐 goal로 'shade:shade' 를 입력하여 직접 구동 시킬 수 있지만,
<executions> 설정으로 package phase에 shade goal을 바인딩 하는 설정을 하면
'mvn package' 로 구동 시킬 수 있다.
Resource Transformer
shade 플러그인을 적용할 때 'Resource Transformer' 라는 개념을 이해할 필요가 있다.
Resource Transformer 설정을 하면 서로 다른 artifacets 들로부터 uber-jar를 생성할 때,
classes 및 resources 파일들을 중복없이 패키징 할 수 있게 해준다.
각 Resource Transformer 설정의 종류 및 특징은 다음과 같다.
출처 : https://maven.apache.org/plugins/maven-shade-plugin/examples/resource-transformers.html
이들 중 흔히 쓰이는 몇가지 설정만 살펴보자.
1. ManifestResourcesTransformer
여기소 주로 쓰이는 것은 ManifestResourcesTransformer 인데,
설명대로 자바 'MANIFEST' 파일의 entries를 세팅해 준다.
아래와 같이 <configuration> 설정에 추가한다.
실행 가능한 jar 파일을 생성할시에 자바 어플리케이션을 구동할 MainClass를 지정해야 하는데,
이것은 'MANIFEST' 파일의 entry 중 하나이다.
위 예제처럼 <mainclass> 설정으로 해당 어플리케이션의 메인클래스를 입력한다.
2. AppendingTransformer
만약 스프링 batch 프로젝트를 shade 플러그인을 통해 'Executable Jar'(사용가능한 Jar) 파일로 패키징 한다고 하자.
그럴 경우 Main 클래스는 스프링 batch Job을 커맨드 라인에서 실행 할 수 있게해주는
'org.springframework.batch.core.launch.support.CommandLineJobRunner'가 된다.
위의 ManifestResourcesTransformer의 mainClass 설정만 해주면 될까?
그것만 해서는 안된다.
스프링으로 구성된 어플리케이션은 spring-context.xml의 namespace를 핸들링 해주는
Handler 클래스들이 정의되어 있는 spring.handlers, 스키마(xsd 등)가 정의되어 있는 spring.schemas 파일이 필요하다.
바로 이때, AppendingTransformer 설정을 사용하여 uber-jar에 포함 시킬 수 있다.
기본적으로 스프링 라이브러리 jar 파일을 까보면 각각 META-INF 밑에 spring.handlers, spring.schemas 파일이 존재한다.
앞서 설명했듯이 shade 플러그인이 모든 의존관계 라이브러리들을 한데 묶어서 uber-jar를 생성할 때,
위 2개의 파일들이 각각 스프링 라이브러리에 동일한 이름으로 존재하기 때문의 중복의 문제가 존재한다.
따라서 AppendingTransformer 설정으로 해당 파일들을 포함시키면, 마치 병합(merge)을 하는 것과 같이
각 라이브러리의 핸들러, 스키마 정보들이 각각 하나의 spring.handlers, spring.shcemas 파일로 생성되는 것이다.
나머지 ResourcesTransformer에 대해서는 공식 Document를 참고하자.
이제 shade 플러그인의 기본적인 설정은 완료되었으니, 프로젝트를 패키징 해보자.
패키징이 완료가 되면 ${project.basedir}/target에 XXX.jar 파일이 생성이 되었을 것이다.
cmd창을 열어 해당 위치로 접근한 후, java -jar XXX.jar 명령어를 실행하게 되면, jar파일이 실행될 것이다.
다음은 실행한 화면이다.
pom.xml에서 라이브러리의 의존성을 설정하는 부분에서 <scope>의 값을 system으로 설정을 하였다면,
shade plugin에서 해당 라이브러리를 include 하지 않아서
XXX.jar를 실행 시에 ClassNotFoundException 발생할 가능성이 있다.
다음 글에서는 <scope>의 값을 system로 설정하였더라도
패키징시에 해당라이브러리 까지 포함하는 Jar를 만드는 방법을 기술하겠다.
'Build Tool > Maven' 카테고리의 다른 글
[Maven] Third Party Lib 추가하는 방법 (0) | 2021.01.05 |
---|---|
[Maven] Maven Profile 활용 (0) | 2021.01.05 |
[Maven] Maven 관례따라 dynamic web project 만들기 (0) | 2021.01.05 |