Why version number in maven dependency is skipped

2019-02-20 04:42发布

I am fairly new to maven's capabilities.. I have seen that in pom.xml where dependencies are put, at times, only groupID and artifact id are mentioned and version is skipped. why is this? For example the below dependency is from springsource website 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>

But elsewhere in stackoverflow it was also mentioned that version is not optional. I would be glad if someone could explain this.

2条回答
趁早两清
2楼-- · 2019-02-20 05:11

Yes, version is not optional.

Consider a multimodule application which has 10 modules, say module1, module2.. module10.Assume that all of these 10 projects use the spring-boot-starter-web. In case these 10 modules are interdependent, you might want to use the same version of the spring-boot-starter-web in each of these 10.

Now just imagine how complicated it would be if you were to maintain the same version number in all of these 10 pom files and then update all of them when you want to use a newer version of spring-boot-starter-web. Wouldn't it be better if this information can be managed centrally?

Maven has got something known a <dependencyManagement/> tag to get around this and centralize dependency information.

For the example which you have provided, below set of links will help you understand how the version number is resolved even though it's not present in the pom which you are looking at.

Look at the parent tag of the pom you are looking at (https://github.com/spring-guides/gs-authenticating-ldap/blob/master/complete/pom.xml)

Now lets go to that parent and see if the versions are specified in the dependencyManagement section of that pom(https://github.com/spring-projects/spring-boot/blob/master/spring-boot-starters/spring-boot-starter-parent/pom.xml). No it's not defined there as well. Now lets look at the parent of parent. https://github.com/spring-projects/spring-boot/blob/master/spring-boot-dependencies/pom.xml. Oh yea, we have got the version numbers there.

Similar to dependencyManagement, plugins can be managed in the pluginManagement section of the pom.

Hope that explains it.

Refer : dependencyManagement, pluginManagement

查看更多
别忘想泡老子
3楼-- · 2019-02-20 05:32

A few additions to the excellent answer by coderplus:

In a multi-module project, it is considered to be a good practice to configure the artifacts used by the project in the dependencyManagement of the root pom.xml so that you don't have to write versions in child module pom.xmls (like in some dependencies in your example).

It is also considered to be a good practice to declare versions of the external libraries that you use as properties and then use these properties in dependencyManagement/dependencies/dependency/version. This is more or less done 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>

In a multi-module project, you should also declare your own artifacts in dependencyManagement.

But please do not write the version explicitly (like Spring people do here), use ${project.version} instead.

So it would have been better to write:

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

instead of

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

here.

The whole purpose is DRY, don't repeat yourself. The more redundant declarations you have in your POMs, the harder they can hit. Hunting for the obsolete dependencies is so much fun.

查看更多
登录 后发表回答