///
Search
🥑

Maven 알고 쓰자!

태그
빌드툴
maven plugin 만들어 보기
maven plugin 으로 파일 생성해서 테스트에서 사용하기 (실제로 사용 가능 할지는 의문이지만)
상위의 메이븐은 예~~~전에 내가 메이븐을 하나도 모를 때 알려고 정리했다. 근데 아직도 아리송해서 다시 한번 봐보자! 기존에 maven 정리 같은 경우 사용법이나 뭔가 좀 친해질려는 경향으로 공부를 했었다. 근데 maven을 사용할 때 다양하게 커스텀도 하고 문서를 보고 내가 몇가지를 실험해보고 싶었다. 그래서 개념적인 부분이 약하다는 걸 알고 개념적인 부분을 정리해보자 예전에 공부할때는 정말 사용하려고 공부를 했구나 라는 생각을 하게된다. ㅠ.ㅠ

Maven 이란?

Maven은 빌드 자동화 툴이다. 자동화 빌드툴? 간단하게 말하자면 내가 pom.xml에 정의한 라이브러리를 자동으로 다운 받고 해당 라이브러리가 의존하는 다른 라이브러리까지 관리하여 자동으로 다운 받아준다. 아래와 같은 pom.xml을 통하여 관리한다.

Maven의 기본 개념과 개념들 간의 연관 관계

아래의 과정과 함께 보며 이해해보자.
Lifecycle(붉은색) : Phase들의 순서가 있는 집합이다. 기본적으로 default, clean, site 가 있으며 각각의 Lifecycle은 고유의 빌드 순서(phase들의 실행 순서)가 있다. 또 하나 중요한 점은 Lifecycle상에서 임의의 phase만 실행은 불가능하다. 모든 phase를 순서대로 실행해야 실행된다.
Phase(초록색) : complie, test, package, clean...(엄청 많다)이다. 최소 수행 단위를 의미하며 수행은 phase가 하는 것이 아닌 plug-in과 연결된 goal이 수행한다.
Goal(노랑색) : goalplug-in의 단위 기능이다. 아까 언급했듯 phase는 “plugin:goal”로 지정된다. 즉, phase를 실행한다는 것은 phase에 지정된 plug-in의 특정 goal을 실행하는 것이다.
plug-in(주황색) : 위에서 언급한 것처럼 goal을 실행하기 위한 하나의 통로라고 생각하면 좋다. 기본적으로 maven은 plug-in에서 동작하며 plug-in은 여러 단위 기능(goal)을 가지고 있다.
알아두면 좋은 것
phase 없는 goal도 있을까? 있다. 즉 아까의 말처럼 phase = plugin:goal 이라고 했다. 이름이 없는 경우도 존재한다고 생각하면 된다. 그럼 직접 실행할 수 있다.
반대로 goal없는 phase도 있을까? 있다. 이를 제공하는 이유는 커스텀하게 연결하여 사용하는 목적도 있다.

Maven 의존성 관리

Maven을 사용하다 보면 pom.xmldependency를 정의하면 자동으로 의존성을 주입할 수 있다. 메이븐이 repository에서 검색해서 자동으로 의존성을 추가해준다. 의존성이 참조하고 있는 부가적인 의존성까지 추가해준다. 여기에는 몇가지의 개념이 존재한다.
Dependency mediation : 의존성이 여러 버전이 발견될 때 어떤 버전의 아티팩트가 선택될지 결정한다. Maven은 가장 가까운 정의를 선택한다. 즉, 디렉토리의 동일 깊이에 있는 경우 가장 상단에 정의된 첫번째 선언을 선택한다.
Dependency management : 버전이 지정 되지 않은 의존성에서 발생할 때, 아티팩트의 버전을 직접 지정할 수 있다.
Dependency scope : 빌드의 현재 단계에 적합한 의존성만 포함할 수 있다. 의존성이 클래스 경로에 포함되는 시기를 결정하는데 사용된다.
compile : 기본 범위, 모든 클래스 경로에서 사용할 수 있다.
provided : 컴파일과 비슷하지만 실행 시 컴파일과 테스트 경로에만 유효하고 런타임시에는 유효하지 않다. 예를 들면 x → y에 대한 의존성을 가지고 있고 x의 내부에서 y는 provider로 설정되어 있다. 그렇다면 z → x의 관계라면 z 는 y에 대한 의존성을 가질 것 같지만 provider때문에 그렇지 않다. z 와 y 가의존성을 가지는 시점은 테스트와 컴파일 시점 뿐이다.
runtime : 컴파일에 의존성이 필요하지 않고 런타임에 필요함을 나타낸다. 컴파일을 제외한 테스트, 런타임에는 의존성을 가진다.
test : 테스트 컴파일 및 실행 단계에서만 사용할 수 있음을 나타낸다. junit이나 mockito에서 많이 봤을거다.
system : 명시적으로 포함된 jar을 제공해야 한다는 점을 제외하고 provider의 범위와 유사하다. 내부에 jar의 위치를 지정하는 systempath속성이 붙어야한다.
import : <dependencyManagement> 태그 내에 있는 의존성 목록으로 의존성을 대체한다.
Excluded dependencies : exclusion을 사용하여 의존성을 명시적으로 제외할 수 있다.
Optional dependencies : x → y → z 순으로 의존성이 주입될 때 y → z 는 optional 요소를 사용하여 z를 선택적으로 표시할 수 있다. 그렇다면 x → y 에만 의존성을 가지며 x는 선택에 따라 z를 명시적으로 표시할 수 있다.

Maven 설정파일 settings.xml

settings.xml 이 파일을 이용하여 라이브러리, 플러그인을 중앙 저장소에서 로컬 저장소로 설정할 수 있다. 프로젝트가 아니라 사용자가 속성에 대한 자체 기본값을 설정해야 하는 경우 좀 유용하게 사용할 수 있다. .m2 디렉토리에 settings.xml에 정의할 수 있다. 없으면 만들면 된다. 또한 여러 설정도 겸할 수 있다. 크게 아래와 같다.
단순 값
플러그인 그룹
서버
프록시
미러
프로필
속성

Maven 설정파일 POM.xml

pom.xml 은 Project Object Model의 줄임말로 프로젝트 root에 존재하는 파일이다. pom에서는 속성값을 사용하여 참조할 수 있다.
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> 속성값 사용 </dependency> </dependencies>
XML
복사

POM의 기본 값

POM에서는 프로젝트를 설명하고 종속성을 관리하며 maven이 프로젝트를 빌드할 수 있게 도움이 되는 구성 세부 정보를 선언한다. 또한 pomjavaobject처럼 슈퍼 pom을 확장한다. 슈퍼 pom의 경우 모든 기본 구성을 정의한다. 가장 단순한 형태의 pom 파일도 슈퍼 pom 파일에 정의된 모든 구성을 상속한다.

이쯤 되니 궁금한 주제

plugin이랑 dependency랑 별반 차이 없는데? 뭘까? 필자가 느낀점 입니다. 당연히 실행되고 남는 위치는 다르다는 걸 알지만 그 외에 동일한데 뭐가 다를까? 라는게 더 정확할 것 같다. 둘 다 jar 파일이다. 그러나 대부분의 작업은 플러그인을 사용하여 수행되고, 종속성은 작업을 실행하는 동안 클래스 경로에 추가되는 jar파일일 뿐이라는 답변이 있었다. 필자가 읽어보고 내린 결론은 plugin의 경우 실행이 된다. 하지만 dependency의 경우 실행이 된 어떤 곳에 class파일을 제공할 뿐 그 이상이 아니다.