POM
Maven은 두 개의 주요 개념에 기반하여 프로젝트를 관리하고 있습니다. 하나는 "Object" 또 하나는 "Tasks" 입니다. Object는 프로젝트 자체를 하나의 개체로 보겠다는 것이고 이 개념이 Ant에는 없고 단지 Task만 있습니다. Task는 Maven 용어 정리에서 살펴봤었던 Goal이나 Action 또는 Verb(Phase와 같은 뜻으로 사용하는 듯)입니다.
오늘은 위의 두 개념중에 첫 번째인 Object(프로젝트 자체를 나타내는 개체)에 대해 살펴봅니다. POM은 다음 그림과 같이 프로젝트와 관련된 모든 정보를 담고 있습니다. 프로젝트 하나 당 POM 파일 하나가 존재합니다.
물론 Maven에서는 프로젝트와 관련된 정보 외에도 추가로 필요한 정보(빌드 서버의 인증 정보와 같은)가 있기 때문에 settings.xml 이라는 파일도 존재합니다. 하지만 일단은 POM만 집중해서 살펴보겠습니다.
다음은 참조 문서에 있는 예제 POM 파일입니다.
<modelVersion>4.0.0</modelVersion>
<groupId>com.training.killerapp</groupId>
<artifactId>killerapp</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<name>Killer App Stores</name>
<packaging>pom</packaging>
<dependency>
<groupId>com.training.killerapp</groupId>
<artifactId>killerapp-api</artifactId>
</dependency>
</dependencies>
<module>killerapp-store-memory</module>
<module>killerapp-store-xstream</module>
</modules>
</project>
크게 두 부분, 세밀하게는 네 부분으로 나누어 살펴볼 수 있습니다.
1. General Project Information
위 예제에서 분홍색 부분에 해당합니다.
이 부분은 이 전에 간단하게 살펴본 적이 있는 것 같습니다. 이 부분에 있는 정보들 중에 groupId, artifactId, packaging, version 네 개를 조합하여 프로젝트 식별자로 사용합니다. 그런데 위의 예제는 groupId와 version이 명시되어 있지 않습니다. 명시하지 않으면, 부모 POM의 version과 groupId를 사용합니다.
상속받을 수 있는 정보들은 다음과 같습니다.
- 종속성 dependencies
- 개발자과 기여자 developers and contributors
- 플러그인 목록 plugin lists
- 리포트 목록 reports lists
- 플러그인 실행 plugin executions with matching ids
- 플러그인 설정 plugin configuration
버전
버전의 다음의 순서대로 표시합니다.
major.minor.bug_fix-qualifier-build_number
스냅샷 snapshot
버전 뒤에 붙여주는 이 표시는 현재 개발중이라는 표시입니다.
예) 1.3.5-alpha-1-SNAPSHOT
2. Project Relationships
SuperPOM
SuperPOM은 모든 프로젝트에서 공통으로 사용하는 정보를 모아 둡니다. 예를들어 빌드 정보와 같은 것을 다음과 같이 담아 두고 모든 프로젝트에서 이 POM을 상속하여 사용하도록 할 수 있습니다.
<!-- where compiled files are placed -->
<outputDirectory>target/classes</outputDirectory>
<!-- The name of the final artifact sans extension (or possible classifiers) -->
<finalName>${artifactId}-${version}</finalName>
<!-- where compiled test files are placed -->
<testOutputDirectory>target/test-classes</testOutputDirectory>
<!-- Where the Java source files are expected to be -->
<sourceDirectory>src/main/java</sourceDirectory>
<!-- Where non-Java script source files are expected to be -->
<scriptSourceDirectory>src/main/scripts</scriptSourceDirectory>
<!-- Where the test Java source files are expected to be -->
<testSourceDirectory>src/test/java</testSourceDirectory>
<resources>
<resource>
<!-- Where non-compiled files reside (such as .properties file). They are put into the outputDirectory -->
<directory>src/main/resources</directory>
</resource>
</resources>
<testResources>
<testResource>
<!-- Where non-compiled files reside. They are put into the testOutputDirectory -->
<directory>src/test/resources</directory>
</testResource>
</testResources>
</build>
...
</project>
종속성 관리 엘리먼트
위 예제에는 없지만, <dependencyManagement> 라는 엘리먼트를 사용하며, 하위 프로젝트들이 종속성을 가지는 프로젝트들에 대한 정보를 미리 기술해 둘 수 있습니다. 그러면, 하위 프로젝트에서는 종속성을 가지는 프로젝트의 groupId와 artifactId만 명시해두면됩니다. version 정보는 SuperPOM의 저 엘리먼트를 참조하여 원하는 프로젝트를 참조하게 됩니다.
종속성
프로제트 간의 관계를 관리할 수 있습니다. 종속성은 해당 프로젝트가 어떤 기능을 수행하기 위해서 필요로 하는 프로젝트들을 나타냅니다. <dependencies> 엘리먼트를 사용하여 나타내며, JUnit을 사용한다면 다음과 같이 나타낼 수 있습니다.
종속성을 나타낼 때 scope을 명시할 수 있는데, 컴파일 할 때만 사용할지, 테스트 할 때만 사용할지 등을 나타냅니다. scope에는 다음의 값들을 사용할 수 있습니다.
compile
provided
runtime
test
system
멀티 모듈
<modules> 엘리먼트안에 여러 개의 <module> 엘리먼트를 사용하여 나타내며, POM 파일에 이 엘리먼트를 가지고 있는 프로젝트는 멀티 모듈 프로젝트라고 합니다. 이 프로젝트는 자신을 빌드하는 것이 아니라, 여러 개의 다른 프로젝트들을 빌드합니다. 따라서 이 프로젝트의 packaging 타입은 pom으로 설정합니다.