javagradlebuild.gradlegradle-kotlin-dslgradle-dependencies

How do I exclude all instances of a transitive dependency when using Gradle?


My gradle project uses the application plugin to build a jar file. As part of the runtime transitive dependencies, I end up pulling in org.slf4j:slf4j-log4j12. (It's referenced as a sub-transitive dependency in at least 5 or 6 other transitive dependencies - this project is using spring and hadoop, so everything but the kitchen sink is getting pulled in... no wait... that's there too :) ).

I want to globally exclude the slf4j-log4j12 jar from my built jar. So I've tried this:

configurations {
  runtime.exclude group: "org.slf4j", name: "slf4j-log4j12"
}

However, this seems to exclude all org.slf4j artifacts including slf4j-api. When running under debug mode I see lines such as:

org.slf4j#slf4j-api is excluded from com.pivotal.gfxd:gfxd-demo-mapreduce:1.0(runtime).
org.slf4j#slf4j-simple is excluded from com.pivotal.gfxd:gfxd-demo-mapreduce:1.0(runtime).
org.slf4j#slf4j-log4j12 is excluded from org.apache.hadoop:hadoop-common:2.2.0(runtime).

I do not want to have to look up the source of each slf4j-log4j12 transitive dependency and then have individual compile foo { exclude slf4j... } statements in my dependencies block.

Update:

I did also try this:

configurations {
  runtime.exclude name: "slf4j-log4j12"
}

Which ends up excluding everything from the build! As though I specified group: "*".

Update 2:

I'm using Gradle version 1.10 for this.


Solution

  • Ah, the following works and does what I want:

    configurations {
      runtime.exclude group: "org.slf4j", module: "slf4j-log4j12"
    }
    

    It seems that an Exclude Rule only has two attributes - group and module.
    Hence for excluding from only an individual dependency, we can do something like:

    dependencies {
      compile ('org.springframework.data:spring-data-hadoop-core:2.0.0.M4-hadoop22') {
        exclude group: "org.slf4j", module: "slf4j-log4j12"
      }
    }
    

    However, the above syntax doesn't prevent you from specifying any arbitrary property as a predicate. When trying to exclude from an individual dependency you cannot specify arbitrary properties. For example, this fails:

    dependencies {
      compile ('org.springframework.data:spring-data-hadoop-core:2.0.0.M4-hadoop22') {
        exclude group: "org.slf4j", name: "slf4j-log4j12"
      }
    }
    

    with

    No such property: name for class: org.gradle.api.internal.artifacts.DefaultExcludeRule
    

    So even though you can specify a dependency with a group: and name: you can't specify an exclusion with a name:!?!

    Perhaps a separate question, but what exactly is a module then? I can understand the Maven notion of groupId:artifactId:version, which I understand translates to group:name:version in Gradle. But then, how do I know what module (in gradle-speak) a particular Maven artifact belongs to?