There will be times when you need to exclude a
transitive dependency, such as when you are depending on a project
that depends on another project, but you would like to either exclude
the dependency altogether or replace the transitive dependency with
another dependency that provides the same functionality. Example 3.7, “Excluding a Transitive Dependency” shows an example of a dependency element that
adds a dependency on project-a, but excludes the
transitive dependency project-b.
Example 3.7. Excluding a Transitive Dependency
<dependency>
<groupId>org.sonatype.mavenbook</groupId>
<artifactId>project-a</artifactId>
<version>1.0</version>
<exclusions>
<exclusion>
<groupId>org.sonatype.mavenbook</groupId>
<artifactId>project-b</artifactId>
</exclusion>
</exclusions>
</dependency>
Often, you will want to replace a transitive dependency with another implementation. For example, if you are depending on a library that depends on the Sun JTA API, you may want to replace the declared transitive dependency. Hibernate is one example. Hibernate depends on the Sun JTA API JAR, which is not available in the central Maven repository because it cannot be freely redistributed. Fortunately, the Apache Geronimo project has created an independent implementation of this library that can be freely redistributed. To replace a transitive dependency with another dependency, you would exclude the transitive dependency and declare a dependency on the project you wanted instead. Example 3.8, “Excluding and Replacing a Transitive Dependency” shows an example of a such replacement.
Example 3.8. Excluding and Replacing a Transitive Dependency
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate</artifactId>
<version>3.2.5.ga</version>
<exclusions>
<exclusion>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jta_1.1_spec</artifactId>
<version>1.1</version>
</dependency>
</dependencies>
In Example 3.8, “Excluding and Replacing a Transitive Dependency”, there is nothing marking
the dependency on geronimo-jta_1.1_spec as a
replacement, it just happens to be a library which provides the same
API as the original JTA
dependency. Here are some other reasons you might want to exclude or
replace transitive dependencies:
-
The
groupIdorartifactIdof the artifact has changed, where the current project requires an alternately named version from a dependency's version - resulting in 2 copies of the same project in the classpath. Normally Maven would capture this conflict and use a single version of the project, but whengroupIdorartifactIdare different, Maven will consider this to be two different libraries. -
An artifact is not used in your project and the transitive dependency has not been marked as an optional dependency. In this case, you might want to exclude a dependency because it isn't something your system needs and you are trying to cut down on the number of libraries distributed with an application.
-
An artifact which is provided by your runtime container thus should not be included with your build. An example of this is if a dependency depends on something like the Servlet API and you want to make sure that the dependency is not included in a web application's
WEB-INF/libdirectory. -
To exclude a dependency which might be an API with multiple implementations. This is the situation illustrated by Example 3.8, “Excluding and Replacing a Transitive Dependency”; there is a Sun API which requires click-wrap licensing and a time-consuming manual install into a custom repository (Sun's JTA JAR) versus a freely distributed version of the same API available in the central Maven repository (Geronimo's JTA implementation).
