Maven의 내부
Source: Dev.to
소개
오늘 나는 소중한 시간을 두 시간이나 잃었습니다. 그렇습니다. 그리고 모두 Maven이 제 생각엔 특이하기 때문입니다.
이 모든 것은 제 부수 프로젝트 중 하나인 frover (GitHub)와 관련이 있습니다. Java로 만든 파일 탐색기입니다. 제가 Java를 좋아하는 이유 중 하나는 배포가 매우, 매우 간단하다는 점입니다: JAR 파일로만 만들면 됩니다 (more info).
앱을 빌드 시스템으로 Maven을 사용하는 이유는 무엇일까요? 음, 하나의 선택지일 뿐입니다. Gradle은 Android 경험상 매우 번거롭게 느껴졌고, Ant는 좋은 빌드 시스템이며 잘 동작하지만 오래된 혹은 레거시 프로젝트에만 쓰이는 듯했습니다. 그래서 Maven이 가장 좋은 선택처럼 보였습니다.
Maven은 커맨드 라인 도구 mvn과 프로젝트 요구사항을 기술하는 pom.xml 파일을 통해 사용됩니다.
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.devbaltasarq</groupId>
<artifactId>frover</artifactId>
<version>1</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>25</maven.compiler.source>
<exec.mainClass>com.devbaltasarq.frover.Ppal</exec.mainClass>
</properties>
<name>frover</name>
<description>A simple file manager.</description>
</project>
매니페스트 문제
애플리케이션을 만들기 시작하고 NetBeans(예시)에서 실행합니다. 모든 것이 정상적으로 동작하므로 dogfooding을 해보기로 합니다. 하지만 JAR이 실행되지 않습니다. 커맨드 라인에서:
$ mvn package
$ java -jar target/frover-1.0.jar
no main manifest attribute, in frover-1.0.jar
JAR은 META-INF 디렉터리 안에 MANIFEST.MF 라는 특별한 텍스트 파일이 필요합니다. 최소한의 내용은 다음과 같아야 합니다:
Manifest-Version: 1.0
Main-Class: com.devbaltasarq.frover.Ppal
JAR은 본질적으로 zip 파일입니다. 이를 확인하면:
$ unzip -v target/frover-1.0.jar
Archive: target/frover-1.0.jar
...
$ unzip -v target/frover-1.0.jar | grep -i manifest
MANIFEST.MF가 나타나지 않습니다. pom.xml에 이미 메인 클래스 정보(properties.exec.mainClass)가 포함되어 있음에도 Maven은 자동으로 매니페스트를 생성하지 않습니다.
maven-jar-plugin 플러그인 추가
Maven이 매니페스트를 포함하도록 하려면 pom.xml에 maven-jar-plugin 플러그인을 추가해야 합니다:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.4.2</version>
<configuration>
<archive>
<addMavenDescriptor>true</addMavenDescriptor>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
<mainClass>${exec.mainClass}</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
이 설정으로 Maven은 MANIFEST.MF를 생성하고, 결과 JAR이 정상적으로 동작합니다.
전체 pom.xml
아래는 플러그인이 설정된 전체 pom.xml 예시입니다:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.devbaltasarq</groupId>
<artifactId>frover</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>25</maven.compiler.source>
<exec.mainClass>com.devbaltasarq.frover.Ppal</exec.mainClass>
</properties>
<name>frover</name>
<description>A simple file manager.</description>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.4.2</version>
<configuration>
<archive>
<addMavenDescriptor>true</addMavenDescriptor>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
<mainClass>${exec.mainClass}</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
결론
maven-jar-plugin을 설정하면 JAR에 매니페스트가 포함되어 문제 없이 실행됩니다. 모든 XML을 추가해야 하는 것이 다소 번거롭긴 하지만, Maven을 사용하면 의존성을 쉽게 관리할 수 있습니다(예: Google의 Gson 라이브러리 등을 같은 pom.xml에 추가). 개발은 계속 진행 중이며, 곧 애플리케이션용 JSON 설정 파일이 추가될 예정입니다.