11

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?

5
  • Solution 5 is out: see github.com/spring-projects/spring-boot/issues/5014 Commented May 31, 2018 at 10:12
  • Have you simply tried to remove the version at all in dependencyManagement block? Commented Jun 1, 2018 at 19:55
  • @khmarbaise, yes, maven complains that version is missing Commented Jun 4, 2018 at 13:02
  • I still see this problem with mvn 3.6.0/3.6.1 Commented Jan 20, 2020 at 11:16
  • Duplicate (no solution): stackoverflow.com/questions/39330834/… Commented Jan 20, 2020 at 12:07

1 Answer 1

3

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.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.