Maven dependency exclusions

3 minute read

Published:

Maven is an amazing build tool for Java software projects. One of the best uses of Maven is importing external libraries and using them in your project. There is a mechanism called Dependency management1, which can be used to centralize the dependency information.

The drawback

While adding a new library or while upgrading an existing library in a large project, it may happen that the new/updated project introduces new dependencies that were previously excluded in the dependency management for some reason (like the library was already present in the JDK).

Simulating the situation

Let’s simulate this situation. I’ll be using the amazing IntelliJ Idea for this.

  1. Firstly, create an empty java project.
  2. Now, go to New > Module and select Maven in the left bar. In the next input area, put any groupId in the form of: com.example.something.anything and artifactId as something we can remember, like example-1.
  3. Similarly, add new modules example-2, example-3 and example-to-be-excluded.
  4. Now, we add example-3 and example-to-be-excluded as dependencies into example-2’s pom file.
  5. Add example-2 as a dependency to example-1
  6. Now, using command line, run mvn install in example-3 and example-to-be-excluded.
  7. Now again in example-2.
  8. Now go to example-1 and run the same command.
  9. Now we check the dependency tree using mvn dependency:tree inside example-1. It should look like this:
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building example-1 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ example-1 ---
[INFO] com.manparvesh.mavenexclusions:example-1:jar:1.0-SNAPSHOT
[INFO] \- com.manparvesh.mavenexclusions:example-2:jar:1.0-SNAPSHOT:compile
[INFO]    +- com.manparvesh.mavenexclusions:example-3:jar:1.0-SNAPSHOT:compile
[INFO]    \- com.manparvesh.mavenexclusions:example-to-be-excluded:jar:1.0-SNAPSHOT:compile
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.908 s
[INFO] Finished at: 2017-12-23T09:09:02+08:00
[INFO] Final Memory: 13M/232M
[INFO] ------------------------------------------------------------------------

We have successfully created a sample environment where we can experiment.

Fixing the problem

Now, consider that your central dependency management has already excluded com.manparvesh.mavenexclusions:example-to-be-excluded:jar:1.0-SNAPSHOT. In this case, while building the complete project, maven will show an error like: <name> is excluded in DepsMgmt, but was found in the dependency tree. In such cases, it is better for us to simply exclude the library that causes conflicts.

For excluding a library, we need to find wherever its parent is being imported as a dependency. In our case, it would be example-2. Now, we can simply go to the example-1’s pom file and add an exclusion to the part where example-2 is added as a dependency. After adding the exclusion, it should look like this:

<dependencies>
    <dependency>
        <groupId>com.manparvesh.mavenexclusions</groupId>
        <artifactId>child-module-2</artifactId>
        <version>1.0-SNAPSHOT</version>
        <exclusions>
            <exclusion>
                <groupId>com.manparvesh.mavenexclusions</groupId>
                <artifactId>example-to-be-excluded</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

Now, if you check the dependency tree, the unwanted dependency will not be shown. In our case, the dependency tree looks like this:

[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building example-1 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ example-1 ---
[INFO] com.manparvesh.mavenexclusions:example-1:jar:1.0-SNAPSHOT
[INFO] \- com.manparvesh.mavenexclusions:example-2:jar:1.0-SNAPSHOT:compile
[INFO]    \- com.manparvesh.mavenexclusions:example-3:jar:1.0-SNAPSHOT:compile
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.671 s
[INFO] Finished at: 2017-12-23T13:22:27+08:00
[INFO] Final Memory: 12M/184M
[INFO] ------------------------------------------------------------------------

As you can see, the dependency tree is cleaned up, and now we can build our project without worrying about this! :tada:

The code for this tutorial can be found here: manparvesh/maven-exclusions



References
=========

  1. [apache.org] ASF. Dependency management Maven. Retrieved from https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Management
  2. [apache] ASF. Dependency exclusion Maven. Retrieved from https://maven.apache.org/guides/introduction/introduction-to-optional-and-excludes-dependencies.html

Leave a Comment