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
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
<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
As always, the code is available on GitHub.