이 페이지의 이전 버전을 보고 있습니다. 현재 버전 보기.

현재와 비교 페이지 이력 보기

« 이전 버전 5 다음 »

고수와 하수를 구분하는 Dependency Management

Maven을 좀 안다고 자랑하려면 Maven Dependency Management에 대한 깊은 이해 및 문제해결 능력을 갖추고 있어야 합니다.

Dependency의 속성 및 정의

Maven POM에 dependency를 추가할 때 다음과 같은 형식으로 추가합니다.

<dependency>
    <groupId>group-a</groupId>
    <artifactId>artifact-b</artifactId>
    <version>1.0</version>
    <type>bar</type>
    <scope>runtime</scope>
</dependency>

dependency의 각 속성은 다음과 같으며 좀더 상세한 설명은 Maven 페이지를 참고하십시오.

속성설명필수
Group ID

Java의 패키지와 같은 개념

Artifact의 그룹

O
Artifact ID

Artifact의 식별자

Artifact 유형이 여러 가지가 있지만 대표적으로 .jar .war .ear 등이 있음

Artifact는 소스코드와 JavaDoc이 같이 포함될 수 있음

O
VersionArtifact의 버전 정보O
TypeArtifact의 유형X
Scope

Artifact의 적용 범위 (test, runtime, compile, provided, import, system 등 다양한 범위가 있음)

  • compile이 기본값(모든 classpath에 적용)
  • test는 테스트 코드 컴파일 및 테스트 실행에만 적용하라는 의미
  • runtime은 실행시에만 적용하라는 의미(컴파일에는 필요하지 않음)
  • provided는 컴파일할때에는 적용이 되지만 패키징할 때에는 빠짐
  • system은 repository에서 찾지 않으며 별도로 <systemPath> 를 추가하고 .jar 파일의 경로를 추가해야 함
X
ClassifierArtifact에 여러 개의 식별자를 두고 싶을 때 사용X
System PathScope가 system인 경우 <systemPath> 를 추가해야 함X

Local Repository에는 어떻게 저장되나?

Local Repository에 dependency를 저장할 때에는 Group ID, Artifact ID, Version에 따라서 다음과 같이 저장합니다.

├── antlr                                               >> Group ID : antlr
    └── antlr                                           >> Artifact ID : antlr
        ├── 2.7.2                                       >> Version : 2.7.2
        │   ├── _remote.repositories
        │   ├── antlr-2.7.2.jar
        │   ├── antlr-2.7.2.jar.sha1
        │   ├── antlr-2.7.2.pom
        │   └── antlr-2.7.2.pom.sha1
        └── 2.7.7
            ├── _remote.repositories
            ├── antlr-2.7.7-sources.jar.lastUpdated
            ├── antlr-2.7.7.jar
            ├── antlr-2.7.7.jar.sha1
            ├── antlr-2.7.7.pom
            └── antlr-2.7.7.pom.sha1

├── ch
    └── qos
        └── logback                                     >> Group ID : ch.qos.logback
            └── logback-classic                         >> Artifact ID : logback-classic
                └── 1.2.3                               >> Version : 1.2.3
                    ├── _remote.repositories
                    ├── logback-classic-1.2.3-sources.jar
                    ├── logback-classic-1.2.3-sources.jar.sha1
                    ├── logback-classic-1.2.3.jar
                    ├── logback-classic-1.2.3.jar.sha1
                    ├── logback-classic-1.2.3.pom
                    └── logback-classic-1.2.3.pom.sha1

Dependency Graph로 의존성 확인하기

Maven Dependency의 의존 구조

다음은 Maven POM의 dependency를 구조화한 도식입니다. 프로젝트에 dependency를 추가하는 경우 추가한 dependency는 또다른 dependency를 참조하고 있습니다. 대규모 프로젝트의 경우 굉장히 복잡한 구조를 가지고 있습니다.

복잡한 dependency 구조를 갖는 프로젝트를 빌드하고 다른 프로젝트에서 이 결과물을 다시 활용하면 다시 복잡한 dependency 구조를 또 갖게 됩니다. 따라서 될 수 있으면 dependency의 구조를 간단하게 가지고 가는 것이 좋습니다.

IntelliJ IDEA에서 Dependency Graph 확인하기

IntelliJ IDEA에서 pom.xml 파일을 오픈한 상태에서 편집기로 마우스를 이동한 후 마우스 오른쪽 버튼을 눌러 다음과 같이 Show Dependencies... 메뉴를 클릭합니다.

그러면 다음과 같이 pom.xml 파일에 정의되어 있는 모든 dependency에 대해서 의존성 그래프가 그려집니다.

Maven의 Dependency Plugin을 이용하여 의존성 그래프 확인하기

Maven의 dependency plugin에는 의존성 그래프를 트리 형식으로 보여주는 기능을 제공하는 goal(tree)가 있습니다. 그렇다면 이 그래프를 왜 확인해야 하나요? 답은 dependency의 충돌(conflict) 문제를 해결하기 위해서 입니다. 

# mvn dependency:tree
[INFO] Scanning for projects...
[INFO] 
[INFO] -------------< org.springframework.boot:spring-boot-ldap >--------------
[INFO] Building Spring Boot LDAP Sample 2.2.6.RELEASE
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-dependency-plugin:3.1.2:tree (default-cli) @ spring-boot-ldap ---
[INFO] org.springframework.boot:spring-boot-ldap:jar:2.2.6.RELEASE
[INFO] +- org.springframework.boot:spring-boot-starter-web:jar:2.2.6.RELEASE:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter:jar:2.2.6.RELEASE:compile
[INFO] |  |  +- org.springframework.boot:spring-boot:jar:2.2.6.RELEASE:compile
[INFO] |  |  +- org.springframework.boot:spring-boot-autoconfigure:jar:2.2.6.RELEASE:compile
[INFO] |  |  +- org.springframework.boot:spring-boot-starter-logging:jar:2.2.6.RELEASE:compile
[INFO] |  |  |  +- ch.qos.logback:logback-classic:jar:1.2.3:compile
[INFO] |  |  |  |  \- ch.qos.logback:logback-core:jar:1.2.3:compile
[INFO] |  |  |  +- org.apache.logging.log4j:log4j-to-slf4j:jar:2.12.1:compile
[INFO] |  |  |  |  \- org.apache.logging.log4j:log4j-api:jar:2.12.1:compile
[INFO] |  |  |  \- org.slf4j:jul-to-slf4j:jar:1.7.30:compile
[INFO] |  |  \- org.yaml:snakeyaml:jar:1.25:runtime
[INFO] |  +- org.springframework.boot:spring-boot-starter-json:jar:2.2.6.RELEASE:compile
[INFO] |  |  +- com.fasterxml.jackson.core:jackson-databind:jar:2.10.3:compile
[INFO] |  |  |  +- com.fasterxml.jackson.core:jackson-annotations:jar:2.10.3:compile
[INFO] |  |  |  \- com.fasterxml.jackson.core:jackson-core:jar:2.10.3:compile
[INFO] |  |  +- com.fasterxml.jackson.datatype:jackson-datatype-jdk8:jar:2.10.3:compile
[INFO] |  |  +- com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:2.10.3:compile
[INFO] |  |  \- com.fasterxml.jackson.module:jackson-module-parameter-names:jar:2.10.3:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter-validation:jar:2.2.6.RELEASE:compile
[INFO] |  |  +- jakarta.validation:jakarta.validation-api:jar:2.0.2:compile
[INFO] |  |  \- org.hibernate.validator:hibernate-validator:jar:6.0.18.Final:compile
[INFO] |  |     +- org.jboss.logging:jboss-logging:jar:3.4.1.Final:compile
[INFO] |  |     \- com.fasterxml:classmate:jar:1.5.1:compile
[INFO] |  +- org.springframework:spring-web:jar:5.2.5.RELEASE:compile
[INFO] |  \- org.springframework:spring-webmvc:jar:5.2.5.RELEASE:compile
[INFO] |     \- org.springframework:spring-expression:jar:5.2.5.RELEASE:compile
[INFO] +- javax.servlet:jstl:jar:1.2:compile
[INFO] +- org.springframework.data:spring-data-ldap:jar:2.2.6.RELEASE:compile
[INFO] |  +- org.springframework:spring-context:jar:5.2.5.RELEASE:compile
[INFO] |  +- org.springframework.ldap:spring-ldap-core:jar:2.3.2.RELEASE:compile
[INFO] |  +- org.springframework.data:spring-data-commons:jar:2.2.6.RELEASE:compile
[INFO] |  \- org.slf4j:slf4j-api:jar:1.7.30:compile
[INFO] +- org.springframework.data:spring-data-jpa:jar:2.2.6.RELEASE:compile
[INFO] |  +- org.springframework:spring-orm:jar:5.2.5.RELEASE:compile
[INFO] |  +- org.springframework:spring-aop:jar:5.2.5.RELEASE:compile
[INFO] |  +- org.springframework:spring-tx:jar:5.2.5.RELEASE:compile
[INFO] |  +- org.springframework:spring-beans:jar:5.2.5.RELEASE:compile
[INFO] |  +- org.springframework:spring-core:jar:5.2.5.RELEASE:compile
[INFO] |  |  \- org.springframework:spring-jcl:jar:5.2.5.RELEASE:compile
[INFO] |  \- org.aspectj:aspectjrt:jar:1.9.5:compile
[INFO] +- org.apache.directory.server:apacheds-core:jar:1.5.7:test
[INFO] |  +- org.apache.directory.server:apacheds-i18n:jar:1.5.7:test
[INFO] |  +- org.apache.directory.server:apacheds-core-api:jar:1.5.7:test
[INFO] |  |  \- org.apache.directory.server:apacheds-core-constants:jar:1.5.7:test
[INFO] |  +- org.apache.directory.server:apacheds-utils:jar:1.5.7:test
[INFO] |  +- bouncycastle:bcprov-jdk15:jar:140:test
[INFO] |  +- org.apache.directory.shared:shared-ldap:jar:0.9.19:test
[INFO] |  |  +- commons-collections:commons-collections:jar:3.2.1:test
[INFO] |  |  +- org.apache.directory.shared:shared-i18n:jar:0.9.19:test
[INFO] |  |  \- antlr:antlr:jar:2.7.7:test
[INFO] |  +- org.apache.directory.shared:shared-ldap-schema:jar:0.9.19:test
[INFO] |  +- org.apache.directory.shared:shared-ldap-schema-loader:jar:0.9.19:test
[INFO] |  +- org.apache.directory.shared:shared-ldap-schema-manager:jar:0.9.19:test
[INFO] |  +- org.apache.directory.shared:shared-cursor:jar:0.9.19:test
[INFO] |  +- org.apache.directory.shared:shared-ldap-jndi:jar:0.9.19:test
[INFO] |  +- org.apache.directory.shared:shared-asn1-codec:jar:0.9.19:test
[INFO] |  +- org.apache.directory.shared:shared-asn1:jar:0.9.19:test
[INFO] |  +- org.apache.directory.shared:shared-ldap-constants:jar:0.9.19:test
[INFO] |  +- org.apache.directory.shared:shared-ldap-converter:jar:0.9.19:test
[INFO] |  +- org.apache.directory.shared:shared-ldap-schema-dao:jar:0.9.19:test
[INFO] |  +- org.apache.directory.shared:shared-ldif:jar:0.9.19:test
[INFO] |  \- org.apache.directory.shared:shared-dsml-parser:jar:0.9.19:test
[INFO] |     +- dom4j:dom4j:jar:1.6.1:test
[INFO] |     |  \- xml-apis:xml-apis:jar:1.0.b2:test
[INFO] |     \- xpp3:xpp3:jar:1.1.4c:test
[INFO] +- org.apache.directory.server:apacheds-core-entry:jar:1.5.7:test
[INFO] +- org.apache.directory.server:apacheds-protocol-shared:jar:1.5.7:test
[INFO] |  \- org.apache.mina:mina-core:jar:2.0.0-RC1:test
[INFO] +- org.apache.directory.server:apacheds-protocol-ldap:jar:1.5.7:test
[INFO] |  +- org.apache.directory.server:apacheds-kerberos-shared:jar:1.5.7:test
[INFO] |  |  \- org.apache.directory.server:apacheds-core-jndi:jar:1.5.7:test
[INFO] |  \- org.apache.directory.server:apacheds-xdbm-tools:jar:1.5.7:test
[INFO] |     \- org.apache.directory.server:apacheds-xdbm-base:jar:1.5.7:test
[INFO] +- org.apache.directory.server:apacheds-server-jndi:jar:1.5.7:test
[INFO] |  +- org.apache.directory.server:apacheds-ldif-partition:jar:1.5.7:test
[INFO] |  |  +- org.apache.directory.server:apacheds-avl-partition:jar:1.5.7:test
[INFO] |  |  |  \- org.apache.directory.server:apacheds-core-avl:jar:1.5.7:test
[INFO] |  |  \- org.apache.directory.server:apacheds-core-mock:jar:1.5.7:test
[INFO] |  \- org.apache.directory.server:apacheds-jdbm-partition:jar:1.5.7:test
[INFO] |     +- org.apache.directory.server:apacheds-jdbm-store:jar:1.5.7:test
[INFO] |     |  \- org.apache.directory.server:apacheds-jdbm:jar:1.5.7:test
[INFO] |     \- org.apache.directory.server:apacheds-xdbm-search:jar:1.5.7:test
[INFO] +- org.springframework.boot:spring-boot-starter-tomcat:jar:2.2.6.RELEASE:provided
[INFO] |  +- jakarta.annotation:jakarta.annotation-api:jar:1.3.5:compile
[INFO] |  +- org.apache.tomcat.embed:tomcat-embed-core:jar:9.0.33:provided
[INFO] |  +- org.apache.tomcat.embed:tomcat-embed-el:jar:9.0.33:provided
[INFO] |  \- org.apache.tomcat.embed:tomcat-embed-websocket:jar:9.0.33:provided
[INFO] +- org.apache.tomcat.embed:tomcat-embed-jasper:jar:9.0.33:provided
[INFO] |  \- org.eclipse.jdt:ecj:jar:3.18.0:provided
[INFO] +- org.springframework.session:spring-session-jdbc:jar:2.2.2.RELEASE:compile
[INFO] |  +- org.springframework.session:spring-session-core:jar:2.2.2.RELEASE:compile
[INFO] |  \- org.springframework:spring-jdbc:jar:5.2.5.RELEASE:compile
[INFO] +- org.springframework.boot:spring-boot-starter-jdbc:jar:2.2.6.RELEASE:compile
[INFO] |  \- com.zaxxer:HikariCP:jar:3.4.2:compile
[INFO] +- com.h2database:h2:jar:1.4.200:compile
[INFO] +- org.springframework.boot:spring-boot-starter-test:jar:2.2.6.RELEASE:test
[INFO] |  +- org.springframework.boot:spring-boot-test:jar:2.2.6.RELEASE:test
[INFO] |  +- org.springframework.boot:spring-boot-test-autoconfigure:jar:2.2.6.RELEASE:test
[INFO] |  +- com.jayway.jsonpath:json-path:jar:2.4.0:test
[INFO] |  |  \- net.minidev:json-smart:jar:2.3:test
[INFO] |  |     \- net.minidev:accessors-smart:jar:1.2:test
[INFO] |  |        \- org.ow2.asm:asm:jar:5.0.4:test
[INFO] |  +- jakarta.xml.bind:jakarta.xml.bind-api:jar:2.3.3:test
[INFO] |  |  \- jakarta.activation:jakarta.activation-api:jar:1.2.2:test
[INFO] |  +- org.junit.jupiter:junit-jupiter:jar:5.5.2:test
[INFO] |  |  +- org.junit.jupiter:junit-jupiter-api:jar:5.5.2:test
[INFO] |  |  |  +- org.opentest4j:opentest4j:jar:1.2.0:test
[INFO] |  |  |  \- org.junit.platform:junit-platform-commons:jar:1.5.2:test
[INFO] |  |  +- org.junit.jupiter:junit-jupiter-params:jar:5.5.2:test
[INFO] |  |  \- org.junit.jupiter:junit-jupiter-engine:jar:5.5.2:test
[INFO] |  +- org.junit.vintage:junit-vintage-engine:jar:5.5.2:test
[INFO] |  |  +- org.apiguardian:apiguardian-api:jar:1.1.0:test
[INFO] |  |  +- org.junit.platform:junit-platform-engine:jar:1.5.2:test
[INFO] |  |  \- junit:junit:jar:4.12:test
[INFO] |  +- org.mockito:mockito-junit-jupiter:jar:3.1.0:test
[INFO] |  +- org.assertj:assertj-core:jar:3.13.2:test
[INFO] |  +- org.hamcrest:hamcrest:jar:2.1:test
[INFO] |  +- org.mockito:mockito-core:jar:3.1.0:test
[INFO] |  |  +- net.bytebuddy:byte-buddy:jar:1.10.8:test
[INFO] |  |  +- net.bytebuddy:byte-buddy-agent:jar:1.10.8:test
[INFO] |  |  \- org.objenesis:objenesis:jar:2.6:test
[INFO] |  +- org.skyscreamer:jsonassert:jar:1.5.0:test
[INFO] |  |  \- com.vaadin.external.google:android-json:jar:0.0.20131108.vaadin1:test
[INFO] |  +- org.springframework:spring-test:jar:5.2.5.RELEASE:test
[INFO] |  \- org.xmlunit:xmlunit-core:jar:2.6.4:test
[INFO] \- org.springframework.ldap:spring-ldap-test:jar:2.3.2.RELEASE:test
[INFO]    +- com.google.code.typica:typica:jar:1.3:test
[INFO]    |  +- commons-httpclient:commons-httpclient:jar:3.1:test
[INFO]    |  \- commons-codec:commons-codec:jar:1.13:test
[INFO]    +- commons-io:commons-io:jar:2.4:test
[INFO]    +- commons-lang:commons-lang:jar:2.6:test
[INFO]    +- javax.activation:activation:jar:1.1:test
[INFO]    \- org.springframework.ldap:spring-ldap-ldif-core:jar:2.3.2.RELEASE:test
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  1.953 s
[INFO] Finished at: 2020-04-20T01:54:58+09:00
[INFO] ------------------------------------------------------------------------

Dependency의 충돌

Dependency가 언제 충돌하나?

다음은 dependency의 충돌 사례입니다. 프로젝트에서 POM에 dependency를 추가했을 때 추가한 dependency가 다른 dependency를 활용하게 되는데 이때 다음과 같이 버전간의 문제가 발생할 수 있습니다. 

버전에 따라서 메소드가 추가 또는 삭제가 될 수 있고, 메소드의 signature가 변경될 수도 있습니다. 이 경우 빌드나 컴파일시 에러가 발생할 수 있습니다. Maven 초보자의 경우 이렇게 발생하는 충돌 문제를 해결하는 것이 쉽지 않습니다. 하수와 고수의 차이가 바로 이 충돌 문제의 해결 능력에 달려있다고 해도 과언이 아닙니다.

어떻게 충돌 문제를 해결할 수 있을까?





  • 레이블 없음