155

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.

Mahozad
  • 18,032
  • 13
  • 118
  • 133
Jens D
  • 4,229
  • 3
  • 16
  • 19

8 Answers8

191

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?

Top-Master
  • 7,611
  • 5
  • 39
  • 71
Jens D
  • 4,229
  • 3
  • 16
  • 19
  • 2
    This seems like better discussion for the [Gradle forums](http://forums.gradle.org/gradle). – superEb Feb 13 '14 at 21:28
  • So done - http://forums.gradle.org/gradle/topics/what_exactly_is_a_module_as_defined_by_gradle_dependencies – Jens D Feb 13 '14 at 21:53
  • 19
    Ugh, I just struggled with this exact issue. I find it so exceptionally difficult to do anything with gradle, especially resolve conflicts on a large project. I'd happily take verbose xml with xsd validation over gradle's dsl – cjbooms Apr 22 '16 at 14:54
  • 2
    The "name:" should be "module:", then it will work for u :) – GuyK Nov 19 '16 at 00:07
  • 1
    For the benefit of future me and others, I wanted to exclude ALL dependency libraries (Gradle 3.3) from my war package. So rather than list out each one, I simply did `configurations { runtime.exclude group: '*' }`. – sfdurbano Mar 02 '17 at 13:57
  • 1
    there is no name object, I had to use `module`. example : `exclude group: "org.apache.logging.log4j", module: "log4j-slf4j-impl"` – prayagupa Oct 23 '20 at 00:39
  • Type com.facebook.react.bridge.ReactMethod is defined multiple times How can I solve this – Nifal Nizar Dec 23 '20 at 16:04
  • this can still cause an issue if other dependencies have same transitive dependency, use configuration exclude instead https://stackoverflow.com/a/48968390/4781155 – mark ortiz Jan 30 '21 at 04:28
73

For excluding one or more library globally add the following to your build.gradle

configurations.all {
   exclude group:"org.apache.geronimo.specs", module: "geronimo-servlet_2.5_spec"
   exclude group:"ch.qos.logback", module:"logback-core"
}

Now the exclude block has two properties group and module. For those of you coming from maven background, group is same as groupId and module is same as artifactId. Example: To exclude com.mchange:c3p0:0.9.2.1 following should be exclude block

exclude group:"com.mchange", module:"c3p0"
venom.unleashed
  • 831
  • 7
  • 6
35

Your approach is correct. (Depending on the circumstances, you might want to use configurations.all { exclude ... }.) If these excludes really exclude more than a single dependency (I haven't ever noticed that when using them), please file a bug at http://forums.gradle.org, ideally with a reproducible example.

Peter Niederwieser
  • 121,412
  • 21
  • 324
  • 259
29

in the example below I exclude

spring-boot-starter-tomcat

compile("org.springframework.boot:spring-boot-starter-web") {
     //by both name and group
     exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat' 
}
Jan Galinski
  • 11,768
  • 8
  • 54
  • 77
BERGUIGA Mohamed Amine
  • 6,094
  • 3
  • 40
  • 38
13

I was using spring boot 1.5.10 and tries to exclude logback, the given solution above did not work well, I use configurations instead

configurations.all {
    exclude group: "org.springframework.boot", module:"spring-boot-starter-logging"
}
mark ortiz
  • 659
  • 1
  • 6
  • 13
8

In addition to what @berguiga-mohamed-amine stated, I just found that a wildcard requires leaving the module argument the empty string:

compile ("com.github.jsonld-java:jsonld-java:$jsonldJavaVersion") {
    exclude group: 'org.apache.httpcomponents', module: ''
    exclude group: 'org.slf4j', module: ''
}
Arnold Schrijver
  • 3,588
  • 3
  • 36
  • 65
7

compile is deprecated and it was replaced by implementation. Therefore, the solution for those running newer versions of gradle:

implementation("org.springframework.boot:spring-boot-starter-web") {
     exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat' 
}
Peter Chaula
  • 3,456
  • 2
  • 28
  • 32
1

This is for Kotlin DSL (build.gradle.kts) which prevents you from using wrong properties.

Exclude the library from all configrations (implementation, runtimeOnly, etc.):

configurations.all {
    exclude(group = "ir.mahozad.android", module = "pie-chart")
    // OR exclude("ir.mahozad.android", "pie-chart")
}

// Another notation:
// configurations {
//     all {
//         exclude(group = "ir.mahozad.android", module = "pie-chart")
//     }
// }

Exclude the library from a single configuration (like implementation):

configurations.implementation {
    exclude(group = "ir.mahozad.android", module = "pie-chart")
}

// Another notation:
// configurations {
//     implementation {
//         exclude(group = "ir.mahozad.android", module = "pie-chart")
//     }
// }

Exclude the library for a single dependency:

dependencies {
    // ...
    implementation("ir.mahozad.android:charts:1.2.3") {
        exclude(group = "ir.mahozad.android", module = "pie-chart")
    }
}
Mahozad
  • 18,032
  • 13
  • 118
  • 133