Java – Maven – why can’t I override the version of a dependencyManagement imported pom

javamaven

I'm looking for an explanation about this case: I have a project that has a dependencyManagement / dependencies section with:

myproject/pom.xml:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-parent</artifactId>
            <version>Brixton.M3</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka</artifactId>
    </dependency>
</dependencies>

The spring-cloud-starter-parent pom defines:

<properties>
        <main.basedir>${basedir}/../..</main.basedir>
        <spring-cloud-netflix.version>1.1.0.BUILD-SNAPSHOT</spring-cloud-netflix.version>
</properties>
<dependencyManagement>
    <dependencies>
        <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-eureka</artifactId>
                <version>${spring-cloud-netflix.version}</version>
        </dependency>
    </dependencies>
</dependencyManagement>

This way, my project will get spring-cloud-starter-eureka version 1.1.0.BUILD-SNAPSHOT.

I was expecting that if I add in myproject/pom.xml a properties section with another version I would override the default version, however it is ignored, why?

myproject/pom.xml

...
<properties>
        <spring-cloud-netflix.version>1.0.0</spring-cloud-netflix.version>
</properties>
...

Best Answer

The property spring-cloud-netflix.version has already been resolved when building the org.springframework.cloud:spring-cloud-starter-eureka artifact, so you can not just override this when declaring the dependency.

To properly specify a certain dependency version, you have to add the version of that dependency in the dependency management section of your pom:

...
<properties>
        <spring-cloud-netflix.version>1.0.0</spring-cloud-netflix.version>
</properties>
...
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-parent</artifactId>
            <version>Brixton.M3</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-eureka</artifactId>
                <version>${spring-cloud-netflix.version}</version>
        </dependency>
    </dependencies>
</dependencyManagement>
<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka</artifactId>
    </dependency>
</dependencies>

As a best practice for a multi module build you would typically have a shared master pom containing the dependency management settings incl. all version information for all your dependencies.