넥서스는 저장소 관리자이므로 가장 중요하고 많이 사용하는 기능은 아티팩트를 등록하고 관리하는 것이다.
이 기능은 넥서스 관리 콘솔에서 수행 가능하지만 아티팩트가 변경되었거나 새로 추가될때마다 관리자가 수행하는 것은 좋은 방법이 아니다.
이제 자바의 빌드툴로 많이 사용되는 메이븐과 넥서스를 연계하는 방법을 알아 보자.
이 책은 메이븐에 대한 책이 아니므로 메이븐에 대한 설명은 넥서스와 연계하는데 필요한 부분에만 국한해서 설명할 것이다.
아직 메이븐이 설치되지 않은 독자들은 메이븐 홈페이지에서 3.0.x 버전의 메이븐을 설치하고 설치 경로를 PATH 에 추가하자.
/usr/local/apache-maven-3.0.5 에 설치했다면 .bash_profile 의 맨 뒤에 다음 내용을 추가한후에 source ~/.bash_profile 명령어로 설정 파일을 반영하자.
export PATH=$PATH:/usr/local/apache-maven-3.0.5/bin/
maven 3.0.5 버전부터는 HTTPS 로 연결할 경우 서버의 SSL 인증서를 검증한다. SSL 인증서가 자체 발급한 인증서일 경우 메이븐이 정상적으로 동작하지 않는다.
이 문제를 해결하려면 메이븐을 3.0.4 를 사용하거나 메이븐 구동시 다음 옵션을 추가해야 한다.
-Dmaven.wagon.http.ssl.insecure=
true
-Dmaven.wagon.http.ssl.allowall=
true
매번 설정이 번거롭다면 MAVEN_OPTS 환경 변수에 설정해도 된다. .bash_profile에 다음 내용을 추가하자.
export MAVEN_OPTS="-Dmaven.wagon.http.ssl.insecure=true -Dmaven.wagon.http.ssl.allowall=true"
메이븐 저장소 종류
메이븐도 넥서스처럼 여러 종류의 저장소를 갖고 있지만 의미는 약간 다르다. 메이븐은 총 3가지 저장소 방식이 있는데 하나씩 알아보자.
로컬 저장소(local Repository)
메이븐은 다운받은 아티팩트를 메이븐이 실행된 PC 또는 서버의 파일 시스템에 캐싱하고 있으며 이 파일 시스템을 로컬 저장소라고 한다. 넥서스처럼 패키지별로 별도의 디렉터리로 이루어져 있다.
로컬 저장소의 디렉터리명은 .m2 이며 위치는 운영체제에 따라 약간 다르다. 윈도는 C:\Users\로그인명\.m2 이며 리눅스나 Mac OS X는 $HOME/.m2 가 된다.
원격 저장소(Remote Repository)
우리가 구성한 넥서스(nexus.example.com)처럼 메이븐이 구동되는 외부에 있는 서버는 원격저장소가 된다. 메이븐은 원격 저장소의 위치를 모르므로 명시적으로 알려주어야 한다.
이는 메이븐으로 빌드하는 프로젝트 파일(pom.xml) 에 기술하면 되며 모든 프로젝트마다 적용되게 하려면 메이븐의 로컬 저장소에 settings.xml 파일에 설정해도 된다.
중앙 저장소(Central Repository)
메이븐에 기본 설정된 저장소이다. 만약 원격 저장소를 설정하지 않았다면 로컬 저장소에 없는 아티팩트가 필요할 경우 중앙 저장소에서 받게 된다. 이는 빌드 속도를 매우 느리게 하므로 꼭 원격 저장소를 설정하여 사용하자.
URL 은 http://repo1.maven.org/maven2/ 이다.
저장소를 찾는 방법
메이븐의 세 가지 저장소 타입중 로컬 저장소와 중앙 저장소 두 개는 메이븐에 기본 설정되어 있다.
그러면 메이븐에게 어떻게 우리가 구축한 리모트 저장소를 알려줄 수 있을까?
바로 프로젝트마다 생성하는 pom.xml 에 지정하는 것이다.
pom.xml 을 버전 관리 서버에 넣으면 체크아웃 받은 모든 개발자가 설정을 공유하므로 이 방법은 모든 개발자가 공유할 수 있다.
넥서스 정보 설정
아티팩트 저장소 설정
이제 넥서스와 연동하는 메이븐 프로젝트를 위해 테스트 프로젝트를 만들어 보자. 진행할 프로젝트는 공통 라이브러리를 만드는 lib-hello 프로젝트이다.
시간 단축을 위해서 템플릿으로부터 메이븐 프로젝트를 생성하는 archetype 을 사용해 보자.
다음 명령어를 실행하면 메이븐의 프로젝트 구조에 맞게 lib-hello 라는 프로젝트 디렉터리가 생성된다.
mvn archetype:generate -B -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-quickstart -DgroupId=com.example -DartifactId=lib-hello -Dversion=1.0
성공적으로 메이븐이 실행됐다면 현재 경로에 lib-hello 라는 디렉터리가 생기고 여기에 새로운 메이븐 프로젝트가 생성됐을 것이다.
이제 프로젝트를 넥서스와 연계하도록 수정해 보자. lib-hello 폴더로 이동한 후 pom.xml 의 <project> </project> 사이에 저장소의 정보를 추가하자.
메이븐은 아티팩트와 플러그인을 다운로드 받는 설정이 각각 다르다.
<repositories> 는 아티팩트를 받아오는 저장소를 설정하며 <pluginRepositories> 는 플러그인을 받아오는 저장소이다.
설정시 주의할 점은 <pluginRepositories> 는 메이븐의 기본 플러그인 설정을 덮어 써야 하므로 id 가 반드시 central 이어야 한다.
<repository> 의 id 는 이런 제한이 없으므로 식별하기 좋은 문자열을 적어주면 되며 URL은 넥서스의 저장소 목록에서 Repository Path 컬럼의 URL 을 적어주면 된다.
이제 메이븐을 실행하면 설정한 넥서스 저장소에서 아티팩트를 다운로드 받는 것을 볼수 있다.
mvn clean package
개인화 설정
pom.xml 에 저장소를 설정하면 된다는 것을 알았으니 새로운 프로젝트가 생길 때마다 pom.xml 에 저장소를 설정해 주고 빌드하면 되지만 동일한 설정을 반복하는 것은 번거로울 수 있다.
이를 해결하기 위해서는 사내 저장소 설정같은 반복되는 설정을 개발자마다 기본 설정으로 만들고 프로젝트에서는 이것을 가져다가 사용하면 된다.
개발자별 기본 설정은 M2_HOME 환경변수에 지정된 경로에서 읽어오며 설정되지 않았을 경우 기본 로컬 저장소인 사용자의 홈 디렉터리에서 .m2/settings.xml 파일에서 읽어오게 된다.
사용자 계정명이 lesstif 일 경우 OS 별 설정 파일의 경로는 다음과 같다.
- Linux/Unix : /home/lesstif/.m2/settings.xml
- 윈도 : /Users/lesstif/.m2/settings.xml
내부 저장소 URL 처럼 프로젝트마다 공통되는 정보는 settings.xml 에 설정하는게 편리한 경우가 많다.
디플로이 하려면 아티팩트 다운로드와는 다르게 디폴로이 권한이 있어야 하므로 디플로이용 저장소에는 접근 통제가 적용되어 있다.
아이디와 암호같은 중요 정보는 pom.xml 에 넣으면 보안상 문제가 될 수 있으므로 개별 설정 파일인 settings.xml 에 설정하는 게 좋다.
디플로이 저장소 설정
프로젝트 빌드시 우리가 구축한 넥서스 서버를 통해 아티팩트를 가져오는 사용하는 방법을 알았다.
이젠 만든 아티팩트를 넥서스에 디플로이 해보자. 디플로이 하려면 메이븐에 대해서 몇 가지 더 알아야 한다.
distributionManagement
distributionManagement 는 pom.xml 에 설정하며 디플로이 하려는 저장소의 URL 을 설정한다.
짐작했듯이 디플로이 저장소는 hosted 방식의 저장소여야 한다. 넥서스에 기본 포함된 두 개의 저장소를 기억해 보자.
넥서스 관리자 화면의 저장소 목록을 클릭하여 하단의 Summary 에서 이 메이븐에 추가하기 위한 정보를 얻을 수 있다.
이제 이 정보를 복사한 후에 pom.xml 에 설정해 보자. distributionManagement 는 <project> 태그 사이에 있어야 한다.
<project> <distributionManagement> <repository> <id>releases</id> //FORMAT <url>https://nexus.example.com/content/repositories/releases</url> //FORMAT </repository> <snapshotRepository> <id>snapshots</id> //FORMAT <url>https://nexus.example.com/content/repositories/snapshots</url> //FORMAT </snapshotRepository> </distributionManagement> </project>
이제 폼 파일 설정이 끝났으므로 디플로이에 필요한 계정 정보를 settings.xml 에 설정해 보자. 위에서 설명한 repository 와 pluginRepositories 설정은 지면을 위해 제외했다.
<settings> <servers> <server> <id>releases</id> //FORMAT <username>deployment</username> <password>deployment123</password> </server> <server> <id>snapshots</id> //FORMAT <username>deployment</username> <password>deployment123</password> </server> </servers> </settings>
여기서 꼭 확인해야 할 부분은 pom.xml내 <distributionManagement> 에 지정한 id 와 <server> 에 있는 id 가 일치해야 한다는 점이다.
id가 다르면 다른 정보로 인식하여 로그인이 할 수 없으므로 디플로이가 실패한다. 디플로이가 실패시 에러 코드가 401 이라면 id 가 잘못됐거나 username 이나 password 가 잘못된 것이므로 확인한 후에 수정하자.
메이븐은 install 과 deploy 두 개의 골을 갖고 있다. install 은 로컬 저장소에 아티팩트를 올리는 명령어로 자신의 .m2 에 저장된다.
넥서스 저장소에 올리기 전 테스트 용도로 활용하면 되며 다른 개발자와 공유하려면 deploy 골을 실행하여여 한다.
이제 mvn deploy 명령을 실행하면 넥서스에 디플로이 되는 것을 확인할 수 있다.
이제 넥서스에 연결하여 다시 한 번 확인해 보자.
좌측의 검색 창에서 lib-hello 를 입력하여 아티팩트를 검색해 보면 정상 업로드 되었음을 확인할 수 있다.
소스와 자바독(javadoc) 도 같이 디플로이
아티팩트가 프로젝트에 걸쳐 공통으로 사용되는 라이브러리라면 이를 사용하는 개발자들은 가끔 라이브러리의 소스나 자바독으로 기술된 API 명세를 보아야 할 경우가 있다.
넥서스에 라이브러리를 디플로이할 때 소스와 자바 독도 같이 올리면 이클립스같은 IDE 환경을 사용하는 개발자는 코딩중에 바로 라이브러리의 소스를 보거나 자바독을 볼 수 있으므로 개발 생산성 향상에 도움이 된다.
메이븐에는 이를 처리하는 별도의 플러그인이 있으며 "maven-source-plugin" 은 아티팩트의 소스를 패키징해 주고 "maven-javadoc-plugin" 은 자바독 파일을 패키징해 준다,
pom.xml 내의 build 항목에 아래와 같이 플러그인을 설정해 주고 페이즈(phase)를 연결 해 주면 mvn deploy 명령어 실행시 소스와 자바독도 같이 디플로이 한다.
<build> <plugins> <plugin> <artifactId>maven-source-plugin</artifactId> <version>2.3</version> <executions> <execution> <id>attach-sources</id> <phase>verify</phase> <goals> <goal>jar</goal> </goals> </execution> </executions> </plugin> <plugin> <artifactId>maven-javadoc-plugin</artifactId> <version>2.9.1</version> <executions> <execution> <id>attach-javadocs</id> <phase>verify</phase> <goals> <goal>jar</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
디플로이 에러 처리
mvn deploy 시 가장 많이 나는 에러 코드는 401과 400 이다. 401은 위에서 설명했고 400 은 이미 아티팩트가 디플로이 되어서 발생한다.
이 에러를 해결하려면 아티팩트의 버전을 변경해서 다시 디플로이를 수행하면 해결된다.
버전을 바꾸고 싶지 않다면 해당 저장소의 설정에서 Redeploy Policy 를 Allow 로 변경하고 디플로이 하거나 아니면 넥서스의 실제 저장소의 파일 시스템에서 아티팩트를 직접 삭제해야 한다.