Maven project의 핵심이라고 하면 당연히 pom.xml이라고 말할 수 있다.
해당 프로젝트에 import 되는 jar파일 정보 및 버전정보를 담고 있으며 최종적으로 패키징되는 기준값을 담고 있기 때문에 해당 파일만 잘 설정해줘도 프로젝트 실행과 배포를 위한 설정이 다 된거라고 볼 수 있다.
그럼 기본적인 구조에 대해서 확인하고 어떤 용도로 사용되는지 정리해보자.
Maven project 제대로 사용하기 : pom.xml
pom.xml은 기본적으로 최초 생성되는 기본구문 (필수구문) 과 추가적인 설정으로 생성되는 부분으로 나눠질 수 있다. 다시 말해 기본구문을 기반으로 각 프로젝트 별로 원하는 내용을 추가/보완하여 커스터마이징 할 수 있다.
<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/maven-v4_0_0.xsd">
<!-- 필수사항 : 프로젝트 정보 기재 부분 -->
<modelVersion>4.0.0</modelVersion>
<groupId>ojava.blog</groupId>
<artifactId>mavendemo</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>mavendemo Maven Webapp</name>
<url>http://maven.apache.org</url>
<!-- 선택사항 : 해당 프로젝트에 대한 설명 -->
<description>demo project for blog</description>
<!-- 선택사항 : pom.xml에서 공통적으로 사용할 버전 또는 설정값 정보 -->
<properties>
<!-- 각 Dependency에 지정해줘도 되나 상단에 써두어서 알아보기 쉽게하려는 의도가 더 많음 -->
<!-- build properties -->
<jdk.source>1.11</jdk.source>
<jdk.target>1.11</jdk.target>
<!-- JSTL / JSP -->
<jstl.version>1.2</jstl.version>
<jsp.version>2.3.0</jsp.version>
<servlet.version>3.0.1</servlet.version>
<!-- 위 내용처럼 tag명을 원하는 대로 지정하고 값을 주는 방식으로 자유롭게 사용 가능 -->
</properties>
<!-- 필수내용 : 프로젝트에 import 되는 dependency 목록 -->
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<!-- 상단에 선언했던 properties에 기재한 내용을 이렇게 사용함 -->
<version>${servlet.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>${jsp.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>2.2.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- 기타 등등... 각 프로젝트에 맞는 내용을 추가하면 된다. -->
</dependencies>
<!-- 필수내용 : 프로젝트 build 정보 -->
<build>
<!-- 선택사항 : resource 정보 기재 -->
<resources>
<resource>
<directory>src/main/webapp</directory>
</resource>
</resources>
<!-- 선택사항 : maven 관련 plugin 정보 기재 -->
<plugins>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
<configuration>
<includes>
<include>${basedir}/src/main/webapp/**</include>
</includes>
</configuration>
</plugin>
<!-- 상단 내용 외 원하는 plugin 관련 내용을 기재하면 된다. -->
</plugins>
</build>
<!-- 선택사항 : repository 별도 설정 -->
<distributionManagement>
<repository>
<id>nexus</id>
<name>nexus-release</name>
<url>${nexus.uri}/content/repository/release</url>
</repository>
<!-- 목적에 따라 release, snapshots, 3rd party 등 나눠서 등록할 수 있다 -->
</distributionManagement>
<!-- 선택사항 : 검증/운영 배포 정보를 구분할 수 있는 설정 profiles -->
<profiles>
<profile>
<id>test</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<finalName>${project.artifactId}-${project.version}</finalName>
<directory>${project.basedir}/target</directory>
<resources>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
</resource>
<resource>
<directory>${project.basedir}/src/main/setting/test</directory>
</resource>
</resources>
</build>
</profile>
<profile>
<id>product</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<finalName>${project.artifactId}-${project.version}</finalName>
<directory>${project.basedir}/target</directory>
<resources>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
</resource>
<resource>
<directory>${project.basedir}/src/main/setting/product</directory>
</resource>
</resources>
</build>
</profile>
</profiles>
</project>
Artifact (필수사항, project tag 하단 프로젝트 필수 정보 부분)
Overview 탭에서 뜨는 부분으로 프로젝트 생성하면 생기는 필수 정보.
프로젝트의 기본적인 정보를 담고 있으며, 배포방식 및 배포정보 등도 담고 있음
properties (선택사항)
pom.xml 내에서 자주 사용되는 정보를 변수처럼 만들어서 사용할 수 있음
같은 내용을 여러번 쓰는 경우에도 이렇게 사용할 수 있지만, 프로젝트 설정의 중요한 사항에 대해 위에 따로 정의하여 보기 쉽게 정리하려는 목적도 있다.
dependencies (필수사항)
pom.xml의 핵심이라고 볼 수 있는 의존성을 정의하는 부분으로. 라이브러리를 불러오는 부분이다.
maven을 통해 불러온 라이브러리들은 Java Build Path에서 Maven Dependencies 하위 목록으로 들어가며 별도 설정이 불가하고 pom.xml을 통해서만 추가/삭제/버전 변경 등이 가능하다.
해당 경로에 추가된 라이브러리가 필요한 다른 라이브러리들이 있다면 (의존적인 라이브러리) 해당 라이브러리까지 참조해서 불러들이는 놀라운 기능이 있다. 해당 기능을 '의존성 전의'라고 한다.
maven 공식 홈페이지를 통해 각 하위 필드별 설명을 찾아왔다.
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<type>jar</type>
<scope>test</scope>
<optional>true</optional>
</dependency>
groupId, artifactId : 의존성 라이브러리에 추가하기 위한 필수값
version : 동일한 artifact를 가진 라이브러리가 여러개 존재하는데 그 중 어떤 버전을 가져올 것인지 설정
type : 해당 프로젝트로 불러들일 의존성 라이브러리의 유형. 기본값은 jar이다.
설정 안하면 jar 파일로 불러들이고, 다른 유형도 존재한다. (ejb-client, test-jar 등)
scope : 해당 라이브러리가 적용될 범위를 지정할 수 있음. 사용 가능한 범위는 총 5개다.
- compile (default) : 아무것도 지정되지 않았을 경우 설정되는 기본 설정값.
이 값으로 설정하는 경우 모든 클래스 경로에서 사용할 수 있고, 컴파일 및 배포 시 같이 제공된다.
해당 프로젝트에 종속된 다른 프로젝트에도 적용될 수 있다. - provided : compile과 유사하나, JDK 혹은 컨테이너가 런타임 시에만 해당 라이브러리를 제공한다.
컴파일 혹은 테스트 경로에서만 사용할 수 있으며, 배포 시에는 빠진다. - runtime : 컴파일 시에는 사용되지 않고, 실행될 때만 사용된다.
런타임과 테스트 경로에서는 있지만, 컴파일 클래스 경로에는 존재하지 않는다. - test : 해당 scope를 사용하는 경우는, 테스트 시에만 해당 라이브러리를 사용한다는 의미이다.
응용 프로그램의 정상적인 사용 시에는 필요 없다는 의미로 테스트 컴파일과 실행 단계에서만 사용하며, 종속된 다른 프로젝트에는 영향을 미치지 않는다. - system : provided와 유사하나, 저장소에서 관리되지 않고 직접 관리하는 JAR를 추가한다.
해당 범위에 있는 라이브러리는 artifact 단위에서는 항상 사용할 수 있으나 repository에 존재하지 않는다.
해당 범위를 사용하는 경우에는 dependency 설정에 systemPath를 추가해서 작성해야 한다.
(어느 경로에 JAR 파일을 둬야 하는지 지정해줘야 함, ${java.home}/lib 등과 같이 기술)
optional : 이 프로젝트가 다른 프로젝트에 의존성을 가진 경우에 사용할지 여부를 선택해준다.
헷갈릴 수 있는 개념인데, A라는 프로젝트에서 B 프로젝트를 참조하여 사용한다고 했을 때 B에서 의존성으로 포함한 dependency의 optional을 true로 주면, A 프로젝트에서는 해당 라이브러리를 참조하지 않는다.
쉽게 말해서, 의존성 정보를 다른 프로젝트에 전달하고 싶지 않을 때 optional을 true로 설정하자.
추가하고자 하는 의존성 라이브러리가 있다면, https://mvnrepository.com/ 해당 사이트를 통해서 원하는 library를 검색해서 maven에 추가하면 된다.
버전별로 아주 친절하게 pom.xml에 붙여넣으면 되는 구조로 제공한다.
build (필수사항)
빌드할 때 사용할 플러그인 목록을 기록한다.
distributionManagement (선택사항)
artifact가 배포될 repository 정보와 설정
대체적으로 가상화 등 망분리 환경에서 외부 인터넷 연결이 불가할 때나 내부용 repository를 별도로 두어 사용하고자 할 때 쓴다.
대표적으로 많이 사용되는 내용은 Nexus (http://www.sonatype.org/nexus/) 이고, 목적에 따라 repository를 나누어 등록할 수 있다. release, snapshots, 3rd party 등.
profiles (선택사항)
여러 개의 profile을 가질 수 있고, 각각 다른 설정파일과 개발 환경을 구축할 때 사용한다.
주로 로컬, 개발서버, 운영서버를 나누어 배포하여야 하는 설정 등이 존재할텐데 이를 각각 profile로 등록해서 배포 시 마다 profile 값만 변경해주면서 패키징하게 되면 설정파일 및 개발환경들이 세팅한 대로 묶여진다.
maven의 package 명령어를 통해 war 등으로 묶을 때 profile에 기술한 id를 함께 작성하면, 설정한 방식으로 빌드하여 배포가 가능하다.
mvn clean package -P test
위의 명령어처럼 -P를 불인 뒤에 원하는 profile id를 써주자. (-P를 안쓰면 기본값으로 패키징을 한다.)
블로그 포스팅을 위해서 찾아보다보니, maven profile의 경우는 각 환경마다 빌드를 새로 해야하는 문제가 있으니 해당 설정을 이용해서 별도 배포하는 것보다는 spring에서 제공하는 spring profile을 권장하는 듯 하다.
maven이 의존성 라이브러리 (dependency) 만 정의하는 용도로 생각했었는데.. 역시 잘 알아보고 그 기능을 잘 활용해야 한다고 느낀다.
maven profile을 정리하려다가 너무 멀리왔는데... 다음에는 spring profile에 대해서 정리해볼까 한다.
더 상세한 내용은 maven 공식 홈페이지를 확인하시길!
https://maven.apache.org/pom.html
'PROGRAM > JAVA / JSP' 카테고리의 다른 글
도로명 주소 API 연동방식, 외부 API 연동 시 유의사항 (0) | 2020.12.14 |
---|---|
for 반복문 중첩 빠져나오기 - break label (0) | 2020.04.13 |
QR코드 생성방식 (Google Chart API 대체) (0) | 2019.03.19 |
String에서 PDF로 변환하기 / STRING (or XSTRING) TO PDF (0) | 2018.12.14 |
lombok @Data not working / getter setter 인식 불가 해결 (2) | 2018.12.03 |