pom.xml 에 여러 개의 dependency 설정을 했을 때 각 라이브러리가 참조하는 라이브러리 중 버전이 충돌하는 경우가 있다.
예를 들어 다음과 같이 hystrix-core 라이브러리는 commons-logging 1.1.1 버전을 참조하고 있고
httpcomponents 라이브러리는 commons-logging 1.2 버전을 참조한다.
1 2 | hystrix-core -> commons-logging:1.1.1 httpcomponents -> commons-logging:1.2 | cs |
이처럼 두 개의 서로 다른 버전을 참조하고 있을 때 maven은 root 레벨과 가장 가까운 라이브러리를 선택하게 된다.
이게 무슨 의미냐 하면
mvn dependency:tree 명령을 치면 pom.xml 에 선언되어 있는 의존성 라이브러리들의 트리 구조를 확인할 수 있다.
pom.xml 자신이 root 라고 했을 때 그 안에 선언되어 있는 dependency 들이 트리 구조로 보여진다.
즉, <dependencies> </dependencies> 안에서 가장 위에 있는 <dependency> 가 root 와 가장 가까운 라이브러리라 할 수 있는 것이다.
아래 두 개의 라이브러리가 선언되어 있을 때 해당 프로젝트에서는 commons-logging:1.2 버전이 사용되어 진다. (httpclient 라이브러리가 root 와 가깝기 때문)
1 2 3 4 5 6 7 8 9 10 11 | <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5</version> </dependency> <dependency> <groupId>com.netflix.hystrix</groupId> <artifactId>hystrix-core</artifactId> <version>1.4.4</version> </dependency> | cs |
이와같이 버전 충돌시 메이븐 버전 전략에 의존하는 것이 아닌 내가 직접 제어하고 싶은 경우가 있다.
개발자가 직접 해결하는 방법에 대해서 작성해 본다.
1.
maven-enforcer-plugin 설정
pom.xml 파일에 아래 플러그인을 추가한다.
maven-enforcer-plugin 은 버전 충돌이 발생하는 라이브러리를 출력해 준다.
1 2 3 4 5 6 7 8 9 10 11 | <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-enforcer-plugin</artifactId> <version>1.4.1</version> <configuration> <rules> <dependencyConvergence/> </rules> </configuration> </plugin> | cs |
위의 플러그인 설정 후 다음의 명령어를 실행해 보자.
1 | mvn enforcer:enforce | cs |
pom.xml 에 버전 충돌이 발생하는 라이브러리가 있다면 다음과 같이 출력될 것이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | [WARNING] Dependency convergence error for commons-logging:commons-logging:1.1.1 paths to dependency are: +-test_project:test_project:0.0.1-SNAPSHOT +-com.netflix.hystrix:hystrix-core:1.4.4 +-com.netflix.archaius:archaius-core:0.4.1 +-commons-configuration:commons-configuration:1.8 +-commons-logging:commons-logging:1.1.1 and +-test_project:test_project:0.0.1-SNAPSHOT +-org.apache.pdfbox:pdfbox:1.8.10 +-org.apache.pdfbox:fontbox:1.8.10 +-commons-logging:commons-logging:1.1.1 and +-test_project:test_project:0.0.1-SNAPSHOT +-org.apache.pdfbox:pdfbox:1.8.10 +-commons-logging:commons-logging:1.1.1 and +-test_project:test_project:0.0.1-SNAPSHOT +-org.apache.httpcomponents:httpclient:4.5 +-commons-logging:commons-logging:1.2 and +-test_project:test_project:0.0.1-SNAPSHOT +-org.apache.httpcomponents:fluent-hc:4.5 +-commons-logging:commons-logging:1.2 | cs |
프로젝트 내에서 충돌이 발생하는 라이브러리들을 알았으니 이를 해결하기 위한 방법을 알아보자.
2.
해결 방법
가장 쉽게 해결할 수 있는 방법은 exclusion을 버전이 충돌하는 라이브러리에 추가해 주는 것이다.
그럼 hystrix-core는 commons-logging:1.1.1 버전이 아닌 commons-logging:1.2 버전을 사용하게 될 것이다.
1 2 3 4 5 6 7 8 9 10 11 | <dependency> <groupId>com.netflix.hystrix</groupId> <artifactId>hystrix-core</artifactId> <version>1.4.4</version> <exclusions> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions> </dependency> | cs |
허나 난 다른 방법으로 버전 충돌을 해결한다.
일단 충돌이 나는 라이브러리를 모두 추출하고, 충돌나는 라이브러리 중 어떤 버전을 사용할지 결정한다.
commons-logging:1.2, commons-logging:1.1 두 개가 있다고 했을 때 commons-logging:1.2 사용 결정
결정이 되면 다음과 같이 주석으로 충돌이 발생하는 라이브러리라고 표기하고 그 아래에 의존성 라이브러리를 추가한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <!-- ==================================================== --> <!-- dependency conflict library --> <!-- ==================================================== --> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>18.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.8.7</version> </dependency> <dependency> <groupId>joda-time</groupId> <artifactId>joda-time</artifactId> <version>2.9.7</version> </dependency> | cs |
마지막으로 충돌이 발생하는 라이브러리에 exclusion을 추가한다.
이와 같이 하면 dependency conflict library 주석 하위에 선언한 라이브러리를 참조하게 될 것이다.
1 2 3 4 5 6 7 8 9 10 | <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> <exclusions> <exclusion> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> </exclusion> </exclusions> </dependency> | cs |
결론은 충돌이 발생하는 라이브러리들이 있다면 충돌이 발생하는 라이브러리를 명시적으로 작성한다.
그리고 선언한 라이브러리들을 사용할 수 있게 충돌이 발생하는 구간에 exclusion 옵션을 추가해 주는 것이다.
'개발툴' 카테고리의 다른 글
jenkins 빌드에서 github action 빌드 배포로 이전 (0) | 2024.08.20 |
---|---|
시놀로지 NAS에 웹 서버 배포 및 운영 (0) | 2024.05.23 |
maven effective pom 활용 (0) | 2019.08.23 |
Fiddler Filter 기능에 대해서 알아보자 (3) | 2019.04.03 |
윈도우 loopback 패킷 캡쳐 (RawCap) (0) | 2017.12.11 |
Maven 용어 정리 (0) | 2017.10.16 |
vagrant 구동 시 오류 (Your VM has become inaccessible) (0) | 2017.10.13 |
Microsoft SQL Server Management Studio - 서버 정보 저장하기 (0) | 2017.09.22 |