Maven - обнаружение нескольких версий одной и той же зависимости

Я просто испытал случай с двумя прямыми зависимостями моего проекта maven, имеющим две разные версии определенной транзитивной зависимости.

В моем конкретном случае у меня были прямые зависимости от следующего:

    <dependency>
        <groupId>org.jclouds.driver</groupId>
        <artifactId>jclouds-sshj</artifactId>
        <version>${jclouds.version}</version>
    </dependency>

и

    <dependency>
        <groupId>org.mule.modules</groupId>
        <artifactId>mule-module-jersey</artifactId>
        <version>${mule.version}</version>
    </dependency>

Обе эти зависимости имели (глубокую) транзитивную зависимость от com.sun.jersey: jersey-core, но с разными версиями для каждого. Maven не терпел неудачу на этом или даже предупреждал (или, если да, я этого никогда не видел!), Что такое происходит... и поэтому я никогда не замечал этого до отладки проблемы, которая произошла, когда версия jersey- ядро, вызванное зависимостью jclouds, заставило некоторые вещи сломаться.

Существует ли какой-либо плагин maven или какой-либо другой инструмент, который будет обнаруживать переопределение такого рода с высокой транзитивной зависимостью и, по крайней мере, предупреждать пользователя (или не выполнить выполнение maven), если он обнаруживает такое столкновение... даже если значение по умолчанию maven - просто выбрать первую версию, которая появляется при разрешении зависимостей?

Ответы

Ответ 1

Используйте плагин Dependency Enforcer. Он остановит сборку, когда зависимости не будут сходиться должным образом.

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

Ответ 2

@Clement P предоставил вам отличный ответ. Однако обратите внимание, что для многомодульных проектов этого может быть недостаточно.

Цель depedndencyconvergence плагина forcecer знает, как обнаружить транзитивные конфликты зависимостей, но столкновение может скрыть себя другим способом.

Предположим, что у вас многомодульный проект. Root - это A, и он имеет 2 вспомогательных модуля, B1 и B2.

B1 объявляет зависимость от артефакта a: b: c: 1.1, а B2 объявляет зависимость от артефакта a: b: c: 2.0

В этом случае, если оба модуля будут построены и развернуты с их зависимостями, у вас будет столкновение, но это своего рода плагин, который не знает, как его обнаружить. Поскольку проект A не зависит (не может) от его подмодулей.

Чтобы преодолеть эту проблему в нашей организации, мы использовали плагин dependency: list и проанализировали его вывод вручную.

Грубое описание процесса. Результатом выполнения этой задачи является список всех транзитивных зависимостей всех проектов в иерархии проектов. Мы чем разбираем вывод, сортируем зависимости и выполняем поиск только для тех артефактов, которые отличаются только идентификатором версии. Это требует некоторых скриптов в вашем CI env, но это единственный способ получить общую картину.

Ответ 3

вы можете запустить отчет об отсрочке или использовать дерево зависимостей:

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

Ответ 4

Вы можете просто взглянуть на ваш обзор dependency hiercharchy. Это не предупредит вас, но вы можете увидеть, будут ли отброшены некоторые версии для более новых версий одной и той же библиотеки.

Ответ 5

Вы можете разрешить конфликт версий, исключив нужную версию из подходящей зависимости. Например:

<dependency>
    <groupId>org.jclouds.driver</groupId>
    <artifactId>jclouds-sshj</artifactId>
    <version>${jclouds.version}</version>
    <exclusions>
      <exclusion>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-core</artifactId>
      </exclusion>
    </exclusions>
</dependency>

Или вы добавляете com.sun.jersey: джерси-ядро с требуемой версией к вашим зависимостям. Maven разрешает ограничения версий, поддерживая зависимость, которая наиболее близка к корню зависимостей.