2017년 6월 16일 금요일

아파치 메이븐(Apache Maven) 시작하기

Apache Maven 프로젝트는 Java 어플리케이션의 빌드 과정을 간략화하기 위해 시작된 프로젝트이다. 그 전까지는 Apache Ant 를 이용해서 빌드 했는데, 이 경우에 여러개의 섭프로젝트로 이뤄진 하나의 프로젝트를 진행할 때 각 섭프로젝트가 서로 다른 Ant 빌드 파일을 가지고, 빌드된 JAR 파일들이 만들어지게 된다. Apache 개발팀은 프로젝트를 빌드하는데 있어 프로젝트의 구성 정보를 확실하게 전달하고, 여러 프로젝트에서 쉽게 JAR 파일을 공유할 수 있는 방식의 필요성을 느꼈고, 그에 대한 결과물로 Maven 이 탄생하게 된다. 그러니까 Maven은 기존의 "Ant + @기능들" 이라 생각하면 된다.

Maven을 우선 설치해야 공부하니까 설치하자. 가장 최신버젼은 3.5 버젼이고, 3.3 버젼 이상부터는 JDK 1.7이상이 설치되어있어야 한다. 설치가 안되있다면 [Java] 자바 시작하기(개발 환경 구성) 글을 보고 설차하도록 하자.

그리고 "JAVA_HOME" 이라는 환경변수 설정을 해주자. 위 글을 보고 따라하는 Ubuntu 사용자의 경우에는 나와 같은 위치에 설치했을테니 쉘을 열고 아래와 같이 타이핑하면 된다. 아니면 각기 jdk 설치한 위치로 하자. 윈도우 사용자의 경우에는 내컴퓨터 옵션에서 환경변수를 설정하자.

export JAVA_HOME= /opt/java/jdk1.8 #jdk폴더위치

그리고 나서는 https://maven.apache.org/download.cgi에 들어가 Maven 파일을 다운로드 해주자. 영어로 복잡하게 많겠지만 Link 칼럼에 있는것중에 Binary Archive를 다운받으면 된다. Source라 적힌것들은 직접 개발할때 쓰라는거다.

나의 경우에는 3.5버젼 apache-maven-3.5.0-bin.tar.gz 파일을 받았다. 다운 다 했으면 설치할 위치에 압축 풀고 놔주자. 편한데 놔두면 된다. 나는 /opt 폴더에 놔뒀다.

그리고 maven 폴더의 bin 폴더를 $PATH 변수에 추가해주면 된다. 그리고 쉘에서 mvn -v 명령어를 실행해주면 아래와 같은 결과가 나오고, 그러다면 설치가 완료된것이다.


user@user-desktop:~$ mvn -v
Apache Maven 3.5.0 (ff8f5e7444045639af65f6095c62210b5713f426; 2017-04-04T04:39:06+09:00)
Maven home: /opt/apache/apache-maven
Java version: 1.8.0_112, vendor: Oracle Corporation
Java home: /opt/java/jdk1.8/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "4.4.0-79-generic", arch: "amd64", family: "unix"

설치를 완료했다면 프로젝트를 하나 만들어보자. 아래 명령어를 실행해준다


user@user-desktop:~$ mvn archetype:generate 
# 첫 실행시 필요한 플러그인들과 파일들을 다운받는라 좀 오래걸릴거다.

Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): 984: #그냥 엔터치면 기본값으로 설정된다
Choose org.apache.maven.archetypes:maven-archetype-quickstart version: 
1: 1.0-alpha-1
2: 1.0-alpha-2
3: 1.0-alpha-3
4: 1.0-alpha-4
5: 1.0
6: 1.1
Choose a number: 6: #마찬가지, 엔터
Define value for property 'groupId': com.muckycode.app
Define value for property 'artifactId': maven-tutorial
Define value for property 'version' 1.0-SNAPSHOT: : #엔터
Define value for property 'package' com.muckycode.app: : #엔터
Confirm properties configuration:
groupId: com.muckycode.app
artifactId: maven-tutorial
version: 1.0-SNAPSHOT
package: com.muckycode.app
 Y: : y #설정을 확인하고 맞으면 y를 쳐주자, 그리고 나면 아래와 같이 빌드가 만들어졌다는 문장들을 볼수있을거다.
[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating project from Old (1.x) Archetype: maven-archetype-quickstart:1.1
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: basedir, Value: /home/user
[INFO] Parameter: package, Value: com.muckycode.app
[INFO] Parameter: groupId, Value: com.muckycode.app
[INFO] Parameter: artifactId, Value: maven-tutorial
[INFO] Parameter: packageName, Value: com.muckycode.app
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] project created from Old (1.x) Archetype in dir: /home/user/maven-tutorial
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:26 min
[INFO] Finished at: 2017-06-16T10:58:19+09:00
[INFO] Final Memory: 18M/200M
[INFO] ------------------------------------------------------------------------

Maven에 의해 생성된 프로젝트 폴더로 가보자. basedir내부에 artifactID폴더에 있을거다. 폴더 내부 구성을 보게되면


user@user-desktop:~/maven-tutorial$ ls -LR
.:
pom.xml  src

./src:
main  test

./src/main:
java

./src/main/java:
com

./src/main/java/com:
muckycode

./src/main/java/com/muckycode:
app

./src/main/java/com/muckycode/app:
App.java

./src/test:
java

./src/test/java:
com

./src/test/java/com:
muckycode

./src/test/java/com/muckycode:
app

./src/test/java/com/muckycode/app:
AppTest.java

기본적으로 maven은 프로젝트 폴더안에 pom.xml, Project Object Model 파일인데, 프로젝트의 구성정보를 전달하는 파일이다.
그리고 src 폴더안에 main 폴더와 test 폴더를 생성하고, 각 폴더 내부에 java 폴더를 생성, java 폴더 내부는 groupID에 입력했던 패키지 형식 계층으로 폴더가 구성된다.
위는 maven-archetype-quickstart라는 archetype을 선택(기본값이다)했을때이고 다른 옵션을 정하면 그에 따라 만들어진다.
Maven에서 소개하는 기본 디렉토리 구조는 아래와 같다. 혹시 이 중에 필요하나 안만들어진게 있다면, 직접 폴더를 만들면 된다.


디렉토리설명
src/main/java자바 소스 파일
src/main/resources리소스 파일
src/main/filters리소스 필터 파일
src/main/webapp웹앱 소스 파일
src/test/java테스트 소스 파일
src/test/resources테스트 리소스 파일
src/test/filters테스트 리소스 필터 파일
src/it확장(Integration) 테스트(플러그인용)
src/assemblyAssembly descriptors
src/siteSite
LICENSE.txt프로젝트 라이센스
NOTICE.txtNotice 파일
README.txtreadMe 파일

위의 폴더 구조와 내부 파일 설명은 Maven 규칙이기도 하니 잘 지켜주자. 모든 자바 소스 파일들은 src/main/java 폴더에 존재해야하며, 모든 테스트 소스 파일들은 src/test/java 폴더에 존재해야하고, 같은 방식으로 리소스들은 resources 폴더에 저장된다. 또 필수사항은 아니지만, 소스파일들은 groupId와 같은 패키지 구조를 가지는게 좋고, 기본적으로 만들어지는 App.java, AppTest.java 파일은 Maven 작동 테스트를 위한것임을 알아두자.

기본적으로 Maven 설치는 최소한의 Maven 기능만 설치한다. 추가기능들은 모드 plug-in 방식으로 제공되며, plug-in의 이름만 주어지면, Maven이 알아서 다운받고 설치한다. 위 프로젝트 생성의 경우에는 Maven이 archetype이라는 플러그인을 다운받았고, archetype 플러그인이 의존하는 다른 플러그인까지 알아서 다 다운받았다. 이런 플러그인들은 로컬에 저장되며, 한번 다운받았으면 다시 다운받을 필요 없다.

자 그러면 다시 우리 프로젝트 폴더로 이동해서 mvn package 명령어를 실행해주자. 그럼 아까와 같이 플로그인 다운로드가 끝난이후 아래와 같은 결과를 보게 될것이다.
설명하자면, mvn package 명령에서 package 파라미터는 build 사이클의 한 단계(Phase)를 의미한다. 각 phase 들은 개별 플러그인이며, 이 플러그인들이 실행하는 하나의 행위들을 goal이라고 표현한다. 예를들어 package 단계의 어떤 goal을 실행하고 싶다면 mvn package:anygoal 이런식을 콜론을 이용해서 명령어를 만들어주면 된다. 각 단계는 실행되기위해 그 전단계들의 실행을 필요로 한다. 그렇기 때문에 이 경우에, 우리는 package 단계를 실행했고, 그 전 단계인 Validate, Compile, Test 단계가 다 실행되고 Package단계가 실행된다. 물론 Validate, Compile, Test 단계모두 각각 실행 할 수도 있다.

  • Validate - pom.xml 파일을 조회해 프로젝트 구성과, 필요 정보에 이상 없나 확인한다.
  • Compile - 소스파일을 컴파일한다
  • Test - 테스트 소스를 컴파일하고 테스트 프레임워크를 실행해 테스트한다
  • Package - pom.xml 파일에 설정된 포맷으로 프로젝트를 패키징한다. 여기서는 jar 포맷이다.


user@user-desktop:~/maven-tutorial$ mvn package
[INFO] Scanning for projects...

[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] Building maven-tutorial 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------

################################################################################
# Validate 단계
[INFO] 
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ maven-tutorial ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /home/user/maven-tutorial/src/main/resources
[INFO] 

################################################################################
# 메인 소스 파일 변경을 감지하고 새로 컴파일한다 - Compile 단계
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ maven-tutorial ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to /home/user/maven-tutorial/target/classes
[INFO] 
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ maven-tutorial ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /home/user/maven-tutorial/src/test/resources
[INFO] 

################################################################################
# 테스트 소스 파일 변경을 감지하고 새로 컴파일한다
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ maven-tutorial ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to /home/user/maven-tutorial/target/test-classes

################################################################################
# 테스트를 진행한다 - Test 단계
[INFO] 
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ maven-tutorial ---
[INFO] Surefire report directory: /home/user/maven-tutorial/target/surefire-reports

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running com.muckycode.app.AppTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.005 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

################################################################################
# 테스트 결과가 이상 없고, 마지막 단계인 package 단계를 실행하고 jar 파일을 생성한다.
[INFO] 
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ maven-tutorial ---
[INFO] Building jar: /home/user/maven-tutorial/target/maven-tutorial-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.654 s
[INFO] Finished at: 2017-06-16T13:13:28+09:00
[INFO] Final Memory: 17M/195M
[INFO] ------------------------------------------------------------------------

여기까지가 CLI로 Maven을 이용하는 법이다. 근데 아마 대부분의 개발자들은 본인 취향의 IDE를 이용해 할것이니, 조금만 더 힘을내서 Maven과 Eclipse 연동하는 법을 알아보도록 하자.

Eclipse IDE는 Maven을 자체 내장해서 나온다. 엥 그면 위에서 설치 괜히한거~는 아니고, Eclipse 내장 Maven말고 별도로 설치한 다른 버젼의 Maven과도 연동할 수 있으니 타버젼 Maven을 사용하고 싶으면 아래와 같은 방법으로 하면 된다.

우선 Help 메뉴에서 About Eclipse를 클릭하게되면 아래와 같은 창이 보일것이다.

About Eclipse 창

그림에서 빨간 사각형 안에 들어가있는 m2라고 적힌 버튼이 보이는가, 그게 바로 Eclipse Maven 플러그인이다. 클릭하면 자세한 정보도 볼 수 있다. 만약 안보인다면 Eclipse 플러그인 검색으로 설치해주자.

설치가 되있는것을 확인했으면 Window 메뉴에서 Preferences 창으로 들어간다음 Maven 검색후 Installations 를 클릭해준다.

Eclipse Preference Maven Installations 창

그면 위와같은 창을 보게 될텐데, 우선은 내장 Maven을 사용하고 있기에 Embedded에 체크되있다. 옆의 Add 버튼을 눌러 위에서 설치했던 최신버젼의 Maven을 추가해주자.

Eclipse Maven Runtime 추가창

올바른 디렉토리를 추가해주고 적당한 이름도 붙여주기만 하면 끝난다. 그럼 아까 그 창이 아래와 같이 변하게 되고, 체크박스만 바꿔주면 연동이 완료된다.

추가 완료 후 Maven Installations 창

새로운 Maven 프로젝트를 생성해보자. File - New-Maven Project를 선택하면 아까 CLI로 했던 과정을 쉽게 할 수 있다.

Eclipse New Maven Project 창 - 01

Create a simple project(skip archetype selection) 을 선택해주자, 아까처럼 복잡한 옵션을 건너뛰고 기본값으로 프로젝트를 생성시켜 준다. 다음을 누르면

Eclipse New Maven Project 창 - 02

CLI랑 별 다른건 없다. 프로젝트 설정을 완료해주고, 완료를 누르면 패키지 탐색기에 새로운 프로젝트가 추가된다.

Eclipse m2 플러그인은 Maven을 통해 위 과정을 완료하기때문에, CLI와 과정이나 결과로 별달리 차이가 없다.

이미 생성된 프로젝트를 가져오기 위해서는 File - Import 에서 Existing Maven Project 선택 후 프로젝트 디렉토리 위치를 입력하면 된다. pom.xml 파일을 통해 프로젝트를 구성하기 때문에 pom.xml 파일에 입력된 설정, 의존성(Dependency)를 재구성한다.

댓글 없음 :

댓글 쓰기