Версия зависимости Maven Sourcing от пра-пра-прародителя вместо управления зависимостями наших родителей - PullRequest
0 голосов
/ 05 мая 2018

Ниже показана иерархия моих POM.

Вы видите, что у нас есть компания-родитель для проектов весенней загрузки. Это POM имеет spring-boot-starter в качестве родителя и импортирует нашу собственную спецификацию управления зависимостями.

[INFO] --- hierarchy-maven-plugin:1.4:tree (default-cli) @ user-service ---
[INFO]  PARENT com.MY_COMPANY.platform:user:3.20.14-SNAPSHOT
[INFO]    PARENT com.MY_COMPANY.platform:spring-boot-parent:3.20.12-SNAPSHOT
[INFO]      PARENT org.springframework.boot:spring-boot-starter-parent:1.5.12.RELEASE
[INFO]        PARENT org.springframework.boot:spring-boot-dependencies:1.5.12.RELEASE  <<<< This pom defines assertJ 2.x
[INFO]          [ other imports ]
[INFO]      IMPORT com.MY_COMPANY:dependencyManagementBase:2.23.14-SNAPSHOT     <<<<<<<<<<<< This pom defines assertJ 3.x
[INFO]    IMPORT com.MY_COMPANY.platform:platform-dependency-management:1.20.7
[INFO] ------------------------------------------------------------------------

Чтобы сосредоточиться на конкретном, мы определяем AssertJ 3 в нашем управлении зависимостями; тем не менее, spring-boot-dependencies определяет AssertJ 2. Не так уж и сложно с assertJ, но есть другие рыбы, такие как Mongo-Java-Driver, которые не принимают нашу версию.

Как Maven выбирает приоритет здесь? Почему наше управление зависимостями не побеждает управление зависимостями далекого предка?

Я также заметил, что если я добавлю AssertJ в качестве зависимости MY_COMPANY.platform: spring-boot-parent, он также НЕ использует версию в нашем управлении зависимостями (поэтому я просто пока оставлю ее там, поэтому иерархия под микроскопом короче).

РЕДАКТИРОВАТЬ - Добавить сокращенные POM

com.MY_COMPANY.platform: весна-ботинки-родитель

<?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>

    <groupId>com.MYCOMPANY.platform</groupId>
    <artifactId>spring-boot-parent</artifactId>
    <version>3.20.12-SNAPSHOT</version>
    <packaging>pom</packaging>

    <prerequisites>
        <maven>3.0.4</maven>
    </prerequisites>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.12.RELEASE</version>
    </parent>

    <properties>
        <MYCOMPANYdependencymanagement.version>2.23.13</MYCOMPANYdependencymanagement.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.assertj</groupId>
            <artifactId>assertj-core</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.MYCOMPANY</groupId>
                <artifactId>dependencyManagementBase</artifactId>
                <version>${MYCOMPANYdependencymanagement.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

com.MY_COMPANY: dependencyManagementBase

<?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>

    <groupId>com.MYCOMPANY</groupId>
    <artifactId>dependencyManagementBase</artifactId>
    <version>2.23.13</version>
    <packaging>pom</packaging>

    <modules>
        <module>spring-dep-man</module>
    </modules>

    <properties>
        <org.assertj-core.version>3.5.2</org.assertj-core.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.assertj</groupId>
                <artifactId>assertj-core</artifactId>
                <version>${org.assertj-core.version}</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

** РЕДАКТИРОВАТЬ 2 - Добавить подробную иерархию, показывающую разные версии **

~/p/springbootparentpom> mvn hierarchy:tree -Dlevel=full
[INFO] --- hierarchy-maven-plugin:1.4:tree (default-cli) @ spring-boot-parent ---
[INFO] Displaying hierarchy.
[INFO]  PARENT org.springframework.boot:spring-boot-starter-parent:1.5.12.RELEASE
[INFO]    PARENT org.springframework.boot:spring-boot-dependencies:1.5.12.RELEASE
[INFO]          DEP_MANAGEMENT ........
[INFO]          DEP_MANAGEMENT org.assertj:assertj-core:2.6.0
[INFO]          [ ... Many DEP_MAN and IMPORT ... ]
[INFO]  IMPORT com.MYCOMPANY:dependencyManagementBase:2.23.14-SNAPSHOT
[INFO]        DEP_MANAGEMENT ........
[INFO]        DEP_MANAGEMENT org.assertj:assertj-core:3.5.2
[INFO]        DEP_MANAGEMENT ........

Ответы [ 3 ]

0 голосов
/ 08 мая 2018

Проблема в том, что ваш проект полагается не на родителя для управления зависимостями, а на импортированный проект. Иерархия зависимостей Maven не работает таким образом. Вероятно, лучшим решением было бы перенести объявление 'parent spring-boot-starter-parent' в проект MY_COMPANY: dependencyManagementBase. Затем измените родительское объявление в com.MYCOMPANY.platform, чтобы оно указывало на ваш проект dependencyManagementBase. Таким образом, у вас будет четкая иерархия наследования.

То, что у вас есть, на самом деле не использует управление зависимостями. то есть, если бы вы изменили раздел 'dependecyManagement' в проекте dependencyManagementBase на 'dependency', вы бы получили те же результаты.

0 голосов
/ 08 мая 2018

Не похоже, что у кого-то есть ответ. Поэтому я просто отвечу своими выводами.

Данный ОП не работает. Моя следующая стратегия - ИМПОРТИРОВАТЬ POM spring-boot-starter-parent и spring-boot-зависимость, так как я не могу использовать их в качестве родителей.

Это, однако, имеет свое поведение.

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

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.mycompany</groupId>
            <artifactId>dependency-management-slim</artifactId>
            <version>2.23.14-SNAPSHOT</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>${spring-boot.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>${spring-boot.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

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

service-root -> only import my-dependency-management
^-- spring-boot-parent -> mimick and import spring-boot-starter-parent
^-- service-parent -> has our common dependencies and profiles
^-- service-impl - code

Однако это НЕ сработало; Версии с весенней загрузкой вышли за рамки наших пользовательских версий. Поэтому я должен был сделать это:

root-parent -> nothing
^-- spring-boot-parent -> mimick and import spring-boot-starter-parent
^-- service-parent -> import my-dependency-management
^-- service-impl - code

Выводы

  • ЕСЛИ импортирует многократное управление зависимостями в ТО ЖЕ ВРЕМЯ, тогда выигрывают первые версии управления.
  • ЕСЛИ вы импортируете в несколько poms, последний импортированный выигрывает.
  • IF родительский объект имеет управление зависимостями с определенными индивидуальными зависимостями, их нельзя переопределить зависимостями управление (это оригинальная проблема).

¯ \ _ (ツ) _ / ¯

0 голосов
/ 05 мая 2018

Я предполагаю, что он захватывает ближайшего.

Посредничество зависимости - это определяет, какая версия зависимости будет использоваться при обнаружении нескольких версий артефакта. В настоящее время Maven 2.0 поддерживает только использование «ближайшего определения», что означает, что он будет использовать версию ближайшей зависимости к вашему проекту в дереве зависимостей. Вы всегда можете гарантировать версию, явно объявив ее в POM вашего проекта. Обратите внимание, что если две версии зависимостей находятся на одной и той же глубине в дереве зависимостей, до Maven 2.0.8 не было определено, какой из них выиграет, но начиная с Maven 2.0.9 учитывается порядок в объявлении: выигрывает первое объявление.

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

enter image description here

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