Course – LS – All
announcement - icon

Get started with Spring Boot and with core Spring, through the Learn Spring course:

>> CHECK OUT THE COURSE

1. Overview

Excluding dependencies in Maven is a common operation. However, it gets significantly more difficult when dealing with Maven plugins.

2. What’s Dependency Exclusion

Maven manages the transitivity of dependencies. This means that Maven can automatically add all the required dependencies by the dependencies we added. In some cases, this transitivity can quickly inflate the number of dependencies because it adds cascading dependencies.

For instance, if we have dependencies such as A → B → C → D, then A will depend on B, C, and D. If A only uses a small part of B, which does not need C, then it is possible to tell Maven to ignore the B → C dependency in A.

Consequently, A will depend only on B and no longer on C and D. This is called dependency exclusion.

3. Excluding a Transitive Dependency

We can exclude sub-dependencies using the <exclusions> element, which contains a set of exclusions on a specific dependency. In brief, we only need to add an <exclusions> element in the <dependency> element of the POM file.

For instance, let’s consider the example of commons-text dependency and assume that our project only uses code from commons-text, which doesn’t need commons-lang sub-dependency.

We’ll be able to exclude the commons-lang dependency from the commons-text transitivity chain in our project by simply adding a <exclusions> section in the declaration of the dependency to commons-text in the POM file of our project like below:

<project>
    ...
    <dependencies>
        ...
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-text</artifactId>
            <version>1.1</version>
            <exclusions>
                <exclusion>
                    <groupId>org.apache.commons</groupId>
                    <artifactId>commons-lang3</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
    ...
</project>

Therefore, if we rebuild a project with the POM above, we’ll see that the commons-text library is integrated into our project but not the commons-lang library.

4. Excluding a Transitive Dependency From a Plugin

Up until now, Maven doesn’t support excluding direct dependencies from a plugin, and an issue is already open to including this new feature. In this chapter, we’ll discuss a workaround to exclude a direct dependency from a Maven plugin by overriding it with a dummy.

Suppose we must exclude the JUnit 4.7 dependency of the Maven Surefire plugin.

First, we must create a dummy module that must be part of our project’s root POM. This module will contain only a POM file that looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.apache.maven.surefire</groupId>
    <artifactId>surefire-junit47</artifactId>
    <version>dummy</version>
</project>

Next, we need to adapt our child POM where we wish to deactivate the dependency. To do so, we must add the dependency with the dummy version to the Maven Surefire plugin declaration:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>${surefire-version}</version>
            <configuration>
                <runOrder>alphabetical</runOrder>
                <threadCount>1</threadCount>
                <properties>
                    <property>
                        <name>junit</name>
                        <value>false</value>
                    </property>
                </properties>
            </configuration>
            <dependencies>
                <dependency>
                    <!-- Deactivate JUnit 4.7 engine by overriding it with an empty dummy -->
                    <groupId>org.apache.maven.surefire</groupId>
                    <artifactId>surefire-junit47</artifactId>
                    <version>dummy</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>

Finally, once we build our project, we will see that the JUnit 4.7 dependency of the Maven Surefire plugin has not been included in the project and that the exclusion has worked well.

5. Conclusion

In this quick tutorial, we explained dependency exclusion and how to exclude transitive dependencies using the <exclusions> element. Also, we exposed a workaround to exclude direct dependencies in a plugin by overriding it with a dummy. 

As always, the code is available on GitHub.

Course – LS – All
announcement - icon

Get started with Spring Boot and with core Spring, through the Learn Spring course:

>> CHECK OUT THE COURSE

res – Maven (eBook) (cat=Maven)