2017-02-09 9 views
4

종속성 목록을 계산할 때 maven dependency plugin이 잘못되었다고 생각합니다.maven dependency plugin은 의존성 버전을 무시합니까?

<?xml version="1.0" encoding="UTF-8"?>                                
<project> 
    <modelVersion>4.0.0</modelVersion> 
    <groupId>mygroup</groupId> 
    <artifactId>combined</artifactId> 
    <version>1.0-SNAPSHOT</version> 
    <packaging>jar</packaging> 

    <dependencies> 
     <dependency> 
     <groupId>mygroup</groupId> 
     <artifactId>base1</artifactId> 
     <version>1.0-SNAPSHOT</version> 
     </dependency> 
     <dependency> 
     <groupId>mygroup</groupId> 
     <artifactId>base2</artifactId> 
     <version>1.0-SNAPSHOT</version> 
     </dependency> 
    </dependencies> 
</project> 

모두, base1 및 base2가 몬즈 랭에 따라 달라

base1 :

<?xml version="1.0" encoding="UTF-8"?>                                
<project> 
    <modelVersion>4.0.0</modelVersion> 
    <groupId>mygroup</groupId> 
    <artifactId>base1</artifactId> 
    <version>1.0-SNAPSHOT</version> 
    <packaging>jar</packaging> 

    <dependencies> 
     <dependency> 
     <groupId>commons-lang</groupId> 
     <artifactId>commons-lang</artifactId> 
     <version>2.3</version> 
     </dependency> 
    </dependencies> 
</project> 

base2 : 결합

<?xml version="1.0" encoding="UTF-8"?>                                
<project> 
    <modelVersion>4.0.0</modelVersion> 
    <groupId>mygroup</groupId> 
    <artifactId>base2</artifactId> 
    <version>1.0-SNAPSHOT</version> 
    <packaging>jar</packaging> 

    <dependencies> 
     <dependency> 
     <groupId>commons-lang</groupId> 
     <artifactId>commons-lang</artifactId> 
     <version>2.6</version> 
     </dependency> 
    </dependencies> 
</project> 

이 3 개 프로젝트 가정 , 그러나 각각 다른 버전! 결합은 base1과 base2에 따라 다릅니다.

mvn dependency:list을 호출하면 두 버전이 모두 사용되므로 버전 2.3과 2.6에서 base1, base2 및 commons-lang이 표시 될 것으로 예상됩니다. 실제 출력은 그러나 :

[INFO] The following files have been resolved: 
[INFO] commons-lang:commons-lang:jar:2.3:compile 
[INFO] mygroup:base1:jar:1.0-SNAPSHOT:compile 
[INFO] mygroup:base2:jar:1.0-SNAPSHOT:compile 

그것도 가장 높은 버전 번호와 공통 LANG을 사용하지 않고, 단지 하나가 처음 발견한다.

어떻게 이것을 피할 수 있습니까? 모든 의존성이 필요해.

+0

commons-lang에 의존해야하는 코드를 변경하는 것이 가장 좋습니다. 2.3. 죄송합니다 ... – otonglet

+0

@otonglet base1과 base2가 타사 모듈 인 경우이를 수행 할 수 없습니다. – radlan

+0

@radlan'mvn dependency : list'와 ['mvn dependency : tree'] (https://maven.apache.org/plugins/maven-dependency-plugin/tree-mojo.html)을 혼동하는 것입니까? – nullpointer

답변

3

따르면

종속성 조정 - 여러 버전의 이슈가 발생하는 경우 어떤 버전의 종속성이 사용되는지 결정합니다. 현재, Maven 2.0은 의존성 트리에서 프로젝트에 가장 가까운 의존성 버전을 사용할 것을 의미하는 "가장 가까운 정의"만을 지원합니다. 프로젝트의 POM에서 명시 적으로 선언하여 버전을 보증 할 수 있습니다. 종속성 트리에서 두 개의 종속성 버전이 동일한 깊이에있는 경우 Maven 2.0.8까지는 어느 것이 승리할지 정의되지 않았지만 Maven 2.0.9 이후로는 개수가 포함 된 선언의 순서가됩니다. 첫 번째 선언이 우선합니다 .

따라서 Maven은 종속성 해결 프로세스에서 처음으로 발생하기 때문에 버전 2.3을 선택합니다.combined 모듈에서 mvn dependency:tree을 실행하면 사용 된 버전과 생략 된 버전이 표시됩니다.

가장 좋은 방법은 명시 적으로 그 POM에 의존성을 선언함으로써 당신은 combined 유물에서 원하는 버전을 선택하는 것입니다 때문에 Maven은 다른 버전 이상이 찬성하는 :

<?xml version="1.0" encoding="UTF-8"?> 
<project> 
    <modelVersion>4.0.0</modelVersion> 
    <groupId>mygroup</groupId> 
    <artifactId>combined</artifactId> 
    <version>1.0-SNAPSHOT</version> 
    <packaging>jar</packaging> 

    <dependencies> 
    <dependency> 
     <groupId>mygroup</groupId> 
     <artifactId>base1</artifactId> 
     <version>1.0-SNAPSHOT</version> 
    </dependency> 
    <dependency> 
     <groupId>mygroup</groupId> 
     <artifactId>base2</artifactId> 
     <version>1.0-SNAPSHOT</version> 
    </dependency> 
    <dependency> <!-- This will override the versions in base1 and base2 --> 
     <groupId>commons-lang</groupId> 
     <artifactId>commons-lang</artifactId> 
     <version>2.6</version> 
    </dependency> 
    </dependencies> 

참고 메이븐 이 경우에는 프로젝트 클래스 패스에 같은 클래스에 대해 두 개의 정의가 있으므로 런타임에 예기치 않은 문제가 발생할 수 있으므로 두 버전을 선택할 수 없습니다.

+0

실제로 이것이 유일한 해결책 인 것 같습니다. 예를 들어, base1과 base2는 빌드 할 때 생성되는 클래스 경로를 가진 실행 가능한 응용 프로그램이므로 모든 종속성을 어셈블 링하는 응용 프로그램의 경우 _container_이며 class2의 종속성 때문에 base2가 실행 가능하지 않기 때문에 원하는 것은 아닙니다. 어셈블 된 종속성에는 포함되어 있지 않습니다. 그러나, 나는 여기 붙어있어 귀하의 제안이 가능한 최상의 해결책이 될 것 같습니다. – radlan

+0

@radlan 나는 뭔가를 놓치고있을 수도 있지만 "base1과 base2는 실행 가능한 응용 프로그램"이라는 설명에 기반하여 build # 1이 base1을 빌드하고 # 2 빌드가 base2를 빌드하는 두 개의 개별 빌드로 빌드를 분리해야하는 것처럼 보입니다. 이 경우 각 빌드는 고유 한 별도 버전의 종속성을 사용합니다. 어쨌든 여기에 관련된 게시물은 : http://stackoverflow.com/questions/24962607/multiple-versions-of-the-same-dependency-in-maven. 나는 그것에 대해서도 우연히 대답했다. 이 경우 Maven 프로파일을 사용할 수 있습니다. 각 프로파일은 자체 종속성을 선언 할 수 있습니다. – manouti

+0

base1과 base2는 별도의 빌드를 가지고 있습니다. 그러나 다른 빌드도 함께 묶어서 번들 전체를 쉽게 배포 할 수 있습니다. – radlan

1

Maven은 처음부터 끝까지 pom을 검색하고 발견 된 첫 번째 버전을 사용합니다.

commons-lang의 두 버전이 모두 필요하다고 가정하면 두 버전을 프로젝트에 넣고 maven을 사용하여 jar 파일에 패키지 할 수 있습니다.

StringUtils.isEmpty()에 대한 호출이 버전 2.3 또는 2.6을 호출하는 경우 컴파일러에서 어떻게 알 수 있습니까?

Same discussion here.

1

Maven은 항상 "가장 가까운 승리"전략을 사용하여 충돌을 해결합니다. 특정 버전을 사용하는 이유를 확인하기 위해 다음 명령을 실행할 수 있습니다

mvn dependency:tree -Dverbose -Dincludes=commons-lang 

대한 추가 정보를 원하시면 다음을 참조하십시오 (굵은 글씨로 강조 표시 관련 부분)이 official documentationhttps://maven.apache.org/plugins/maven-dependency-plugin/examples/resolving-conflicts-using-the-dependency-tree.html