Multi-module project: Exclude a dependency from the parent pom

Viewed 846

We have a Maven multi-module project with some 30 child projects/module in it.

All child projects where using those two dependencies. (This is just to put something concrete in the example)

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-cassandra-reactive</artifactId>
</dependency>

Hence, we refactored and put those two dependencies to the parent POM. The snippet from above is now in the parent level. All child projects could still benefits from it, and have to only maintain the version in one place, all very happy.

We now have a 31st project which fits the business use cases and fits inside this multi module project, we believe it makes sense to have it under this same parent POM.

However, this 31st project does not need one particular dependency from the Parent POM. (In this case the Cassandra dependency, but the question is about how to exclude something from the parent)

Having this 31st project part of this multi module, he also takes this dependency (Cassandra) from the parent. How to tell this child project to exclude this dependency from the parent?

  • I do not want to extract this project entirely and have it separated from the multi module.

  • I tried putting an exclusion in ALL dependencies, but it is still there. Like in all dependencies of my child pom, I write this:

    <dependency>
        <groupId>some.group</groupId>
        <artifactId>some.artifact</artifactId>
        <exclusions>
            <exclusion>  <!-- declare the exclusion here -->
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-cassandra-reactive</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    
  • I even tried doing the crazy refactor of moving the dependency away from the parent back to all children, and did 30 copy paste to the child, with my 31st project not having it. This works, but I believe there is something smarter than that.

How to exclude one particular dependency from the Parent POM please?

1 Answers

The way I normally do this is by using a multi-level hierarchy of poms.

This means that instead of a single parent-pom with just one row of non-parent poms underneath it, I have an entire tree of parent poms consisting of a root-parent-pom with several levels of intermediate-parent-poms as its children, ending with the non-parent-poms as the leaves of the tree.

By adding intermediate parent-poms you can have the root parent only provide the dependencies that are truly used by all children, while intermediate poms can provide additional dependencies that are only used by their children but not by children of their siblings.

So, in your case, your root parent pom would declare all dependencies except cassandra, and it would have two children: your casandraless project, and your existing parent pom which would now become an intermediate parent pom and it would only declare the cassandra dependency. So, the children of the intermediate parent pom would inherit all the dependencies except cassandra from the root, and then cassandra from the intermediate parent pom.

I have tried this, it works very well.

It is true that there may theoretically exist situations that cannot be covered, because parent poms can only form a tree, and a tree is not a graph, but in practice I never came across a situation where I wanted to arrange my dependencies in such a way that this mechanism could not cover.

As an example, take a look at my public home projects, which I have rolled all together into one repository for the sake of more easily managing them:

https://github.com/mikenakis/Public

https://github.com/mikenakis/Public/blob/master/pom.xml is the root pom.

https://github.com/mikenakis/Public/blob/master/testana/pom.xml is an intermediate parent pom,

https://github.com/mikenakis/Public/blob/master/testana/testana-console/pom.xml is a child pom. (A leaf.)

Now, in my projects it just so happens that I only declare dependencies in the leaf poms, because my projects do not really depend on many external libraries. But I could be declaring dependencies in the root pom and in the intermediate parent poms if I wanted to, and their children would be inheriting them.

Related