Maven - обнаружение нескольких версий одной и той же зависимости - PullRequest
18 голосов
/ 21 марта 2012

Я только что столкнулся с двумя прямыми зависимостями моего проекта 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 - просто выбрать первую версию, которая появляется при разрешении зависимостей?

Ответы [ 6 ]

27 голосов
/ 21 марта 2012

Используйте плагин 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>
5 голосов
/ 27 октября 2014

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

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

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

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

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

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

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

4 голосов
/ 21 марта 2012

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

mvn зависимость: дерево -Dverbose -Dinclude = commons-collection

2 голосов
/ 21 марта 2012

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

1 голос
/ 21 марта 2012

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

<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: jersey-core с требуемой версией к вашим зависимостям. Maven разрешает конфликты версий, поддерживая зависимость, ближайшую к корню зависимостей.

0 голосов
/ 30 марта 2018

@ Виталий

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

mvn dependency:tree | grep ":compile" | sed 's/.* \(.*\):compile/\1/' | sort -u | cut -d ':' -f '1 2' | uniq -c | grep -vE "^ *1"

тогда мы можем использовать следующую командную строку, чтобы получить использованные версии этих зависимостей (это не оптимизированная командная строка;):

for dep in $(mvn dependency:tree | grep ":compile" | sed 's/.* \(.*\):compile/\1/' | sort -u | cut -d ':' -f '1 2' | uniq -c | grep -vE "^ *1" | cut -d ' ' -f 8); 
do 
  echo $dep; 
  mvn dependency:tree | grep $dep; 
  echo 
done
...