I’m trying to exclude a transitive dependency via ...
# community-support
d
I’m trying to exclude a transitive dependency via
Copy code
implementation(libs.foo) {
   exclude("group", "module")
}
But it's still listed in :dependencies task. It's a second in line dependency. So foo depends on bar, and bar has a dependency I want to exclude, is that perhaps the reason? The dependency doesn't reference logback in its code, yet taints the classpath with it.
v
Besides that it should work, a component metadata rule would be the better idea. `exclude`s are always the big hammer, while component metadata rules are the scalpel to fix up erroneous metadata of dependencies. If you could share a build
--scan
URL, it could clarify why the exclude is not effective. Probably it comes in in some other way. The
dependencyInsight
task could also help to investigate where it is coming from if you cannot create a build scan.
d
Should have waited to ask a bit longer, came up with this:
Copy code
configurations.all {
	exclude("org.slf4j", "slf4j-api")
	exclude("ch.qos.logback", "logback-core")
	exclude("ch.qos.logback", "logback-classic")
}
Which excludes it fully.
v
Sure, but same comment, better use component metadata rules to fix up the broken dependency metadata šŸ™‚
d
As mentioned, the library that has these dependencies don't use them, so it's just an upstream bug.
v
And most important, report to the dependency so they can fix up their metadata
d
Ah, I'll look into that, thanks.
Dead dep I'm afraid, reported it to the first-in-line project though.
v
If it's dead, replace it šŸ˜„
d
Well, the first in line isn't dead. It's open-gif, a single file project, that scrimage depends on. Filed an issue in scrimage about it.
Humm... so something like this is the recommended way?
Copy code
// scrimage depends on open-gif which incorrectly taints the classpath
// with an old version of logback which no library should ever do as
// it's a logging backend, and in this case it doesn't even reference
// any logback related classes even so nuke it.
@CacheableRule
abstract class OpenGif : ComponentMetadataRule {
	override fun execute(context: ComponentMetadataContext) = context.details.allVariants {
		withDependencies {
			removeAll { it.group in listOf("org.slf4j", "ch.qos.logback") }
		}
	}
}

dependencies {
	components {
		withModule<OpenGif>("com.github.zh79325:open-gif")
	}
	implementation(libs.scrimage.core)
	implementation(libs.scrimage.filters)
}
Is it possible to turn that into something more reusable like:
Copy code
withModule<DependencyKiller>("group:module", listOf("a", "b", "c"))
v
Humm... so something like this is the recommended way?
Yes. Alternatively you could also do it in the settings script. Or you could use the https://github.com/gradlex-org/jvm-dependency-conflict-resolution plugin which defines many helpful capability rules and provides syntactic sugar over plain component metadata rules.
Is it possible to turn that into something more reusable like:
Yes, you can give parameters to metadata rules, this is also covered in the docs I linked you to. Or you just use the plugin I just referenced šŸ™‚
d
My bad, easy to browse past a bit too quickly. Thanks for your help as always.
šŸ‘Œ 1