If I declare a dependency on an artifact that has ...
# dependency-management
i
If I declare a dependency on an artifact that has multiple variants, and two of them qualify for my needs, and their only difference is through an attribute that I don't mention in my project, what happens? Does Gradle crash because there are more than 1 possible variants? Does Gradle somehow select one of them? If it's the other solution, as a library author, can I pre-select which one of them is the "default" to use when the user hasn't specified anything?
v
Depends on which attribute you are talking about. But no, if two variants match then Gradle will bail and error-out not able to decide which to use. For further information, here the variant selection algorithm is described: https://docs.gradle.org/current/userguide/variant_model.html
i
Thanks. Is there a way a library author can provide two otherwise conflicting variants and mention which one should be preferred by default if Gradle doesn't care? For example, I want to publish a library with a production and a debug build. However, the Java plugin doesn't have an attribute for this that is set by default, so if I publish both variants, Gradle won't know which to use, and will error-out, right?
v
I think so, yes, but you can easily TIAS. I'm not aware of such a "default" setting, that is not really matching the architecture I guess. If your variants have different capabilities (the default) then the debug variant will anyway just be chosen if that capability is selected explicitly by the consumer. If you configured both variants to have the same capability but different attributes, then the consumer has to request according attributes. If you invent an own attribute, that is not a decision you should do lightly. New attributes are usually more created by ecosystems where you then usually also have a plugin for it applied in the consumer that registers the attribute and also configures compatibility and disambiguation rules. The latter is what would say "if there are two variants one with value true for attribute X and one with value false for attribute X then take the one with false". But that is something set in the consumer, for example by an according plugin as I said.
🙏 1
i
What's TIAS?
v
try it and see
🙂
i
Ah. Well, observed behavior tends to change more often than documented behavior. Thanks for the link 🙂 I think my mental model for variants is starting to be good enough, but I need to study capabilities more.
v
Capabilities are for things like "give me the variant that supports Oracle DB" or "give me the variant that integrates with library X". Attributes are more for things like "give me the variant I need at compile time", "give me the variant I need at runtime", or "give me the variant I need when I'm on Java 9 or newer".
i
So, capabilities would be optional features? For example, a library could have two different implementations, and the user must explicitly choose one? Whereas, attributes are about technical incompatibilities that Gradle knows how to fix because only one variant "makes sense", e.g. a library that exposes a Java and a C versions under the same artifact?
p
Yes
m
If it’s the other solution, as a library author, can I pre-select which one of them is the “default” to use when the user hasn’t specified anything?
If you own a Gradle plugin you can do some stuff using disambiguation (or your users can do it if you tell them how to)