Maven - исключая транзитивную зависимость из DependencyManagement - PullRequest
0 голосов
/ 26 января 2020

Подумайте о следующем pom.xml, используя maven 3.6.2

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

  <modelVersion>4.0.0</modelVersion>

  <artifactId>foo</artifactId>
  <groupId>bar</groupId>
  <version>1.0.0</version>

  <dependencies>
<!-- #1
    <dependency>
      <groupId>org.jdbi</groupId>
      <artifactId>jdbi3-jackson2</artifactId>
      <version>3.12.0</version>
    </dependency>
-->
    <dependency>
      <groupId>org.apache.kafka</groupId>
      <artifactId>kafka_2.12</artifactId>
      <version>2.4.0</version>
      <scope>compile</scope>
    </dependency>
<!-- #2
    <dependency>
      <groupId>org.jdbi</groupId>
      <artifactId>jdbi3-jackson2</artifactId>
      <version>3.12.0</version>
    </dependency>
-->
  </dependencies>

<!-- #3
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.jdbi</groupId>
        <artifactId>jdbi3-bom</artifactId>
        <type>pom</type>
        <version>3.12.0</version>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
-->

  <properties>
    <maven.compiler.target>11</maven.compiler.target>
    <maven.compiler.source>11</maven.compiler.source>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  </properties>
</project>

Если вы запустите mvn dependency:tree | grep databind, вы должны увидеть:

[INFO]    +- com.fasterxml.jackson.core:jackson-databind:jar:2.10.0:compile

Это базовая линия и устанавливается kafka_2.12 использует jackson-databind:2.10.0

Если вы раскомментируете только комментарий # 1 и повторно запускаете, вы должны увидеть:

[INFO] |  +- com.fasterxml.jackson.core:jackson-databind:jar:2.9.9.3:compile

Это имеет смысл для меня и говорит мне jdbi3-jackson2 использует jackson-databind:2.9.9.3 и эта версия используется, потому что она появляется до kafka_2.12

Если вы раскомментируете только комментарий № 2 и повторите его, вы должны увидеть:

[INFO] |  +- com.fasterxml.jackson.core:jackson-databind:jar:2.10.0:compile

Это также имеет смысл для меня, потому что jdbi3-jackson2 теперь появляется после kafka_2.12

Если вы раскомментируете только комментарий № 3 и повторите его, вы должны увидеть:

[INFO]    +- com.fasterxml.jackson.core:jackson-databind:jar:2.9.9.3:compile

Я ожидал 2.10.0, потому что я ничего не использую от бомбы (в частности, jdbi3-jackson2)

На основании почти всего, что все говорят о бомбах, я бы подумал, что информация о их версии будет только будет использоваться при применении зависимости в BOM

Далее, если я добавлю следующее в любом месте i n dependencyManagement затем возвращается к 2.10.0:

  <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.10.0</version>
  </dependency>
  1. как я могу обнаружить эту проблему (я обнаружил это только потому, что kafka завершится ошибкой и сообщит, что для этого требуется указать c Джексон). Моя мысль - написать скрипт / плагин, который сравнивает зависимости: дерево с «золотой» копией и терпит неудачу, если они различаются, чтобы заставить людей хотя бы дважды проверить свои изменения при изменении dependencyManagement
  2. как мне исключить зависимость от dependencyManagement? Я сделал это с нормальными зависимостями, и такой же тег исключения существует для dependencyManagement, но все, что я пробую, работает. Я бы предположил, что исключение вступает в силу, когда вы фактически используете зависимость, но я также думал, что версия вступит в силу только тогда, когда вы действительно используете зависимость, но это предположение кажется неправильным.
  3. , потому что я не могу исключить это, я могу форсировать версию с помощью метода, описанного выше, но почему он работает независимо от порядка, когда он находится в dependencyManagement, в отличие от того, где порядок имеет значение в обычном теге dependencies?

Ответы [ 2 ]

0 голосов
/ 27 января 2020
  • Для № 1. Я рекомендую использовать maven -forcecer-plugin

  • Для # 2. Вы можете исключить только прямые переходные зависимости.

  • Для № 3. Алгоритм решает, основываясь на ближайшем определении, что означает, что чем ближе будет зависимость к вашему проекту, тем он будет выбран.

0 голосов
/ 26 января 2020

Прежде всего, спецификации перекрывают переходные зависимости. Если в дереве зависимостей где-то появляется зависимость, и спецификация указывает для нее версию, эта версия выигрывает, если:

  • Вы сами определили зависимость с другой версией.
  • Вы добавили запись зависимостей, самостоятельно переопределяя значение в спецификации.

Также, конечно, если спецификации перекрываются, выиграть может только одна.

Так что если у вас есть jackson-databind как транзитивная зависимость, и у вас есть спецификация, в которую она входит, вы получаете версию из спецификации. Если вы сами не создадите запись для зависимостей, которая переопределяет спецификацию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...