2

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?

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
PatPanda
  • 3,644
  • 9
  • 58
  • 154
  • 1
    Keep version in parent pom using dependencyManagement and move the actual usage in those child poms that need it. – Thorbjørn Ravn Andersen Nov 16 '20 at 00:45
  • Thank you @ThorbjørnRavnAndersen. But if possible, this is what I would like to avoid. I would need to move one dependency that is currently in the parent and all children are benefiting happily, move down to all children and duplicate the dependency there. It is possible to just keep in the Parent POM, but removing it from one child alone? – PatPanda Nov 16 '20 at 00:54
  • Like mentioned in this article: https://roytuts.com/managing-dependencies-and-plugins-in-multi-module-project/ – PatPanda Nov 16 '20 at 00:56
  • The disadvantage of using is you have to re-declare the required dependency in child pom file. – PatPanda Nov 16 '20 at 00:56
  • This is exactly what I would like to avoid. I have 30ish and more to come children needing all dependencies from parent. Just one child that does not need it. Instead of maintaining in all children, can I just exclude from one? – PatPanda Nov 16 '20 at 00:57
  • 1
    You can only avoid it by tricking Maven to use a dummy artifact. That is a slippery slope for production code. This is the occasion for you to refactor the dependency down from the parent Pom. I would just do it - 30 should be doable in 10-15 minutes with a modern ide. – Thorbjørn Ravn Andersen Nov 16 '20 at 07:49

1 Answers1

0

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.

Mike Nakis
  • 56,297
  • 11
  • 110
  • 142