Apache Maven 핵심 개념과 실전 활용

Maven 개요

Apache Maven은 프로젝트 빌드, 의존성 관리, 문서 생성을 통합 관리하는 도구입니다. POM(Project Object Model) 구조를 중심으로 표준화된 디렉터리 구조와 빌드 라이프사이클을 제공하여 개발팀 간 협업을 용이하게 합니다.

핵심 설계 철학: 규약 우선

Maven은 "Convention over Configuration" 철학을 따릅니다. 개발자가 별도 설정 없이도 프로젝트를 구성할 수 있도록 합리적인 기본값을 제공합니다.

구성 요소기본 경로
소스 코드${project.basedir}/src/main/java
리소스${project.basedir}/src/main/resources
테스트 코드${project.basedir}/src/test/java
컴파일 결과${project.basedir}/target/classes
배포 아티팩트${project.basedir}/target

POM 파일 구조

pom.xml은 Maven 프로젝트의 핵심 설정 파일입니다. 다음은 기본 구조입니다:

<?xml version="1.0" encoding="UTF-8"? >
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                             http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>io.example.team</groupId>
    <artifactId>payment-service</artifactId>
    <version>2.1.0</version>
    <packaging>jar</packaging>
</project>

모든 POM은 암묵적으로 Super POM을 상속받습니다. 실제 적용되는 설정을 확인하려면 다음 명령을 실행합니다:

mvn help:effective-pom

빌드 라이프사이클

Maven은 세 가지 표준 라이프사이클을 제공합니다:

Clean 라이프사이클

  • pre-clean: 빌드 결과 삭제 전 작업
  • clean: 타 디렉터리 제거
  • post-clean: 후속 정리 작업

Default (Build) 라이프사이클

단계설명
validate프로젝트 구조 및 정보 검증
compile소스 코드 컴파일
test단위 테스트 실행
package배포 가능한 아티팩트 생성
verify품질 기준 충족 여부 확인
install로컬 저장소에 아티팩트 설치
deploy원격 저장소에 아티팩트 배포

Site 라이프사이클

프로젝트 문서와 보고서를 생성합니다. mvn site 명령으로 실행하며, Doxia 엔진을 통해 XDoc, XHTML 등 다양한 형식을 처리합니다.

프로파일(Profile) 활용

프로파일은 빌드 환경별 설정 분리를 가능하게 합니다. 다음은 경별 데이터베이스 설정 예시입니다:

<profiles>
    <profile>
        <id>dev</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <properties>
            <db.url>jdbc:h2:mem:testdb</db.url>
        </properties>
    </profile>
    <profile>
        <id>prod</id>
        <properties>
            <db.url>jdbc:postgresql://db.example.com:5432/prod</db.url>
        </properties>
    </profile>
</profiles>

프로파일 활성화 방법:

# 명시적 활성화
mvn package -Pprod

# 환경 변수 기반 활성화
mvn package -Denv=prod

# settings.xml에서 기본 활성화
<activeProfiles>
    <activeProfile>dev</activeProfile>
</activeProfiles>

저장소 체계

유형위치/특성
Local개발 머신의 ~/.m2/repository
CentralMaven 커뮤니티 관리, https://repo.maven.apache.org
Remote조직 내부 또는 제3자 저장소 (Nexus, Artifactory 등)

의존성 검색 순서: Local → Central → Remote 순으로 탐색하며, 미처지 못한 의존성은 상위 저장소에서 다운로드받습니다.

SNAPSHOT 버전 관리

개발 중인 모듈 간 연동 시 SNAPSHOT 접미사를 사용하면 매 빌드마다 최신 버전을 자동으로 가져옵니다:

<dependency>
    <groupId>io.example.team</groupId>
    <artifactId>order-api</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

강제 최신 다운로드를 위해서는 -U 플래그를 사용합니다: mvn clean package -U

외부 의존성 처리

중앙 저장소에 없는 JAR 파일은 system 범위로 지정합니다:

<dependency>
    <groupId>com.legacy.lib</groupId>
    <artifactId>proprietary-sdk</artifactId>
    <version>3.5</version>
    <scope>system</scope>
    <systemPath>${project.basedir}/lib/proprietary-sdk-3.5.jar</systemPath>
</dependency>

Web 애플리케이션 빌드

웹 프로젝트 생성 명령:

mvn archetype:generate \
    -DgroupId=io.example.portal \
    -DartifactId=customer-portal \
    -DarchetypeArtifactId=maven-archetype-webapp \
    -DinteractiveMode=false

생성된 구조:

  • src/main/webapp/ - JSP, HTML, 정적 리소스
  • src/main/webapp/WEB-INF/web.xml - 배포 서술자
  • src/main/resources/ - 설정 파일

빌드 및 실행:

mvn clean package
# target/customer-portal.war 생성됨

의존성 전이 및 충돌 해결

Maven은 직접 선언하지 않은 전이 의존성도 자동으로 처리합니다. 충돌 발생 시 "가까운 거리의 첫 번째 선언" 원칙이 적용됩니다.

<!-- 전이 의존성 제외 -->
<dependency>
    <groupId>io.example.framework</groupId>
    <artifactId>web-framework</artifactId>
    <version>2.0</version>
    <exclusions>
        <exclusion>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<!-- 선택적 의존성 선언 -->
<dependency>
    <groupId>io.example.util</groupId>
    <artifactId>advanced-cache</artifactId>
    <version>1.2</version>
    <optional>true</optional>
</dependency>

릴리스 자동화

maven-release-plugin을 활용한 배포 파이프라인:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-release-plugin</artifactId>
    <version>3.0.0</version>
    <configuration>
        <tagBase>https://svn.example.com/tags</tagBase>
        <releaseProfiles>production</releaseProfiles>
    </configuration>
</plugin>

릴리스 수행 절차:

# 1. 준비 (버전 확정, 태그 생성)
mvn release:prepare

# 2. 배포 (저장소 업로드)
mvn release:perform

# 문제 발생 시 롤백
mvn release:rollback

다중 모듈 프로젝트 구성

대규모 시스템은 모듈화하여 관리합니다:

<!-- 부모 POM -->
<groupId>io.example.platform</groupId>
<artifactId>platform-parent</artifactId>
<version>4.0.0</version>
<packaging>pom</packaging>

<modules>
    <module>core-domain</module>
    <module>api-gateway</module>
    <module>notification-service</module>
    <module>reporting-engine</module>
</modules>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>io.example.platform</groupId>
            <artifactId>core-domain</artifactId>
            <version>${project.version}</version>
        </dependency>
    </dependencies>
</dependencyManagement>

모듈 빌드 시 부모 디렉터리에서 일괄 실행:

mvn clean install -pl api-gateway -am
# -pl: 특정 모듈 지정
# -am: 해당 모듈의 의존 모듈 함께 빌드

태그: maven POM Build Lifecycle Dependency Management Java Build Tool

6월 6일 19:13에 게시됨