I want my dependency in dependencyManagement
block to inherit a version from spring-boot-parent
's dependencyManagement
block, but add exclusion to it, so that I don't need to specify that exclusion in each of child modules.
My parent pom inherits from spring-boot-parent:
<artifactId>my-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
<relativePath/>
</parent>
<dependencyManagement>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>???</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencyManagement>
child pom inherits my-parent
:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
</dependencies>
I tried several approaches:
When I replace ???
with ${parent.version}
, in child module this version is resolved to be my-parent
's version: 1.0.0-SNAPSHOT
, which is incorrect.
When I replace ???
with ${parent.parent.version}
, maven breaks, as it doesn't support such properties
I can fix ???
to be 2.0.1.RELEASE
and this will work fine, but if I update the version of spring boot, I have to remember to update the version of this dependency also, which is non-intuitive
I cannot extract 2.0.1.RELEASE
as a property in my-parent
and use that property as parent version, as maven does not support that.
I could've used property with value 2.0.1.RELEASE
inherited from spring-boot-parent
pom, but there is none such property, as far as I can see.
Is there a nice way to achieve what I want?
See Possible to have the parent version as Property to give to the children? - the version used to declare your parent can't be repurposed in a way that says "make this reference fixed to mean its interpretation at this point in the graph". Strings are strings and placeholders are placeholders; there's no built-in facility to have some kind of in-between thing. If the parent uses a property to define a dependency version you can reference that property; if it uses a fixed string (as in your case) then you'll need to repeat something in order to define an exclusion. As referenced in the linked question, a common way is something like this:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
</parent>
<properties>
<spring.boot.version>2.0.1.RELEASE</spring.boot.version>
</properties>
<dependencyManagement>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>${spring.boot.version}</version>
<exclusions>
...
You still have to repeat the value in two fields -- so you have to make very sure that you always keep those in sync (parent version and property).
However, the increasingly-popular way to manage this is to declare those versions in a BOM (a "bill-of-materials" pom with the specific purpose of keeping a set of components aligned). Then the dependencyManagement
stuff can be imported instead of inherited. Spring Boot has been doing this for a while now; in fact the parent in your example doesn't actually declare the dependencies itself, they come from a different artifact. So instead of inheriting from the parent, you could do something like this (I might have the sequence of these backwards -- I can't remember whether first or last wins):
<properties>
<spring.boot.version>2.0.1.RELEASE</spring.boot.version>
</properties>
<dependencyManagement>
<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</artifactId>
<version>${spring.boot.version}</version>
<exclusions>
...
... now, if there are other reasons (beyond just dep mgmt) you wanted to inherit from spring-boot-starter-parent
then this won't really help your problem; you'll still need to duplicate. But I suspect that as your project matures you'll want to have a parent of your own devising anyway.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With