본문 바로가기

Spring 3.0 - 4.3

메이븐 기초 (2) pom 파일

*** 메이븐 기초 1편 안보고 왔다면 보러가기 :-) 

https://rimkongs.tistory.com/243

 

메이븐 기초 (1) Maven이란 / Maven 설치법 / jar파일 생성하기

Maven이란? 프로젝트 빌드와 라이프 사이클, 사이트 생성 등 프로젝트 전반을 위한 관리 도구로서 많은 자바 프로젝트가 메이븐을 사용해서 프로젝트를 관리하고 있다. 그럼, Maven을 왜 사용할까?

rimkongs.tistory.com

 

 

메이븐 프로젝트를 생성하면 pom.xml 파일이 프로젝트 루트 폴더에 생성된다. 이 pom.xml 파일은 Project Object Model 정보를 담고 있는 파일이다.

 

 

 

 

 

pom.xml 의 주요 관련 태그만 살펴보자. (각자 pom.xml 파일을 열어 살펴보자)

  • <dependencies> : 이 프로젝트에서 의존하는 다른 프로젝트 정보를 기술
  • <dependency> : 의존하는 프로젝트 POM 정보를 기술
  • <packaging> : 패키지 타입 설정. jar 뿐만 아니라 웹 애플리케이션을 위한 war 타입도 존재.

 

 

  • <artifactId> : 프로젝트 식별자를 지정한다. (즉, 보통 프로젝트명을 기술)

 

 

  • 프로젝트에서 <version> 태그에 있는 버전의 spring-context 모듈을 사용한다고 설정한다. (ex. 5.0.2 RELEASE)

 

 

  • 11 버전을 기준으로 자바 소스를 컴파일하고 결과 클래스를 생성한다. 자바 컴파일러가 소스 코드를 읽을 때 사용할 인코딩은 UTF-8로 설정한다.

 

 

1. 의존 설정 <dependency>

메이븐을 사용하지 않을 경우 개발자들은 코드에서 필요로 하는 라이브러리를 각각 다운로드 받아야 한다. 

예를 들어 아파치 commons DBCP 라이브러리를 사용하기 위해서는 DBCP 뿐만 아니라 common pool 라이브러리도 다운로드 받아야 한다. 즉 코드에서 필요로 하는 라이브러리뿐만 아니라 그 라이브러리가 필요로 하는 또 다른 라이브러리도 직접 찾아서 설치해 주어야 한다.  

 

하지만 메이븐을 사용하면 코드에서 직접 사용하는 모듈에 대한 의존만 추가하면 된다. 예를 들어 commons-dbcp 모듈을 사용하고 싶다면 다음 <dependency> 코드만 추가하면 된다.

* 여기서 의존을 추가한다는 것은 일반적인 자바 어플리케이션에서 클래스패스에 commons-dbcp 모듈을 추가한다는 것을 뜻한다.

<!-- dbcp (db 커넥션 풀) -->
		<dependency>
		    <groupId>commons-dbcp</groupId>
		    <artifactId>commons-dbcp</artifactId>
		    <version>1.4</version>
		</dependency>	

 

그러면 메이븐은 commons-dbcp뿐만 아니라 commons-dbcp가 의존하는 라이브러리를 자동으로 처리해준다. 

즉 commons-dbcp 1.2.1 버전의 경우 commons-collections 2.1 버전과 commons-pool 1.2 버전 등을 함께 다운로드 받는다. 이런 식으로 반복해서 다운로드 받은 모듈이 필요로 하는 모듈을 다운로드 받고 이들 모듈을 현재 프로젝트에서 사용할 클래스패스에 추가해준다

이렇게 의존 대상이 다시 의존하는 대상까지도 의존 대상에 포함하기 때문에 이를 의존 전이라고 한다.

 

따라서 개발자는 일일이 필요한 모듈을 다운로드 받을 필요가 없다. 현재 코드가 직접 필요로 하는 모듈만 <dependency>로 추가하면 된다. 나머지 의존은 모두 메이븐이 알맞게 처리해준다. 

 

 

(1) 의존의 scope : compile, runtime, provided, test

앞의 pom.xml 파일에서 <dependency> 코드를 보면 <scope>를 포함하고 있는 것과 그렇지 않은 것이 존재한다.

<scope>는 의존하는 모듈이 언제 사용되는지를 설정한다. <scope>에는 다음 네 값이 올 수 있다.

  • compile : 컴파일할 때 필요. 테스트 및 런타임에도 클래스패스에 포함된다. <scope>를 설정하지 않을 경우 기본 값은 compile 이다.
  • runtime : 런타임에 필요. JDBC 드라이버 등이 예가 된다. 프로젝트 코드를 컴파일 할 때는 필욯아지 않지만 실행할 때 필요하다는 것을 의미한다. 배포시 포함된다.
  • provided : 컴파일 할 때 필요하지만 실제 런타임 때에는 컨테이너 같은 것에서 기본으로 제공되는 모듈임을 의미한다. 예를 들어 서블릿이나 JSP API  등이 이에 해당된다. 배포시 제외한다.
  • test : 테스트 코드를 컴파일 할 때 필요. Mock 테스트를 위한 모듈이 예이다. 테스트 시에 클래스패스에 포함된다. 배포시 제외된다.

 

 

 

(2) 메이븐 프로젝트를 보면 다음과 같은 구조를 볼 수 있다.

 

  • src/main/java 폴더 : 소스 폴더로 정의되어 있음
  • Maven Dependencies : 메이븐 의존에 설정한 아티팩트가 이클립스 프로젝트의 클래스패스에 추가됨

Maven Dependencies 에 등록된 jar 파일들은 앞서 설명한 메이븐 로컬 리포지토리에 위치한다. 실제로 이클립스는 메이븐 프로젝트를 임포트 할 때 필요한 모든 jar 파일을 로컬 리포지토리에 다운로드한 뒤 그 파일을 클래스패스에 추가한다.

 

 

 

 

 

2. 원격 repository 와 로컬 repository

위의 '1. 의존 설정'에서 pom.xml 파일에 의존 설정을 추가했지만 아직 spring-context-5.0.2.RELEASE.jar 파일을 어디서도 다운로드하지 않았다. 클래스 패스에 jar 파일을 추가하려면 파일시스템 어딘가에 이 파일이 존재해야 한다. 그럼 이 파일은 어디서 구할까? 개발자가 이 파일을 직접 다운로드 하여 어딘가에 복사해야 하나?

 

답은 원격 리포지토리와 로컬 리포지토리에 있다. 

 

메이븐은 컴파일이나 패키징 등 작업을 실행할 때 필요한 플러그인이나 pom.xml 파일의 <dependency>에 설정한 모듈을 메이븐 중앙 리포지토리에서 다운로드 받는다.

 

과정을 좀 더 자세히 보자면, 메이븐은 코드를 컴파일하거나 실행할 때 <dependency>로 설정한 artifact 파일을 사용하는데 이 artifact 파일은 다음 과정을 거쳐 구한다.

  • 메이븐 로컬 리포지토리에서 [그룹ID] \ [아티팩트ID] \ [버전] 폴더에 아티팩트ID-버전.jar 형식의 이름을 갖는 파일이 있는지 검사한다. 파일이 존재하면 이 파일을 사용한다. 
  • 로컬 리포지토리에 파일이 없으면 메이븐 원격 중앙 리포지토리로부터 해당 파일을 다운로드하여 로컬 리포지토리에 복사한 뒤 그 파일을 사용한다.

 

 

* 중앙 리포지토리 주소 http://repo1.maven.org/maven2/ 

 

원격 리포지토리에서 다운로드 받은 모듈은 로컬 리포지토리에 저장된다. 로컬 리포지토리는 [USER_HOME]/.m2/repository 폴더에 생성된다.

 

 

 

 

3. 메이븐 라이프사이클과 플러그인 실행

메이븐은 프로젝트의 빌드 라이프사이클을 제공한다. 1편 글에서 프로젝트를 생성한 뒤 컴파일 하고(mvn compile), 테스트하고(mvn test), 패키징하는(mvn package) 과정을 정해진 명령어를 이용해서 실행했다. 이때 compile, test, package는 모두 빌드 라이프사이클에 속하는 단계이다.

 

메이븐은 크게 clean, build (default), site의 세 가지 라이프사이클을 제공한다.

각 라이프사이클은 순서를 갖는 단계(phase)로 구성된다. 또한 각 단계별로 실행할 플러그인 골(goal)이 정의되어 있어서 각 단계마다 알맞은 작업을 실행한다.

 

라이프사이클의 특정 단계를 실행하려면 다음과 같이 명령어를 실행하자.

mvn test
mvn deploy -- mvn [단계이름]

 

이렇게 특정 단계를 실행하면 그 단계의 앞에 위치한 모든 단계를 실행한다. 각 단계를 실행할 때는 각 단계에 묶인 골(goal)을 실행한다.

 

 

플러그인을 직접 실행할 수도 있다.

mvn compiler:compile -- mvn [플러그인명]

단 플러그인 골을 직접 명시한 경우에는 해당 플러그인만 실행하기 때문에 라이프사이클의 단계를 실행하지는 않는다.

 

 

※ 플러그인 골(Plugin Goal)

compiler:compile 은 'compiler'라는 플러그인에서 'compile' 기능(goal)을 실행한다는 것을 뜻한다.