Exclude all transitive dependencies of a single dependency

Viewed 263736

In Maven2, to exclude a single transitive dependency, I have to do something like this:

<dependency>
  <groupId>sample.group</groupId>
  <artifactId>sample-artifactB</artifactId>
  <version>1</version>
   <exclusions>
     <exclusion>
       <groupId>sample.group</groupId>
       <artifactId>sample-artifactAB</artifactId>
     </exclusion>
   </exclusions>
</dependency>

The problem with this approach is that I have to do this for every transitive dependency contributed by sample-artifactB.

Is there a way to use some sort of wildcard to exclude all transitive dependencies at once instead of one-by-one?

12 Answers

For maven2 there isn't a way to do what you describe. For maven 3, there is. If you are using maven 3 please see another answer for this question

For maven 2 I'd recommend creating your own custom pom for the dependency that has your <exclusions>. For projects that need to use that dependency, set the dependency to your custom pom instead of the typical artifact. While that does not necessarily allow you exclude all transitive dependencies with a single <exclusion>, it does allow you only have to write your dependency once and all of your projects don't need to maintain unnecessary and long exclusion lists.

One thing I have found useful:

If you put the dependency with the exclusions in the dependencyManagement section of either the parent POM for your project, or in an importable dependency management POM, then you don't need to repeat the exclusion (or the version).

For example, if your parent POM has:

<dependencyManagement>
    <dependencies>
    ...         
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.2.1</version>
            <exclusions>
                <exclusion>
                    <groupId>junit</groupId>
                    <artifactId>junit</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
     ....
  </dependencies>
</dependencyManagement>

Then the modules in your project can simply declare the dependency as:

        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
        </dependency>

The in the parent POM will specify both the version and the exclusions. I use this technique for nearly all of our projects and it eliminates a lot of repetition.

There is a workaround for this, if you set the scope of a dependency to runtime, transitive dependencies will be excluded. Though be aware this means you need to add in additional processing if you want to package the runtime dependency.

To include the runtime dependency in any packaging, you can use the maven-dependency-plugin's copy goal for a specific artifact.

What is your reason for excluding all transitive dependencies?

If there is a particular artifact (such as commons-logging) which you need to exclude from every dependency, the Version 99 Does Not Exist approach might help.


Update 2012: Don't use this approach. Use maven-enforcer-plugin and exclusions. Version 99 produces bogus dependencies and the Version 99 repository is offline (there are similar mirrors but you can't rely on them to stay online forever either; it's best to use only Maven Central).

Related