为啥有时会跳过 maven 依赖项中的版本号?

Posted

技术标签:

【中文标题】为啥有时会跳过 maven 依赖项中的版本号?【英文标题】:Why version number in maven dependency is skipped at times?为什么有时会跳过 maven 依赖项中的版本号? 【发布时间】:2014-12-14 00:04:21 【问题描述】:

我对 maven 的功能还很陌生.. 我已经看到在放置依赖项的 pom.xml 中,有时只提到了 groupID 和 artifact id 并且跳过了版本。为什么是这样? 例如下面的依赖来自springsource网站http://spring.io/guides/gs/authenticating-ldap/

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-ldap</artifactId>
        <version>3.2.4.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.apache.directory.server</groupId>
        <artifactId>apacheds-server-jndi</artifactId>
        <version>1.5.5</version>
    </dependency>
</dependencies>

但在 *** 的其他地方也提到版本不是可选的。如果有人能解释这一点,我会很高兴。

【问题讨论】:

【参考方案1】:

是的,版本不是可选的。

考虑一个多模块应用程序,它有 10 个模块,比如 module1、module2.. module10。假设所有这 10 个项目都使用spring-boot-starter-web。如果这 10 个模块相互依赖,您可能希望在这 10 个模块中使用相同版本的 spring-boot-starter-web

现在想象一下,如果您要在所有这 10 个 pom 文件中保持相同的版本号,然后在您想使用更新版本的 spring-boot-starter-web 时更新所有这些文件,那将是多么复杂。如果可以集中管理这些信息不是更好吗?

Maven 有一个已知的 &lt;dependencyManagement/&gt; 标签来解决这个问题并集中依赖信息。

对于您提供的示例,下面的一组链接将帮助您了解如何解析版本号,即使它不存在于您正在查看的 pom 中。

查看你正在查看的 pom 的父标签 (https://github.com/spring-guides/gs-authenticating-ldap/blob/master/complete/pom.xml)

现在让我们去那个父节点看看版本是否在那个 pom 的 dependencyManagement 部分中指定(https://github.com/spring-projects/spring-boot/blob/master/spring-boot-starters/spring-boot-starter-parent/pom.xml)。不,它也没有在那里定义。现在让我们看看父母的父母。 https://github.com/spring-projects/spring-boot/blob/master/spring-boot-dependencies/pom.xml。哦,是的,我们那里有版本号。

类似于dependencyManagement,插件可以在pom的pluginManagement部分进行管理。

希望能解释一下。

参考:dependencyManagement,pluginManagement

【讨论】:

【参考方案2】:

coderplus 的优秀答案的一些补充:

在多模块项目中,将项目使用的工件配置在根pom.xmldependencyManagement 中被认为是一种很好的做法,这样您就不必在子模块中编写版本pom.xmls (就像您的示例中的某些依赖项一样)。

声明作为属性使用的外部库的版本,然后在dependencyManagement/dependencies/dependency/version 中使用这些属性也被认为是一种很好的做法。这或多或少已经完成here:

<properties>
    <logback.version>1.1.2</logback.version>
</properties>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>$logback.version</version>
        </dependency>
    </dependencies>
</dependencyManagement>

在多模块项目中,您还应该在dependencyManagement 中声明自己的工件。

但请不要明确写出版本(就像 Spring 人做的here),改用$project.version

所以写起来会更好:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot</artifactId>
            <version>$project.version</version>
        </dependency>

而不是

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot</artifactId>
            <version>1.2.0.BUILD-SNAPSHOT</version>
        </dependency>

here.

整个目的是DRY,不要重复自己。您在 POM 中的冗余声明越多,它们的打击就越大。寻找过时的依赖项非常有趣。

【讨论】:

以上是关于为啥有时会跳过 maven 依赖项中的版本号?的主要内容,如果未能解决你的问题,请参考以下文章

依赖项中的 JUnit 版本错误

为啥即使我的 maven 依赖项中有第三方依赖项,也只需要 OSGi 容器中的第三方依赖项?

在 Maven 依赖项中显示省略的版本:树?

Prisma 易受攻击的依赖项未在 Maven 依赖项中显示:树

为啥 Python for 循环在遍历列表副本并进行删除时会跳过元素? [复制]

maven为啥更新不下来新jar包?