Maven Chapter4 Page 1 Table of Contents Table of Contents... 1 Revision History... 2 1. 내가꿈꾸는개발환경... 3 2. 메이븐설치및템플릿프로젝트생성... 3 3. 메이븐설정파일... 3 4. 메이븐라이프사이클 lifecycle... 3 4.1 메이븐의라이프사이클과페이즈... 4 4.2 메이븐페이즈와플러그인... 7 4.3 메이븐기본페이즈와플러그인...13 5. 메이븐을이용한의존라이브러리관리... 23 6. 메이븐과이클립스통합... 23 7. 메이븐과데이터베이스통합... 23 8. 메이븐프로파일, 배포... 23 9. 리포팅기능을활용한문서관리... 23 10. 메이븐모듈 module... 23 11. 메이븐사내저장소설치및활용... 23 12. 표준 POM 파일생성및리팩토링... 23 13. 메이븐아키타입 archetype... 23 14. 새로운프로젝트를시작하면서..... 24
Maven Chapter4 Page 2 Revision History Name Date Reason For Changes Version
Maven Chapter4 Page 3 1. 내가꿈꾸는개발환경 2. 메이븐설치및템플릿프로젝트생성 3. 메이븐설정파일 4. 메이븐라이프사이클 lifecycle 프로젝트시작 3 일째 ( 소제목 ) 위키북프로젝트의뼈대는만들었는데빌드는어떤방식으로진행되는것인지이해가되지않는다. 앤트빌드툴에서는설정파일을보면빌드가어떻게진행되는지, 각빌드간의의존관계는어떠한지명확하게알수있었는데메이븐은어느곳을찾아봐도알수없다. 그리고 mvn help:effective-pom 을실행하여최상위 POM 설정내용을확인했는데많은부분을차지하고있는플러그인 (<plugin/>) 설정에대해서도잘모르겠다. 지금까지실행한빌드는 2 장에서따라하기식으로학습했던메이븐 Getting Started 문서 1 를참고해서빌드를할수있었다. 이문서에서제공하는데로빌드를했지빌드가어떤방식으로진행되는지이해하기는힘들었다. Getting Started 문서를보면메이븐은빌드라이프사이클을가지며, 라이프사이클의각단계를페이즈 phase 라고부른다는것을알수있다. 메이븐의라이프사이클은순서가정해져있으며, 순차적으로페이즈를실행하는것이다. 라는것까지이해할수있겠다. 암튼메이븐은알듯하다가도모를존재이다. 오늘은빌드과정에대하여집중적으로살펴봐야겠다. 개인적인느낌이지만오늘학습할내용이메이븐의핵심내용이지않을까? 하는생각을하면서하루를 시작한다. 1 http://maven.apache.org/guides/getting-started/maven-in-five-minutes.html
Maven Chapter4 Page 4 4.1 메이븐의라이프사이클과페이즈 앤트는애플리케이션을빌드하기위한단위로타겟 target 을사용한다. 앤트는프로젝트를생성할때마다 타겟을만들고, 각타겟의빌드순서를개발자가임의적으로정의할수있다. 프로젝트를앤트빌드툴 기반으로빌드하는스크립트를보면다음과같다. <project name="myproject" default="dist" basedir="."> <property name="src" location="src"/> <property name="build" location="build"/> <property name="dist" location="dist"/> <target name="init"> <mkdir dir="${build}"/> </target> <target name="compile" depends="init"> <javac srcdir="${src}" destdir="${build}"/> </target> <target name="dist" depends="compile"> <mkdir dir="${dist}/lib"/> <jar jarfile="${dist}/lib/myproject-${dstamp}.jar" basedir="${build}"/> </target> </project> 예제 4-1 앤트빌드스크립트예제 예제 4-1 의앤트빌드스크립트를보면 <target/> 엘리먼트단위로빌드가가능하며, 각 <target/> 엘리먼트간에의존관계 (depends 속성 ) 를설정하는것이가능하다. 앤트빌드툴은 <target/> 엘리먼트생성및 <target/> 엘리먼트간의의존관계를개발자가자유롭게정의할수있다. 그러나메이븐은모든빌드단위가이미정의되어있으며, 개발자가임의로변경할수없다. 이절에서는메이븐이기본으로제공하는메이븐의빌드단계에대하여살펴보도록하겠다. 일반적으로프로젝트를빌드할때의과정을보면빌드결과물삭제, 컴파일을하기위하여필요한자원을복사, 소스코드컴파일, 테스트, 압축 ( 패키지 ), 배포의과정을거친다. 앤트에서는이각각의단계를타겟 target 으로만든후각타겟간에의존관계를만들어순서를결정하도록했다. 메이븐도앤트와똑같다. 단, 한가지다른점이라면빌드단계를미리정의하고있다는것이다. 메이븐은이와같이미리정의하고있는빌드순서를라이프사이클하며, 라이프사이클의빌드단계를 페이즈라고부른다. 메이븐에서는모두세개의라이프사이클을제공한다. 첫째는소스코드를컴파일, 테스트, 압축, 배포를담당하는기본라이프사이클, 둘째는빌드한결과물을제거하기위한 clean
Maven Chapter4 Page 5 라이프사이클, 셋째는프로젝트문서사이트를생성하는 site 라이프사이클이다. 메이븐에서제공하는세 개의라이프사이클을도식화해보면그림 4-1 과같다. 그림 4-1 메이븐에서제공하는세개의라이프사이클 그림 4-1 에서기본라이프사이클은라이프사이클에서중심이되는페이즈만을보여주고있다. 메이븐에서제공하는페이즈는그림 4-1 보다더많은단계를제공한다 2. 메이븐빌드의중심이되는라이프사이클은기본라이프사이클이며, 메이븐빌드에서제공하는세개의라이프사이클은독립적으로실행하는것이가능하다. 4.1.1 기본라이프사이클 메이븐은기본라이프사이클을활용해소스코드컴파일, 테스트, 압축, 배포와같은일련의작업이모두 실행된다. 기본라이프사이클의각페이즈에대하여살펴보면다음과같다. compile: 소스코드를컴파일한다. test: JUnit, TestNG 와같은단위테스트프레임워크로단위테스트를한다. 기본설정은단위 테스트가실패하면빌드실패로간주한다. 2 Maven 에서제공하는라이프사이클의모든페이즈는 http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html 문서에서확인할수있다.
Maven Chapter4 Page 6 package: 단위테스트가성공하면 pom.xml 의 <packaging /> 엘리먼트값 (jar, war, ear 등 ) 에따라압축한다. install: 로컬저장소에압축한파일을배포한다. 로컬저장소는개발자 PC 의저장소를의미한다. deploy: 원격저장소에압축한파일을배포한다. 원격저장소는외부에위치한메이븐저장소를의미한다. 저장소와관련한더자세한내용은 5 장에서다루고있다. 기본라이프사이클은여러단계의페이즈로나뉘어져있으며, 각페이즈는의존관계를가진다. 그림 4-1 에서 package 페이지를실행하면의존관계에있는 test 페이즈가먼저실행되고, test 페이즈는 compile 페이즈에의존관계가있기때문에 compile 페이즈가먼저실행되는방식이다. 따라서최종적인빌드순서를보면 compile, test, package 페이즈순으로빌드가진행된다. 4.1.2 clean 라이프사이클 clean 라이프사이클은 clean 페이즈를이용하여실행할수있다. clean 페이즈를실행하면메이븐빌드를 통하여생성된모든산출물을삭제한다. 메이븐은기본으로모든산출물을 target 디렉토리에생성하는데 clean 페이즈를실행하면 target 디렉토리를삭제한다. 4.1.3 site 라이프사이클 site 라이프사이클은 site 와 site-deploy 페이즈를이용하여실행할수있다. site 라이프사이클은메이븐설정파일의정보를활용하여프로젝트에대한문서사이트를생성할수있도록지원한다. mvn site 를실행하면메이븐에설정되어있는기본설정, 플러그인설정에따라 target/site 디렉토리에문서사이트를생성한다. site 페이즈는문서사이트를생성하고, site-deploy 페이즈는생성한문서사이트를설정되어있는서버에배포하는역할을한다. 3 장에서생성한위키북프로젝트에서 mvn site 를실행하면그림 4-2 와같이기본문서사이트가 생성된다.
Maven Chapter4 Page 7 그림 4-2 위키북프로젝트에서 site 페이즈를통하여생성한문서사이트 4.2 메이븐페이즈와플러그인 메이븐에서제공하는모든기능은플러그인을기반으로동작한다. 메이븐페이즈또한메이븐플러그인을 통하여실질적인작업이실행된다. 따라서메이븐페이즈가실행되는과정을이해하기위하여먼저메이븐 플러그인에대하여이해해야한다. 4.2.1 메이븐플러그인 메이븐에서사용하고자하는플러그인이있다면메이븐설정파일에다음과같이설정한다. < 코드 > <project> <build> <plugins> <plugin> <groupid>org.apache.maven.plugins</groupid> <artifactid>maven-compiler-plugin</artifactid> <version>2.1</version> </plugin> </plugins> </build>
Maven Chapter4 Page 8 </project> </ 코드 > 메이븐에서플러그인을사용하려면 <build>/<plugins>/<plugin> 엘리먼트아래에사용하고자하는 플러그인의 groupdid, artifactid, version 을설정하면된다. 위소스코드는 compiler 플러그인을사용하도록 설정한것이다. 메이븐플러그인은하나의플러그인에서여러작업을수행할수있도록지원한다. 메이븐은플러그인에서실행할수있는각각의작업을골 goal 이라고정의한다. 예를들어 compiler 플러그인은하나지만이플러그인이지원하는골은 sourcedirectory 의소스코드를컴파일하는 compile 골, testsourcedirectory 의테스트소스코드를컴파일하는 testcompile 골, compiler 플러그인에대한도움말을제공하는 help 골로나뉜다. 빌드스크립트에설정한플러그인은다음과같은방법으로실행할수있다. mvn groupid:artifactid:version:goal 예를들어앞에서설정한 compiler 플러그인의 compile 골은다음과같이실행할수있다. mvn org.apache.maven.plugins:maven-compiler-plugin:2.1:compile 그런데플러그인의특정골을실행하기위하여이와같이복잡한방법으로실행해야한다면많은 개발자들이플러그인을사용하지않을것이다. 따라서메이븐은플러그인을좀더쉽게실행할수있도록 다음과같은규칙을두어관리하고있다. 개발자로컬저장소에설치되어있는가장최신버전의플러그인을실행하기를원한다면 version 을 생략할수있다.(groupID:artifactID:goal) artifactid 가 "maven-$name-plugin" 와 "$name-maven-plugin" 규칙을따른다면 groupid:$name:goal 형식으로실행할수있다. 예를들어앞의 compiler 플러그인은 org.apache.maven.plugins:compiler:compile 과같이실행할수있다. 메이븐은중앙저장소에위치한플러그인을찾기위한 groupid 목록을 MAVEN_HOME/conf/settings.xml 이나 USER_HOME/.m2/settings.xml 파일에서다음과같이 관리할수있다.
Maven Chapter4 Page 9 <plugingroups> <plugingroup> org.apache.maven.plugins</plugingroup> </plugingroups> 이플러그인그룹목록에포함하면 $name:goal 과같이실행할수있다. compiler 플러그인은최종적으로 compiler:compile 로실행하는것이가능하다. 앞으로이책에서다루게될메이븐플러그인은 $name:goal 형태로실행하는것이가능하다. 그이유는메이븐은기본적으로플러그인그룹목록에 org.apache.maven.plugins 와 org.codehaus.mojo 을가지고있으며, 우리가사용하게될메이븐플러그인의대부분은위두개의 groupid 를가지기때문이다. 지금까지어떻게동작하는지도모르고실행했던 archetype:generate 명령은 groupid 가 org.apache.maven.plugins, artifactid 가 maven-archetype-plugin 인플러그인의 generate 골, help:effetive-pom 명령은 groupid 가 org.apache.maven.plugins, artifactid 가 maven-help-plugin 인플러그인의 effective-pom 골을실행한것이다. 버전은로컬저장소에다운로드한최신버전을활용한다. 메이븐에서활용할수있는대부분의플러그인은다음두개의사이트에서제공하고있다. 아파치메이븐사이트 : http://maven.apache.org/plugins/ 코드하우스모조 Codehaus Mojo 프로젝트 : http://mojo.codehaus.org/plugins.html < 참고사항 > 위두개의사이트에접속해보니너무많은플러그인을제공하고있어어느플러그인을사용해야할지막막할것이다. 이클립스를처음사용할때가장좋았던점이다양한플러그인을제공하고있어서내가원하는개발환경을얼마든지확장해나갈수있다는것이었다. 그런데시간이지나면서너무많은플러그인으로인해어느플러그인을사용해야할지막막한경험이있었는데메이븐또한같은경험을할가능성이높다. 이클립스도초반에는다양한플러그인을설치하고활용해보면서재미를느끼는데결국에는반드시필요하다고생각되는몇개의플러그인만을제한적으로사용한다. 메이븐플러그인또한같은전략으로접근하는것이바람직할것으로생각된다. 따라서처음부터많은플러그인을활용하는데초점을맞추지말고꼭필요하다고생각되는플러그인이발생하는순간적용하는전략을가져가는것이좋을것으로생각한다. 이책에서는프로젝트를진행할때사용하면좋겠다고생각하는플러그인을위주로진행하도록하겠다. < 참고사항 >
Maven Chapter4 Page 10 4.2.2 페이즈와플러그인의관계 메이븐에서페이즈는빌드라이프사이클에서빌드단계와각단계의순서만을정의하고있는개념이다. 빌드과정에서페이즈가실질적인빌드작업을하지는않는다. 실질적인빌드작업은각페이즈에연결되어있는플러그인의골이한다. 지금까지앞장에서 mvn test, mvn package 와같이빌드를했던것은메이븐의페이즈를실행한것이다. 예를들어 mvn compile 과같이 compile 페이즈를실행한것이다. compile 페이즈를실행하면실질적인컴파일작업은 compile 페이즈와연결되어있는 compiler 플러그인의 compile 골이실행되면서컴파일작업을진행한다. 그림 4-3 페이즈와골간의연결관계 그림 4-3 에서보는바와같이메이븐의기본라이프사이클은페이즈를기반으로빌드를실행하며, 각 페이즈를실행할때기본으로연결된플러그인의골을실행하는구조로동작한다. 메이븐의라이프사이클 페이즈와골의연관관계를살펴보면다음과같다.
Maven Chapter4 Page 11 그림 4-4 메이븐기본페이즈와골간의관계를보여주는화면 3 기본페이즈에대한플러그인정보는메이븐이이미알고있으므로추가설정없이페이즈를실행하면플러그인을자동으로다운로드한다. 예를들어 compile 페이즈를실행하면메이븐중앙저장소에서 compiler 플러그인을자동으로다운로드해서컴파일을진행한다. 메이븐기반프로젝트를생성한후기본페이즈를실행하면많은플러그인을다운로드하는것을확인할수있다. 메이븐의페이즈가실행되면서각페이즈와연결되어있는플러그인이실행되는과정을살펴보기위하여 3 장에서만들었던위키북프로젝트를 mvn test 명령으로다시한번실행해결과화면을살펴보자. 3 그림 4-4 는 Maven: The Definitive Guide 책에서인용했다. Maven: The Definitive Guide 책의 PDF 버전은 http://books.sonatype.com/maven-book/index.html에서무료로다운로드할수있다. Maven: The Definitive Guide 책은메이븐에대한전반적인내용을모두포함하고있어메이븐을더깊이있게활용하고자하는개발자에게많은도움을준다.
Maven Chapter4 Page 12 그림 4-5 위키북프로젝트에서 test 페이즈를실행했을때의결과화면 3 장에서는대수롭지않게생각되었던빌드과정이그림 4-5 를보면대략적으로어떤방식으로진행되는지이해할수있을것이다. 그림 4-4 의기본라이프사이클을보면 test 페이즈를실행했을때페이즈가실행되는순서는 process-resources(resources:resources), compile(compiler:compile), process-testresources(resources:testresources), test-compile(compiler:testcompile), test(surefire:test) 이다. 그림 4-5 를보면각페이즈가실행될때각페이즈와연결되어있는플러그인의골이실행되는것을알수있다. 이와같이메이븐은기본빌드작업부터확장기능까지모든작업이플러그인기반으로동작한다.
Maven Chapter4 Page 13 메이븐의기본페이즈에연결되어있는플러그인은메이븐중앙저장소에서자동으로다운로드한다. 따라서 빌드를할때추가적인설정을하지않아도된다. 지금까지메이븐의라이프사이클, 각라이프사이클을구성하고있는페이즈, 각페이즈에연결되어있는 플러그인의관계에대하여살펴봤다. 다음은각페이즈에대한구체적인설명과설정방법에대하여 살펴보도록하겠다. 4.3 메이븐기본페이즈와플러그인 4.3.1 자원복사및소스코드컴파일 처음살펴볼페이즈는소스코드를컴파일하는 process-resources 와 compile 페이즈이다. 3 장에서생성한 위키북프로젝트의디렉토리로이동한후다음명령을실행하면 src/main/java 디렉토리아래의모든소스 코드가컴파일된다. mvn compile compile 페이즈를실행하면먼저의존관계에있는 process-resources 페이즈가실행된다. processresources 페이즈에서는 resources 플러그인의 resources 골 (resources:resources) 이먼저 src/main/resources 디렉토리에있는모든자원을 target/classes 디렉토리로복사한다. 만약 pom.xml 파일에서 <resources/> 엘리먼트를재정의했다면재정의한규칙에따라자원을복사한다. <project > <build> <resources> <resource> <directory>src/main/resources</directory> </resource> <resource> <directory>src/main/java</directory> <excludes> <exclude>**/*.java</exclude> </excludes> </resource> </resources> </build> </project> 예제 4-2 <resources/> 엘리먼트를재정의할때의예제소스
Maven Chapter4 Page 14 예제 4-2 는 pom.xml 설정파일에서 <resources/> 엘리먼트를재정의하였다. 애플리케이션을개발하다보면아이바티스프레임워크설정파일이나스트럿츠 2 프레임워크의메시지설정파일을 src/main/resources 디렉토리에서관리하기보단설정파일을사용하는소스와같은패키지로관리할때가더유용하므로보통은 src/main/java 디렉토리에서관리한다. 이처럼 src/main/java 디렉토리에서도자원을관리한다면예제 4-1 과같이설정하면된다. 예제 4-1 에서설정한정보를바탕으로 compile 페이즈를실행하기전에 *.java 파일을제외한모든설정파일을 target/classes 디렉토리로복사한다. process-resources 페이즈실행이완료된후 compile 페이즈와연결된 compiler 플러그인의 compile 골 (compiler:compile) 이 src/main/java 디렉토리의자바소스코드를 target/classes 디렉토리로컴파일한다. compile 페이즈는 src/main/java 디렉토리의소스코드만컴파일한다. 명령프롬프트에서 mvn compile 을실행했을때의결과화면은다음과같다. 그림 4-6 위키북프로젝트에서 compile 페이즈를실행했을때의화면 자바소스코드를컴파일할때컴파일러의버전, 자바소스코드의인코딩설정이필요할때가있다. 이와 같은설정은 compiler 플러그인에서하면된다. 만약프로젝트 pom.xml 파일에서재정의하지않으면 최상위 POM 에설정된 compiler 플러그인설정을따른다. <project > <build> <plugins>
Maven Chapter4 Page 15 <plugin> <artifactid>maven-compiler-plugin</artifactid> <configuration> <source>1.5</source> <target>1.5</target> <encoding>utf-8</encoding> </configuration> </plugin> </plugins> </build> </project> 예제 4-3 compiler 플러그인에컴파일러 source, target 버전과인코딩을설정하는예제소스 resources 플러그인과 compiler 플러그인에대한자세한정보는다음 URL 에서참조할수있다. resources 플러그인 : http://maven.apache.org/plugins/maven-resources-plugin/ compiler 플러그인 : http://maven.apache.org/plugins/maven-compiler-plugin/ compiler 플러그인페이지를확인해보면예제 4-3 에서설정한옵션이외에추가적인옵션을설정하는것이 가능하다는것을확인할수있다. 플러그인설정과활용에대한더자세한내용은 6 장에서다루고있다. 4.3.2 테스트자원복사및테스트소스코드컴파일 src/test/resources 디렉토리의자원복사는 process-test-resources 페이즈, src/test/java 디렉토리에있는테스트소스코드컴파일은 test-compile 페이즈에서진행한다. test-compile 페이즈는 compile 페이즈와같이소스코드를컴파일하기전에 process-test-resources 페이즈를실행해 src/test/resources 디렉토리의자원을먼저복사한후테스트소스코드를컴파일한다. mvn test-compile src/test/java 디렉토리에있는모든테스트소스코드는 src/main/java 디렉토리에있는실제소스코드와의존관계에있다. 즉, 실제소스코드를컴파일하지않은상태에서테스트소스코드는컴파일할수없다. 따라서 test-compile 페이즈를실행하면 compile 페이즈를먼저실행해 src/main/java 디렉토리의소스코드를컴파일한다. 위키북프로젝트에서 test-compile 을실행하면다음과같이 compile 페이즈가먼저실행되는것을확인할수있다.
Maven Chapter4 Page 16 그림 4-7 위키북프로젝트에서 test-compile 페이즈를실행했을때의화면 test-compile 페이즈를실행하면 compiler 플러그인의 testcompile 골이실행된다. 그림 4-7 을보면 compiler:testcompile 을실행하기전에 compiler:compile 을실행하고, src/test/resources 에있는자원을 target/test-classes 디렉토리에복사하는것을확인할수있다. 4.3.3 테스트하기 테스트소스코드까지컴파일을완료했다면다음단계는테스트코드로실제서비스코드를테스트해야 한다. 이때사용하는페이즈가 test 이다. mvn test test 페이즈는 target/test-classes 에컴파일한단위테스트클래스를실행하고그에따른결과물을 target/surefire-reports 디렉토리에생성한다. test 페이즈는 test-compile 페이즈에의존관계를가진다.
Maven Chapter4 Page 17 그림 4-8 위키북프로젝트에서 test 페이즈를실행했을때의화면 메이븐의기본설정은 test 페이즈를실행하면 target/test-classes 디렉토리아래에존재하는모든단위 테스트클래스를실행한다. 만약테스트를실행할때특정테스트수트 TestSuite 별로나누어서테스트를실행할 필요가있다면 test 옵션을사용한다. 다음과같이 test 를실행할때원하는테스트클래스를지정할수있다. mvn -Dtest=AllUnitTests test 만약테스트클래스를여러개실행하고싶다면쉼표 (,) 로구분한다. mvn -Dtest=AllUnitTests,AllIntegrationTests test 메이븐을사용하지않는프로젝트에처음메이븐을적용할경우기존에작성한단위테스트코드가정상적으로동작하지않아빌드가되지않을수도있다. 물론단위테스트코드를지속적으로관리해단위테스트를실행했을때 100% 성공한다면문제없다. 하지만, 대부분프로젝트에서는단위테스트코드로기능이정상동작하는지확인한후지속적으로관리하지않아실패하는단위테스트가존재하는경우가많다. 이처럼실패하는단위테스트가존재할경우빌드가실패하면서다음단계를실행할수없다. 이같은상황에서는단위테스트를실행하지않도록 maven.test.skip 속성을 true 로설정할수있다. mvn -Dmaven.test.skip=true test
Maven Chapter4 Page 18 매번 maven.test.skip=true 을인자로전달하기싫다면 pom.xml 설정파일에서 <properties/> 엘리먼트에 maven.test.skip 속성을추가하면된다. <project > <properties> <maven.test.skip>true</maven.test.skip> </properties> </project> 위와같이설정하는것도가능하지만 test 페이즈에연결되어있는 surefire 플러그인에서설정할수도있다. <plugin> <groupid>org.apache.maven.plugins</groupid> <artifactid>maven-surefire-plugin</artifactid> <version>2.5</version> <configuration> <skiptests>true</skiptests> </configuration> </plugin> 다른페이즈는플러그인이름을보면어떤기능을할지이해할수있는데 surefire 플러그인은플러그인이름만으로는이해하기어려운부분이있다. 위와같이설정할경우단위테스트를실행하지않기때문에지금까지만든단위테스트가의미없게된다. 따라서일부단위테스트가실패하더라도다음단계의빌드를실행하도록 surefire 플러그인을설정할수있다. <plugin> <groupid>org.apache.maven.plugins</groupid> <artifactid>maven-surefire-plugin</artifactid> <version>2.5</version> <configuration> <testfailureignore>true</testfailureignore> </configuration> </plugin>
Maven Chapter4 Page 19 surefire 플러그인은기본으로 JUnit 테스트프레임워크 4 를기반으로동작하는단위테스트코드에대하여실행 가능하다. 만약 TestNG 테스트프레임워크 5 를기반으로작성한단위테스트를실행하고자한다면다음과같이 설정할수있다. <plugin> <groupid>org.apache.maven.plugins</groupid> <artifactid>maven-surefire-plugin</artifactid> <version>2.5</version> <configuration> <suitexmlfiles> <suitexmlfile>testng.xml</suitexmlfile> </suitexmlfiles> </configuration> </plugin> 위예제소스에서 testng.xml 파일은 TestNG 테스트프레임워크의단위테스트를관리하는설정파일이다. surefire 플러그인에대한더자세한정보는다음 URL 에서참조할수있다. surefire 플러그인 : http://maven.apache.org/plugins/maven-surefire-plugin/ 4.3.4 패키징하기 컴파일과테스트가완료되었다면다음작업은 jar, war 와같은형태로압축하는것이다. 이처럼 pom.xml 의 <packaging/> 엘리먼트에설정한값으로압축할때사용하는페이즈가 package 이다. mvn package 4 http://www.junit.org/ 자바진영에서가장활발하게사용하는단위테스트프레임워크이다. 5 http://testng.org/ JUnit 과더불어활발하게사용되는단위테스트프레임워크이다. TestNG 는각단위 테스트간에의존관계를설정할수있다는것이특징이다.
Maven Chapter4 Page 20 package 페이즈를실행하면 compile, test-compile, test, package 순으로실행된다음 jar, war 파일이 target 디렉토리하위에생성된다. package 페이즈로생성하는압축파일의명명규칙은다음과같다. 메이븐은기본적으로 <build>/<finalname> 엘리먼트에값이설정되어있다면 ${finalename}.${packaging} 형태로압축파일이생성된다. 예를들어위키북프로젝트설정이다음과같다. <project...> <groupid>net.javajigi</groupid> <artifactid>wikibook</artifactid> <packaging>war</packaging> <version>1.0-snapshot</version> <build> <finalname>wikibook</finalname> </build> </project> 위와같이설정된상태에서 package 페이즈를실행하면 target/wikibook 디렉토리와 target 디렉토리아래에 wikibook.war 파일이생성된다. 이파일의이름과 target/wikibook 디렉토리의이름은 pom.xml 에서 finalname 엘리먼트설정에따라결정된다. 만약 finalname 엘리먼트가설정되어있지않으면 ${artifactid}- ${version}.${packaging} 이압축파일이름과디렉토리이름이된다. <project...> <groupid>net.javajigi</groupid> <artifactid>wikibook</artifactid> <packaging>war</packaging> <version>1.0-snapshot</version> <build> </build> </project> 예를들어위와같이설정되어있고 finalname 이설정되어있지않다면생성되는디렉토리명은 target/ wikibook-1.0-snapshot 이며, war 파일의이름은 wikibook-1.0-snapshot.war 이된다. 압축플러그인과관련된더자세한내용은다음 URL 에서참조할수있다.
Maven Chapter4 Page 21 war 플러그인 : http://maven.apache.org/plugins/maven-war-plugin/ jar 플러그인 : http://maven.apache.org/plugins/maven-jar-plugin/ ear 플러그인 : http://maven.apache.org/plugins/maven-ear-plugin/ 4.3.5 배포하기 메이븐으로압축까지완료했다면압축한파일을배포해야한다. 메이븐의배포방식은두가지로나뉜다. 첫번째는메이븐을실행하는컴퓨터의로컬저장소에압축한 jar, war 파일을배포하기다. 두번째는메이븐원격저장소에배포하기다. 메이븐의원격저장소와사내메이븐저장소설치에관한내용은 11 장에서자세하게다루겠다. 이절에서는각저장소에압축한결과물을배포할때사용하는페이즈만살펴보겠다. 메이븐로컬저장소에배포할때는 install 페이즈를사용할수있다. mvn install install 페이즈는 package 페이즈에의존관계에있다. 따라서 install 페이즈를실행하기전에 package 페이즈를실행해압축을완료한다음로컬저장소에배포한다. 다른개발자들과 jar, war 파일을공유하려면로컬에서압축한 jar, war 파일을외부에존재하는메이븐 저장소에배포해야한다. 메이븐에서이작업을지원하는페이즈는 deploy 이다. mvn deploy deploy 는 jar, war 파일을원격저장소에등록하는역할을한다. deploy 페이즈는 install 페이즈와의존 관계에있다. 지금까지살펴본페이즈의의존관계를살펴보면 compile, test-compile, test, package, install, deploy 순으로의존관계가있는것을알수있다. 메이븐의배포와관련한플러그인에대한더자세한정보는다음 URL 에서참조할수있다. install 플러그인 : http://maven.apache.org/plugins/maven-install-plugin/ deploy 플러그인 : http://maven.apache.org/plugins/maven-deploy-plugin/ 4.3.6 빌드결과물제거하기 메이븐에서기본으로제공하는페이즈중에서마지막으로살펴볼페이즈는빌드한결과물을제거하는 페이즈이다. 메이븐은 target 디렉토리의결과물을모두제거하고처음부터새롭게빌드할수있는 clean 페이즈를제공한다.
Maven Chapter4 Page 22 mvn clean clean 페이즈를실행하면 target 디렉토리가삭제된다. clean 페이즈는다른페이즈와의존관계가없다. 명시적으로실행하지않을경우다른페이즈가실행될때 clean 페이즈는실행되지않는다. 그런데 clean 페이즈를실행하지않을경우이전에빌드했던산출물중에서불필요한산출물이남아있어에러가발생할수있다. 따라서다른페이즈를실행할때반드시 clean 을실행하고빌드하는습관을가지는것이좋다. mvn clean test => clean 페이즈를실행하여 target 디렉토리를삭제한후 test 페이즈를실행한다. mvn clean install => clean 페이즈를실행하여 target 디렉토리를삭제한후 install 페이즈를실행한다. clean 플러그인에대한더자세한내용은다음 URL 에서참조할수있다. clean 플러그인 : http://maven.apache.org/plugins/maven-clean-plugin/ < 참고사항 > 그림 4-1 을보면메이븐은 site, site-deploy 페이즈를기본으로가진다. 이페이즈에대해서는 9 장에서하나의장을할애해설명하고있기때문에이장에서는설명을생략한다. </ 참고사항 > 메이븐기반으로빌드를어떻게실행할지막막했는데이제서야어느정도감이잡혔다. 물론 100% 모두 이해했다고확신할수는없지만앞으로메이븐을활용하면서더깊이있게이해하면될듯하다. 사실 메이븐이빌드하는과정을살펴보면서다음과같은결론을얻었다. 지금까지앤트를사용할때타겟을추가하고각타겟간에의존관계를연결하던반복적인작업을메이븐은 미리정의하고있다. 이같은결론을얻고나니앤트와별반다를것이없다는생각이든다. 지금까지앤트기반으로작업할때매번반복하던작업을하지않아도된다고생각하니기분이홀가분하다. 그런데한가지의문이생긴다. 앤트는새로운타겟을추가하고다른타겟과의존관계를연결하는것이자유롭다. 그런데메이븐은각페이즈와하나의플러그인이연결되어있고, 특정페이즈를실행하면연결되어있는플러그인이실행되는구조로되어있다. 만약각페이즈사이에새로운빌드작업을추가하고싶은상황이발생할텐데이런상황에대한지원도가능하겠지? 아직은이에대한해결방법을찾지못했지만메이븐의빌드과정을이해했다는것에만족해야겠다. 메이븐에대한이해도가높아지면서해결방법을찾으리라는기대를하면서오늘공부는마쳐야겠다. 오늘은메이븐빌드단계에대한이해를하려고공부하다보니위키북프로젝트에기여한부분이하나도 없다. 오늘은기여를못했지만내일은반드시무엇인가기여를해야겠다.
Maven Chapter4 Page 23 5. 메이븐을이용한의존라이브러리관리 6. 메이븐과이클립스통합 7. 메이븐과데이터베이스통합 8. 메이븐프로파일, 배포 9. 리포팅기능을활용한문서관리 10. 메이븐모듈 module 11. 메이븐사내저장소설치및활용 12. 표준 POM 파일생성및리팩토링 13. 메이븐아키타입 archetype
Maven Chapter4 Page 24 14. 새로운프로젝트를시작하면서..