Ниже показана иерархия моих 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 ........
Можете ли вы опубликовать тег зависимости для assertj в своем POM?
Я действительно хотел бы видеть вас также dependencyManagement и parent, если это вообще возможно.
Обновлено с помощью POM.




Я предполагаю, что он хватает ближайшего.
Dependency mediation - this determines what version of a dependency will be used when multiple versions of an artifact are encountered. Currently, Maven 2.0 only supports using the "nearest definition" which means that it will use the version of the closest dependency to your project in the tree of dependencies. You can always guarantee a version by declaring it explicitly in your project's POM. Note that if two dependency versions are at the same depth in the dependency tree, until Maven 2.0.8 it was not defined which one would win, but since Maven 2.0.9 it's the order in the declaration that counts: the first declaration wins.
Что я делаю для подобных вещей, так это захожу в раздел зависимостей моей IDE для данного проекта. Он показывает мне все зависимости, какую версию и откуда она взялась (пример см. Внизу всплывающего окна на прикрепленном изображении).
Я использую IntelliJ. Рядом с зависимостью отображается значок стрелки вверх. Когда я нахожу указатель мыши, он показывает фрагмент объявления из моего Dep-man, а когда я щелкаю значок, он переводит меня в управление зависимостями, которое я хочу использовать! Таким образом, кажется, что intelliJ понимает это правильно, но не командную строку maven.
Проблема в том, что ваш проект полагается не на родительский объект для управления зависимостями, а на импортированный проект. Иерархия зависимостей Maven так не работает. Вероятно, лучшим решением было бы переместить объявление 'parent-spring-boot-starter-parent' в проект MY_COMPANY: dependencyManagementBase. Затем измените родительское объявление в com.MYCOMPANY.platform, чтобы оно указывало на ваш проект dependencyManagementBase. Таким образом, у вас будет четкая иерархия наследования.
То, что у вас сейчас есть, на самом деле не использует управление зависимостями. то есть, если бы вы изменили раздел «dependencyManagement» в проекте dependencyManagementBase на «dependency», вы бы получили те же результаты.
Спасибо. Пока вы это публиковали, я публиковал еще один пост с моими выводами (stackoverflow.com/a/50242089/768671). Можете ли вы подтвердить, что мы говорим об одном и том же? Хотя это вроде как то, что вы говорите, вы НЕ МОЖЕТЕ импортировать управление зависимостями?
Точно. Вы не можете импортировать управление зависимостями и ожидать, что оно изменит версию, которая была определена в pom более высокого уровня. Вам нужно либо объявить версию в вашем проекте нижнего уровня, либо сделать ваш проект dependencyManagement родительским.
Похоже, ни у кого нет ответа. Так что я просто отвечу своими выводами.
Данный OP не работает. Моя следующая стратегия - ИМПОРТИРОВАТЬ POM-файлы spring-boot-starter-parent и spring-boot-dependency, поскольку я не могу использовать их в качестве родителей.
Однако у этого есть свои особенности.
Я обнаружил, что если мое управление зависимостями выглядит так, мои версии выигрывают:
<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
¯ \ _ (ツ) _ / ¯
У меня такая же проблема - надеюсь, кто-нибудь знает ответ