How do I exclude all instances of a transitive dependency when using Gradle?
JavaGradlebuild.gradleGradle Kotlin-DslGradle DependenciesJava Problem Overview
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.
Java Solutions
Solution 1 - Java
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?
Solution 2 - Java
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"
Solution 3 - Java
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.
Solution 4 - Java
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'
}
Solution 5 - Java
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"
}
Solution 6 - Java
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: ''
}
Solution 7 - Java
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'
}
Solution 8 - Java
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")
}
}