I have a library which is written in Java 8 and it is consumed by some projects which are in Java 11, therefore when building the consumer projects some packages are missing like in this stack overflow thread.
One of the fixes is adding
in my library’s
build.gradle. Is it possible to conditionally attach those dependencies only if the consumer Java version is 11?
Forgive me if this question is ridiculously stupid but I’ve been working with Gradle for only 3 weeks now.
If your consumers are Gradle builds, you can use variant aware resolution: Gradle User Manual: Version 6.8.3
Those docs have an example of different dependencies for Java 8 and Java 9+.
Maybe start reading further up in the docs to get an understanding of the whole feature.
To be honest with the knowledge I currently have, it is nearly impossible for me to figure it out only basing on the documentation. While reading the docs I feel like it assumes some things to be trivial for the reader which are not (in my case). As you said it mentions the possibility of having two variants with the attribute
org.gradle.jvm.version set differently but that’s all. There are no examples as to how to declare variants (I only mangaed to declare attributes for a configuration but when I print the
outgoingVariants task it only shows the
Did you start to read at the link or earlier as I advised?
I did start reading earlier. I have tried something and I think I’ve managed to specify a feature variant and declare an attribute to it (
TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE to 11).
Below is the producer build script
sourceCompatibility = 1.8
and in my outgoingVariants I can see both
java11ConfigApiElements like this
yet still my consumer seems to pick those default ones -
runtimeElements despite being in Java 11. (I’m deducing that basing on its dependencies, it has
org.slf4j:slf4j-api:1.7.30 in its runtimeClasspath)
Could you shed some light as to why this works different than I expect?
You don’t need to deduce, I think you should see exactly what variant is chosen if you utilize the
dependencyInsight task on the consumer.
So just as I thought. Now I’m even more confused. In the documentation part about
org.gradle.jvm.version. in the compatibility and disambiguation rules it says
Defaults to the JVM version used by Gradle, lower is compatible with higher, prefers highest compatible. Shouldn’t it match the variant with the highest available version? (assuming every other attribute is the same)
org.gradle.jvm.version. attribute be specified in the consumer as well or is it automatically set by gradle?
From a quick look, I believe the issue is that you set the Java 11 attribute value only on the
java11ConfigRuntimeElements but not on the
dependencyInsight looks at
Could you verify what happens for the
runtimeClasspath of the consumer?
Also, are those two projects in the same build or do you use publication in between?
If the later, looking at the produced metadata might help confirm the additional variants are indeed published.
Looks like this other thread has the right answer: adding a feature variant is done by adding a capability.
See that other thread for more information.