메이븐이란? (JAVA Maven the build tool)
회사에서 일을 하면서 내가 정말 해멨던 메이븐에 대해서 정리해보고자 한다.
나는 회사에서 메이븐 때문에 고생을 많이 했다. 정말정말정말정말!!!!
코드가 아무리 맞게 짜여져 있어도 메이븐이 꼬여 있으면 ㅠㅠ 프로그램이 작동하지 않는다.....
(아무리 apple.java, banana.java, kiwi.java가 알맞게 짜여있어도)
처음에는 이것이 도무지 이해가 가지 않았었다. 아니 난 옆자리 분과 토씨하나 틀리지 않고 똑같은 코드를 가지고 있는데, 내 컴퓨터에선 작동 자체가 되지 않는 것인가?
처음엔 이 순간만 모면하면 되겠지, 어떻게든 run만 되면 되겠지 란 마음으로 대충 환경을 설정하고 새로고침하고 생활하다가...
왜 이게 작동되는지 모르고, 왜 이게 안되는지 모르니깐 버리는 시간이 많더라.
그래서 제대로 배워보고자 공부하며 쓰는 글!
기본 개념
- 빌드 (Build) :
소스코드를 컴퓨터에서 실행 가능한 독립 SW 가공물로 변환하는 과정 또는 그에 대한 결과물
다시 말하면, 내가 쓴 코드 파일 및 자원 등(.xml, properties, .jpg, .jar)을 JVM이가 인식할 수 있는 구조로 패키징 하는 과정 및 결과물. (만약 자바라고 한다면) 이클립스나 인텔리제이 없이도 내가 작성한 code.java의 내용이 작동될 수 있어야 한다. - 빌드 관리 도구 (Build Tool):
프로젝트에서 필요한 xml, properties, jar 파일등을 자동으로 인식하여 빌드.
프로젝트 정보 관리, 테스트 빌드, 배포등의 작업 진행
외부 라이브러리를 참조하여 자동으로 다운로드 및 업데이트 및 관리 - Ant, Maven, Gradle
자바의 대표적인 빌드 관리 도구들이다. (Ant → Maven → Gradle 순서대로 개발됨)
Ant는 너무 옛날 옛적이 쓰이던 빌드 도구이며 현재는 잘 쓰이지 않는다.
Gradle은 안드로이드 및 많이 쓰이는 빌드 도구이지만 이 글에서 설명을 생략한다. (왜냐면 울 회사에서 안쓰니까 ㅋㅋ) - 빌드 순서 (Build Process):
Compile → Test → Packaging 3 단계로 진행
(1) Compile: src/main/java 디렉토리 아래의 모든 소스 코드가 컴파일
(2) Test: src/test/java, src/test/resources 테스트 자원 복사 및 테스트 소스 코드 컴파일 됨
(3) Packaing: 컴파일과 테스트가 완료 된 후, jar, war 같은 형태로 압축하는 작업 - JAR:
java archive 준말. 빌드의 결과물 중 하나.
어플리케이션을 쉽게 동작하도록 관련 파일(자바 리소스, 속성, 라이브러리 등)들을 패키징해주는 것이 주 역할
.zip처럼 비슷하게 생겼는데, .zip과는 달리 .jar은 압축해제를 하지 않아도 JDK에서 접근해서 사용 가능.
jar파일은 JRE만 있다면 프로젝트 구동이 가능하다.
Mavem이란? Maven 특징!
메이븐의 특징이자 바로 대표적인 장점은 라이브러리 관리/다운로드가 편리하다는 것.
한 때 자바 대표 빌드 관리 도구였던 Ant를 대체/개선하기 위해 개발된 메이븐!
Ant는 단순 빌드 기능만 있었지만 Maven은 정해진 라이프 사이클에 의해 체계적으로 빌드를 수행하며, 프로젝트 라이브러리까지 관리 해주는 장점이 있다.
- 프로젝트에서 필요한 라이브러리가 무엇인지 pom.xml 파일로 알 수 있다. (프로젝트당 하나씩 있는 바로 그 파일)
- pom.xml에 정의된 필요 라이브러리에 연관된 다른 라이브러리도 자동 관리 가능하다. 나는 pom.xml에 A라는 라이브러리만 필요하다고 말해놓았지만, A가 만약 A1, A2, A3, A4등에 dependency를 가지고 있다면, A1,A2,A3,A4 라이브러리도 함께 다운 받아 주는 것이다. (일잘알..)
- 자동 의존성 관리는 중앙저장소를 통해서 한다.
중앙 저장소는 라이브러리를 공유하는 파일서버인데, 아파치재단에서 운영관리하는 저장소를 사용할 수도 있고 별도의 사설 저장소(nexus등) 를 사용할 수도 있다. (현업에서도 난 두 개에서 내려받는다) - 현재 다운받아 사용하던 라이브러리가 바뀌면 자동으로 업데이트 또한 해준다. (일잘알2..)
라이프사이클 life cycle 이란?
메이븐은 프레임워크이기 때문에 정해진 동작 방식 및 순서가 있다. 이 순서를 라이프사이클이라 한다.
◎ Clean: 빌드 시 생성되었던 파일들을 삭제
◎ Validate: 프로젝트가 올바른지, 필요한 모든 정보를 사용할 수 있는지 확인
◎ Compile: 프로젝트의 소스코드를 컴파일 하는 단계
◎ Test : 유닛 테스트(예: junit)를 수행 하는 단계. 테스트 실패시 빌드 실패로 처리된다. 참고로 이 단계는 필수가 아니다. pom.xml에 skipTest 옵션을 줄 수 있다)
◎ Pacakge : 실제 컴파일된 소스 코드와 리소스들을 jar, war 등등의 파일 등의 배포를 위한 패키지로 만드는 단계
◎ Verify : 통합 테스트 결과에 대한 검사를 실행하여 품질 기준을 충족하는지 확인
◎ Install : 패키지를 로컬 저장소에 설치하는 단계
◎ Site : 프로젝트 문서와 사이트 작성, 생성하는 단계
◎ Deploy : 만들어진 package를 원격 저장소에 release 하는 단계
폼파일이란? (pom.xml ???)
자바 프로젝트에 필요한 라이브러리가 정의되어 있는 xml 파일이다. 라이브러리 뿐만 아니라 Maven이 프로젝트를 완전히 빌드하는 데 필요한 데이터가 다 여기에 있다.
메이븐을 이용하는 프로젝트의 root에 저장되어있다. 한 자바 프로젝트에 빌드 툴을 maven으로 설정하면, 프로젝트 최상위 디렉토리에 "pom.xml"이라는 파일이 자동 생성된다.
프로젝트에 대한 정보, 프로젝트에 존재하는 종속성, 소스 파일의 디렉토리, 플러그인 정보 등등이 적혀져 있는 것이다. Maven은이 모든 정보를 얻기 위해 pom 파일을 읽는다.
그럼 정의한 해당 라이브러리 + 관련 라이브러리까지 네트워크를 통해 자동 다운로드 하기 때문에, 협업할 때 대용량의 war, jar파일 등을 주고받을 필요 없다. (pom.xml만 건내주면 깔끔)
참고로 pom은 (project object model)의 준말이다.
<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.0http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.samsung.banana</groupId>
<artifactId>egovframework-dev-com</artifactId
<version>1.0</version>
<packaging>war</packaging>
<name>egovframework-dev-com Maven Webapp</name
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.4</version>
<scope>test</scope>
</dependency>
</dependencies>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
</plugins>
</project>
태그에 대해 좀 더 설명하자면:
먼저 최종 빌드하고자 하는 프로그램은 하나지만, 여기에 딸린 프로젝트들은 여러개일 수 있다는 것을 유념하자
프로젝트 하나당 폼파일은 하나 존재한다.
- modelVersion : 폼 모델(메이븐) 버전
- groupId : 프로젝트를 생성하는 조직의 고유 아이디로 일반적으로 대표하는 사이트 도메인을 역순으로 적음
나는 회사에서 com.samsung.XXX라고 씀 - artifactId : 그룹아이디 외 다른 프로젝트와는 구분될 수 있는 프로젝트 아이디. (프로젝트는 여러개일 수 있으니)
그룹아이디와 아티팩트아이디가 합쳐져서 프로그램의 도메인을 나타낸다. - parent: 프로젝트가 여러개일 때, 부모프로젝트인지 자식프로젝트인지.
프로젝트마다 pom.xml이 모두 존재하고, 자식프로젝트는 부모프로젝트 것을 상속(?) 받아온다. - version: 현 프로젝트 버전.
- packaging: 패키징 유형 (jar, war, ear등)
- name : 프로젝트 이름
- description: 해당 프로젝트의 간략한 설명. (기능 및 목적 등)
- properties: 폼파일내에서 빈번하게 사용되는 중복상수를 정의. 여기서 정의하고 추후 ${변수명}의 형태로 사용.
폼파일이 짧으면 모르겠는데, 회사에서 쓰는 것들은 진짜 500줄이 넘어간다. - build: 프로젝트 빌드와 관련된 정보 설정. (어떻게 배포할 것인가)
- encoding : 추후 기입 예정
메이븐 레파지토리 (maven repository)
artifact 들의 저장소 (내 컴퓨터에 저장하는 로컬 및 서버에 저장하는 리모트로 구성)
* artifact란? : 빌드로 생성되는 프로젝트의 결과물 (예: .jar, .war, .ear 등)
pom.xml에서 선언한 dependency들에 따라 프로젝트는 이 저장소로부터 불려와져 사용된다.
■ 로컬 저장소 (local repository)
메이븐 설치시 로컬의 maven artifact들을 저장/관리하는 repository가 자동으로 구성된다.
※ 디폴트 경로 : C:\Documents and Settings\Administrator\.m2\repository
이건 아마 셋팅파일(C:\Documents and Settings\Administrator\.m2\settings.xml)에 설정되어있을 텐데 수정 가능함
- 또는 IDE에서 레파지토리 경로 따로 지정 가능. (나는 그냥 프로젝트 폴더 안에 maven_repositories라고 따로 폴더를 만들어서 관련 라이브러리를 다 집어넣었다)
■ 원격 저장소 (remote repository)
메이븐에서 제공하는 아파치 중앙저장소 또는 각 기업에서 사용하는 사설 원격 저장소(예: nexus)들이 있다.
개발자는 환경설정을 통해 하나 이상의 외부 레파지토리에서 필요로 하는 artifact들을 다운로드 받아 사용할 수 있다.
■ 레파지토리 호출 프로세스
1. 프로젝트의 pom.xml에서 필요 라이브러리 선언
2. 개발자 로컬 저장소에서 선언한 라이브러리 검색
- 있다면 ? 프로젝트에 라이브러리 cache
- 없다면 ? 원격 저장소에요청
3. 원격 저장소에서 선언한 라이브러리 검색
- 로컬 저장소는 원격 저장소에서 검색된 artifact를 내려받아 저장한다.
- 여기서도 없다면? ----------> 빌드 불가 ㅠㅠ
Recall Maven Architecture
그렇다면 메이븐으로 프로젝트를 만들어보자.
직접 만들어 보면 보다 더 제대로 메이븐에 대해서 폼파일에 대해서 알 수 있을 것이다 ^____^
다음 글에서... 계속!