[java] Maven 종속성 해결 (충돌)

4 개의 프로젝트가 있다고 가정 해 보겠습니다.

  • 프로젝트 A (B 및 D에 종 속됨)
  • 프로젝트 B (D에 종 속됨)
  • 프로젝트 C (D에 종 속됨)
  • 프로젝트 D

이 시나리오에서 프로젝트 A를 실행하면 Maven이 종속성을 D로 올바르게 해결합니다. 올바르게 이해하면 Maven은 항상 가장 짧은 경로로 종속성을 가져옵니다. D는 A의 직접적인 종속성이므로 B 내에 지정된 D가 대신 사용됩니다.

그러나 이제 다음 구조를 가정하십시오.

  • 프로젝트 A (B와 C에 종 속됨)
  • 프로젝트 B (D에 종 속됨)
  • 프로젝트 C (D에 종 속됨)
  • 프로젝트 D

이 경우 D를 해결하는 경로는 동일한 깊이를 갖습니다. Maven이 충돌하게됩니다. Maven에게 종속성을 제외해야한다고 말할 수 있다는 것을 알고 있습니다. 그러나 제 질문은 그러한 종류의 문제를 어떻게 해결할 것인가입니다. 실제 응용 프로그램에서는 많은 종속성과 충돌이있을 수 있습니다.

모범 사례 솔루션은 실제로 물건을 제외하는 것입니까, 아니면 이것에 대한 다른 가능한 솔루션이 있습니까? 일부 버전이 변경되어 Maven이 다른 종속성을 사용하기 때문에 갑자기 ClassNotFound 예외가 발생하면 처리하기가 매우 어렵습니다. 물론이 사실을 알면 문제가 종속성 충돌이라고 추측하기가 조금 더 쉬워집니다.

maven 2.1-SNAPSHOT을 사용하고 있습니다.



답변

이와 같은 상황을 해결하는 방법은 <dependencyManagement>프로젝트의 루트 pom에 섹션 을 포함하여 사용할 라이브러리의 버전을 지정하는 것입니다.

편집하다:

<dependencyManagement>
  <dependencies>
    <dependency>
        <groupId>foo</groupId>
        <artifactId>bar</artifactId>
        <version>1.2.3</version>
    </dependency>
   </dependencies>
</dependencyManagement>

이제 종속성에 의해 요청 된 라이브러리 foo : bar의 버전에 관계없이 버전 1.2.3이 항상이 프로젝트와 모든 하위 프로젝트에 사용됩니다.

참고:


답변

Maven은 충돌없이 두 상황을 모두 처리 할 수 ​​있습니다. 두 가지 버전의 전이 종속성이 필요한 경우 충돌이 발생합니다. ClassNotFoundException당신은 실제로 사용됩니다 충돌하는 의존성의 버전에서 사용할 수없는 클래스를 사용하려고 시도하는 응용 프로그램 (또는 종속)의 결과를 설명합니다. 문제를 해결하는 방법에는 여러 가지가 있습니다.

  1. 충돌하는 종속성에 의존하는 사용중인 라이브러리의 버전을 업데이트하여 모두 해당 종속성의 동일한 버전 버전에 의존하도록합니다.
  2. 포함 할 버전 (예제에서 누락 된 클래스가 포함 된 버전)이있는 프로젝트의 직접적인 종속성으로 충돌 종속성을 선언합니다.
  3. <dependencyManagement>POM 섹션을 통해 전이 종속성이 사용해야하는 충돌 종속성의 버전을 지정 합니다.
  4. 충돌하는 종속성의 원치 않는 버전을 종속성에 포함되지 않도록 명시 적으로 제외합니다. <exclusion>


답변

이것은 근본적으로 maven 문제가 아니라 Java 문제입니다. 프로젝트 B와 프로젝트 C에 프로젝트 D의 두 가지 호환되지 않는 버전이 필요한 경우 프로젝트 A에서 둘 다 사용할 수 없습니다.

이와 같은 충돌을 해결하는 Maven 방법은 이미 알고 있듯이 제외 할 충돌을 선택하는 것입니다.

mvn dependency:analyze및 사용하여 mvn dependency:tree어떤 갈등이 있는지 찾는 데 도움이됩니다.


답변

규칙 Dependency Convergence를 사용하여 전체 프로젝트에서 일관된 종속성을 적용 할 수 있습니다 .

 <plugin>
     <groupId>org.apache.maven.plugins</groupId>
     <artifactId>maven-enforcer-plugin</artifactId>
     <version>1.3.1</version>
     <executions>
        <execution>
           <id>enforce</id>
           <configuration>
              <rules>
                 <DependencyConvergence/>
              </rules>
           </configuration>
           <goals>
              <goal>enforce</goal>
           </goals>
        </execution>
     </executions>
  </plugin>


답변

한 가지 가능한 전략은 주 프로젝트에 사용할 D 버전 (최신 fg)을 지정하는 것입니다. 그러나 라이브러리 D가 이전 버전과 호환되지 않는 경우 kukudas에서 설명한대로 문제가 있습니다. 프로젝트에서 두 라이브러리를 모두 사용할 수 없습니다.

이러한 상황에서는 이전 버전에서 B 또는 C를 사용해야 할 수 있으므로 둘 다 호환되는 D 버전에 의존하게됩니다.


답변