Excluding dependency from a single configuration

Hi,

I’m having difficulties configuring a build so a transitive dependency is excluded in one configuration, but present in another one. I created a simple build.gradle file that I can use to reproduce the problem.

For instance, if I declare a compile dependency on quartz, which transitively depends on slf4j-api, and explicitly exclude the slf4j-api dependency in the compile configuration, declaring a testRuntime dependency on slf4j-api doesn’t seem to work - looks like the testRuntime dependency is suppressed by the compile exclusion rule.

This is my build.gradle file:

 repositories {
     jcenter()
 }

 apply plugin: 'java'

 dependencies {
    compile group: 'org.quartz-scheduler', name: 'quartz', version: '2.3.0'
    configurations.compile.exclude(group: 'org.slf4j', module: 'slf4j-api')
    testRuntime group: 'org.slf4j', name: 'slf4j-api', version: '1.7.7'    
}

And the dependencies resolved by Gradle:

compile - Dependencies for source set 'main' (deprecated, use 'implementation ' instead).
\--- org.quartz-scheduler:quartz:2.3.0
     +--- com.mchange:c3p0:0.9.5.2
     |    \--- com.mchange:mchange-commons-java:0.2.11
     +--- com.mchange:mchange-commons-java:0.2.11
     \--- com.zaxxer:HikariCP-java6:2.3.13

testRuntime - Runtime dependencies for source set 'test' (deprecated, use 'testRuntimeOnly ' instead).
\--- org.quartz-scheduler:quartz:2.3.0
     +--- com.mchange:c3p0:0.9.5.2
     |    \--- com.mchange:mchange-commons-java:0.2.11
     +--- com.mchange:mchange-commons-java:0.2.11
     \--- com.zaxxer:HikariCP-java6:2.3.13

Is there any error with my configuration? Is Gradle resolving the dependencies as expected? How can I express the exclusion of a dependency in one configuration only, but not in others?

Thank you,

Douglas

1 Like

By the way, excluding the transitive dependency at the dependency level, instead of the configuration level, seems to have the expected result. After modifying the dependencies declaration to

dependencies {
    compile (group: 'org.quartz-scheduler', name: 'quartz', version: '2.3.0') {
        exclude group: 'org.slf4j', module: 'slf4j-api'
    }
    //configurations.compile.exclude(group: 'org.slf4j', module: 'slf4j-api')
    testRuntime group: 'org.slf4j', name: 'slf4j-api', version: '1.7.7'
}

I see the dependencies being resolved as I expect:

compile - Dependencies for source set 'main' (deprecated, use 'implementation ' instead).
\--- org.quartz-scheduler:quartz:2.3.0
     +--- com.mchange:c3p0:0.9.5.2
     |    \--- com.mchange:mchange-commons-java:0.2.11
     +--- com.mchange:mchange-commons-java:0.2.11
     \--- com.zaxxer:HikariCP-java6:2.3.13

+--- org.quartz-scheduler:quartz:2.3.0
|    +--- com.mchange:c3p0:0.9.5.2
|    |    \--- com.mchange:mchange-commons-java:0.2.11
|    +--- com.mchange:mchange-commons-java:0.2.11
|    \--- com.zaxxer:HikariCP-java6:2.3.13
\--- org.slf4j:slf4j-api:1.7.7

However, I don’t think this approach solves the original problem, as I still can’t have a configuration-wide exclusion - say the excluded library is a transitive dependency of multiple dependencies, I’d have to explicitly exclude it once for each of them.

Kind of an old post, but here’s how to do it for all dependencies in a single configuration.

buildscript{/*snip*/}

configurations {
    implementation {
        exclude(group: 'org.slf4j', module: 'slf4j-api')
    }
}

dependencies{/*snip*/}

Not that his is not inside the dependencies block.
If you want to exclude it from every configuration, just change implementation to all