Exclude dependency globally via Rule and declare one or more exceptions based on e.g. a configuration name

Hi,

at the moment I’ll remove commons-logging from all my dependencies like this, because I ship everywhere a logging bridge which does provide that code and I used all { … } because I don’t want to check all my deps if they may bring that logging dep:

dependencyResolutionManagement {
	components {
		all {
			allVariants {
				withDependencies {
					removeAll {
						it.group in ["commons-logging"]
					}
				}
			}
		}
	}
}

Now I got one subproject, which has a configuration, lets name it A, which has an artifact declared with commons-logging as dependency and here I want to make an exception - reason does not matter - that if it is from that config, leave it alone and use it as is.

Reading through the docs and examples I found it seems impossible to declare that exception, correct?

What alternative do I have to let this happen, I want to remove it everywhere but also want to declare exceptions where I want it, I don’t want to switch to a whitelist and use withModule(xx:yy) { … } because I would be forced to declare all modules which may bring that dependency … which is, looking at my dep graph, not a nice task to maintain.

Ideas anyone? Alternatives?

I recommend that instead you declare that the bridge and JCL provide the same capability by adding capabilities instead.
Then if only one of the two is present, it stays, if both are there somewhere you get a conflict and can pick which to use.

I’d recommend using the JVM Dependency Conflict Detection and Resolution plugins plugin for that, as it has the matching component metadata rules already in and many more common ones and also allows to easily pick or add other rules more conveniently, for example if your bridge is not one of the ones already handled.

Nice idea with that plugin, I’ll try that.

But just for the record, how could it be done without that plugin just with the rule stuff, is there a way to access a configuration name there?

With the construct you showed, you are correcting the metadata of a published library.
This metadata is not different per configuration, it is the metadata of the library.
This is more for cases like a missing declared dependency or some superfluous declared dependency, cases that are always true for said library.
Using it to “exclude” the transitive library is more an abuse of the functionality and you cannot do it configuration-specific.

The idiomatic way is to cause a capability conflict between the two libs that provide the same capability (implementation and bridge-lib) and then solve the conflict however you need it for each conflict case, which is exactly what that library is doing for you / helping to do.

Ok, point taken.
One last final question for the alternative provided, how can I access the gradle catalog in the plugins callback, e.g. when I do:

		patch {
			module("org.odftoolkit:odfdom-java") {
				removeDependency("org.json:json")
				addRuntimeOnlyDependency("com.vaadin.external.google:android-json")
			}
		}

that won’t work because it want to have a version specified for the vaadin lib, I did declare that in my project BOM (libs.versions.toml) - is there a declaration to force the plugin to take that into account or to explicity tell the callback to look there, ideas?

Looking though open issues I found:

Seems that is on the TODO list, correct?

Not fully sure what you mean, especially as the issue you posted seems unrelated to your question as well as I don’t know what you mean with “plguins callback” in this context.

But if you need a defined version from your version catalog, you can for example do addRuntimeOnlyDependency("com.vaadin.external.google:android-json:${libs.versions.vaadin.get()}"), or addRuntimeOnlyDependency(libs.vaadin.map { "${it.group}:${it.name}:${it.version}" }.get()), and maybe request that those methods also support version catalog accessors which probably makes a lot of sense.

The question was, that I would like to just use:

addRuntimeOnlyDependency(“com.vaadin.external.google:android-json”)

and the plugin would use the declared dep in the

[libraries]

section of my catalogue either automatically if found or I could tell via some callbacks in the plugin DSL (something like lookupVersionsFromCatalogue() … ) that it should look there or like you said, use “version catalog accessors” which it does not support yet, like you’ve written.

I highly doubt the alternatives you mentioned would ever be implemented, as they are also pretty much against the sense of a version catalog. Just putting something in there never has any effect. It is just a catalog to pick from. If you don’t pick using an accessor, it has no influence on any dependencies anywhere.

Having methods that receive such an accessor would imho make sense as I said and you should definitely request them being added. I’ll thumb-up the issue after you reported it.

Why that, that is what the linked ticket does propose, no?

Use something in the DSL like:

platform(:my-root-project)

which could than take the catalogue as a platform / BOM reference so you can specify your modules / artifacts without version at all, why would / should that be a problem to be implemented?

No, not at all.
It proposes to port some feature from the other plugin that I do not even find in that plugin.
But from the short shown snippet, I’d say it is for using consistent resolution rules and additionally taking versions from some platform project.
A platform project is not a version catalog.
A platform is like a BOM and where used does influence dependency resolution and versions.
A version catalog is just a catalog to pick from if you feel so.

Feel free to request a feature that takes the versions from a version catalog automatically by string, but I don’t think it makes sense and hope it will not get accepted as it is against the philosophy of version catalogs. Being able to use a version catalog accessor as argument instead of a string on the other hand fits perfectly well, that’s why I suggested you post a feature request for that. :slight_smile:

Thanks for the insights, will requests that feature :slight_smile:

1 Like