Is there a way to exclude a Maven dependency globally?

MavenMaven 2Dependenciespom.xml

Maven Problem Overview


I’m trying to find a “generic” way of excluding a transitive dependency from being included without having to exclude it from all the dependencies that depend on it. For example, if I want to exclude slf4j, I do the following:

  <dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-jmx</artifactId>
    <version>3.3.2.GA</version>
    <exclusions>
      <exclusion>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
      </exclusion>
    </exclusions>
  </dependency>
  <dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-entitymanager</artifactId>
    <version>3.4.0.GA</version>
    <type>jar</type>
    <exclusions>
      <exclusion>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
      </exclusion>
    </exclusions>
  </dependency>

This is partly to clean up the pom file, partly to avoid issues in the future with people adding dependencies that depend on that excluded dependency — and forgetting to exclude it.

Is there a way?

Maven Solutions


Solution 1 - Maven

Does this help? http://jlorenzen.blogspot.com/2009/06/maven-global-excludes.html

"Assuming I want to exclude avalon-framework from my WAR, I would add the following to my projects POM with a scope of provided. This works across all transitive dependencies and allows you to specify it once.

<dependencies>
  <dependency>
      <artifactId>avalon-framework</artifactId>
      <groupId>avalon-framework</groupId>
      <version>4.1.3</version>
      <scope>provided</scope>
  </dependency>
</dependencies>

This even works when specifying it in the parent POM, which would prevent projects from having to declare this in all child POMs."

Solution 2 - Maven

To expand on dnault's comment:

One can use the Maven Enforcer plugin's Banned Dependencies rule to ensure dependencies are excluded. One still has to exclude them manually, but the build will fail if anyone adds the dependency elsewhere by mistake.

<dependencies>
  <dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-jmx</artifactId>
    <version>3.3.2.GA</version>
    <exclusions>
      <exclusion>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
      </exclusion>
    </exclusions>
  </dependency>
</dependencies>

<plugins>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-enforcer-plugin</artifactId>
    <version>1.4.1</version>
    <executions>
      <execution>
        <goals>
          <goal>enforce</goal>
        </goals>
        <configuration>
          <rules>
            <bannedDependencies>
              <excludes>
                <exclude>org.slf4j:slf4j-api</exclude>
              </excludes>
            </bannedDependencies>
          </rules>
        </configuration>
      </execution>
    </executions>
  </plugin>
</plugins>

Also there is an open feature request: MNG-1977 Global dependency exclusions

Solution 3 - Maven

I created an empty jar and created this dependency:

<dependency>
	<groupId>commons-logging</groupId>
	<artifactId>commons-logging</artifactId>
	<scope>system</scope>
	<systemPath>${basedir}/src/lib/empty.jar</systemPath>
	<version>0</version>
</dependency>

It is not perfect because from now on you have an empty jar in your compile/test path. But that is just cosmetic.

Solution 4 - Maven

As a reminder, here is the answer from Maven official documentation:

>Why exclusions are made on a per-dependency basis, rather than at the POM level > This is mainly done to be sure the dependency graph is predictable, and to keep inheritance effects from excluding a dependency that should not be excluded. If you get to the method of last resort and have to put in an exclusion, you should be absolutely certain which of your dependencies is bringing in that unwanted transitive dependency.

If one wants to make a build more robust, a version range can be used. This would ensure that no newer version of the dependency can interfere with the project.

<dependency>
   <groupId>org.slf4j</groupId>
   <artifactId>slf4j-api</artifactId>
   <version>[1.4.2,)</version>
   <scope>provided</scope>
</dependency>

Any slf4j-api version >= 1.4.2 will be considered as offered (provided) at runtime, either from a configured classpath or a container.

References

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionS&#233;bastien Le CallonnecView Question on Stackoverflow
Solution 1 - MavenJofferView Answer on Stackoverflow
Solution 2 - MavenArend v. ReinersdorffView Answer on Stackoverflow
Solution 3 - MavenGuus BloemsmaView Answer on Stackoverflow
Solution 4 - MavenStephanView Answer on Stackoverflow