본문 바로가기

Maven

#5. 메이븐을 이용한 의존 라이브러리 관리

기존 의존 관계 라이브러리를 추가해야 하는 경우



메이븐의 의존 라이브러리 관리


메이븐의 핵심 기능 중 하나이다. 하지만, 우리가 프로젝트를 진행하면서 가장 문제를 많이 일으키는 부분이기도 하다. 즉, 이 부분을 제대로 이해해야 발생한 이슈들을 쉽게 해결할 수 있다.


메이븐 저장소

  1. 중앙 저장소 : 오픈 소스 라이브러리, 메이븐 플러그인을 관리하는 저장소 ( 개발자가 임의로 라이브러리 배포 불가 )
  2. 사내 원격 저장소 : 메이븐 기반으로 프로젝트를 진행하는 경우 모든 라이브러리가 중앙 저장소에 있는게 아니다.
                   이처럼 중앙 저장소에 없는 라이브러리를 한 곳에 모아두기 위하여 별도의 메이븐 저장소를 설치해 관리하는 것이 가능
  3. 로컬 저장소 : 메이븐을 빌드할 때 다운받은 라이브러리를 관리하는 개발자 PC의 저장소 ( USER_HOME/.m2/repository )


메이븐 저장소 설정


 우리 프로젝트에서 사용하고 있는 저장소들이다. 중앙 저장소(http://repo1.maven.org/maven2)에서 제공하지 않는 라이브러리를 위한 저장소도 명시를 해놓았다.  


위의 개념과 관련 된 이슈다. 이클립스 Mars -> Neon으로 업데이트를 하면서 저장소에 xtext 예전 버전이 없어 생긴 문제이다.


메이븐 의존 라이브러리 관리


  •  로컬 저장소에 jar가 다운받아지는 과정
    메이븐 중앙 저장소에 접근하여 groudId/artifactId/version에 있는 ${artifactId}-${version}.jar 파일을 메이븐 로컬 저장소에 다운로드

  • pom.xml에 dependency만 명시하면 좋은점

    1) 기존처럼 일일히 다운 안받아도 됨
    2) GIT에 라이브러리를 공유하지 않아 소스 코드의 크기가 작아짐

  • 라이브러리 검색 방법
    http://mvnrepository.com 에서 검색 지원

프로젝트에 의존 라이브러리 추가하기


기존처럼 프로젝트 내에서 라이브러리를 확인하려면 어떻게 해야할까? 


의존 관계로 설정한 라이브러리를 프로젝트로 복사해주는 dependency 플러그인이 있다.


 이 상태로 빌드를 해보면 내가 설정한 의존 관계 라이브러리 수보다 많은 라이브러리들이 lib 폴더에 추가된 것을 확인할 수 있다. 

분명 메이븐에서 추가적인 기능을 제공해주고 있는 것이다. 


의존성 전이


[프로젝트를 개발할 때 외부 라이브러리와의 의존관계를 나타낸 그림]


문제 

위의 그림처럼 외부 라이브러리를 추가하는 경우 거기에 따라오는 또 다른 외부 라이브러리를 추가해야 한다. 이는 결과적으로 메이븐 설정 파일의 복잡도를 증가시킨다. 


해결

메이븐 2.0부터 의존성 전이 기능을 제공해준다. 즉, 자기가 필요한 라이브러리는 자기가 알아서 받자는 것이다.


하지만 의존성 전이 기능 때문에 불필요한 라이브러리가 추가되거나 의도하지 않은 라이브러리와 의존관계를 갖는 경우가 발생한다.


의존성 전이에 대한 설정


  • 의존성 중개 ( Dependency mediation )
    상황 : A->B->C->D 2.0버전, A->E->D 1.0버전 의 의존관계를 가지고 있음
    결과 : 더 가까운 의존관계 있는 pom 설정을 참고한다. 즉, D 1.0버전을 가지게 된다.
    해결 : A 프로젝트의 메이븐 설정 파일에 명확하게 의존 관계를 명시한다.(밑에 내용)

  • 의존성 관리 ( Dependency management )
    <dependencyManagement/> 엘리먼트에서 버전을 명시적으로 정의한다. ( #12 글 참고 )

  • 의존성 스코트 ( Dependency scope )
    현재 빌드 상태에 맞는 라이브러리인 경우 의존 관계를 가진다. (classpath에도 종류가 있다 compile classpath, runtime classpath ) 예를 들어 test 스코프를 가지는 경우 최종 배포 산출물을 빌드하는 시점에는 포함되지 않는다.


    => TOP IDE에서는 scope를 지정하지 않아 모든 플러그인이 포함된다.

    - compile : 기본 scope, 컴파일 할 때 필요함
    - runtime : application runtime에 필요한 class
                   library를 compile classpath에만 추가하고, runtime classpath에 추가하는 것을 까먹은 경우 => NoClassDefFoundError 발생
    - test : test할때만 필요
    - provided : 이 옵션은 compile과 매우 비슷하지만, 실행시 의존관계를 제공하는 JDK나 Web Container(tomcat 같은)에 대해서 적용된다.  예를 들어             Java Enterprise Edition Web application을 개발할때 Servlet API나 Java EE API들은 "provided" scope로 지정해야한다. 왜냐하면 Servlet             API 같은 경우는 Servlet Container 자체에서 지원해 주기 때문에(Tomcat 같은 경우는 ${tomcat home directory}/lib 디렉토리에 있는 Servlet             라이브러리를 사용) 컴파일시 또는 테스트시에는 필요하지만 실행시에는 필요하지 않기 때문이다.


  • - a->b compile ( 좌측 ) 이고, b->c test ( 위 ) 이면 a->c는 아무런 의존성이 없음
    - a->b test 이고, b->c compile 이면 a->c는 test 

  • 의존성 예외 ( Excluded dependencies )
    의존 관계에 있는 라이브러리를 <exclusion/>을 활용하여 명시적으로 제외시킬 수 있다.
  • 선택적 의존성 ( Optional dependencies )
    상황 : A->B->C 의존관계를 가지는 경우 B프로젝트에 C가 optional로 설정
    결과 : A 프로젝트를 빌드할 때 C는 의존관계를 가지지 않음. ( <optional/> )

속성 - 중복 설정 제거


  • pom.xml의 properties 사용
  • setting.xml에서 사용할 속성 ( 로컬 저장소 경로 )
  • 환경 변수 속성 : evn 접두사를 이용한 시스템 환경 변수 값 참조
  • 자바 시스템 속성


'Maven' 카테고리의 다른 글

#3. 메이븐 설정 파일  (0) 2017.10.25
#1. 이상적인 개발 환경  (0) 2017.10.25
#6. 메이븐과 이클립스 통합  (0) 2017.10.24
Error 모음  (0) 2017.03.18
Maven 기본  (0) 2017.03.10