有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Maven从曾祖父母那里获得依赖版本,而不是我们的父母依赖管理

下面显示了我的POM的层次结构

您可以看到,我们有一个公司的母公司pom,用于spring boot项目。这个POM将spring boot starter作为其父级,并导入我们自己的依赖项管理BOM

[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引导依赖项定义了AssertJ 2。与assertJ没什么大不了的,但还有其他一些像Mongo Java驱动程序这样的鱼,它们并没有接受我们的版本

Maven是如何选择优先权的?为什么我们的依赖管理不能战胜远祖的依赖管理

我还注意到,如果我添加AssertJ作为我的_公司的依赖项。平台:spring boot parent,它在我们的依赖关系管理中也不使用这个版本(所以我现在只保留它,所以显微镜下的层次结构更短)

编辑-添加缩写的POM

com。我的公司。平台:spring boot父级

<?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。我的公司: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 ........

共 (1) 个答案

  1. # 1 楼答案

    似乎没人知道答案。所以我会用我的发现来回答

    给定OP不起作用。我的下一个策略是导入spring boot starter父项和spring boot依赖项POM,因为我不能将它们用作父项

    然而,这有它自己的行为

    我发现,如果我的依赖关系管理看起来像这样,我的版本就会赢:

    <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的spring boot分开。所以为了保持优先权,我想我必须这样做:

    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
    

    然而,这并不奏效;spring boot版本超过了我们的定制版本。 所以我不得不这么做:

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

    结论

    • 如果在同一pom中导入多个依赖项管理,则第一个管理版本获胜
    • 如果导入多个POM,则最后一个导入的POM将获胜
    • 如果父级定义了依赖项管理,并定义了各个依赖项,则不能使用依赖项覆盖它们 管理(这是最初的问题)

    “'\_(ツ)_/“'