Using variants and toolchains together

Hi,
I would like to use variants to produce two versions of the same software, one targeting Java 8+ and one targeting Java 11+. I am already using the toolchains to test with multiple versions of the JDK, but I must specify:

java {
    toolchain {
        languageVersion.set(JavaLanguageVersion.of(8))
    }
}

how do I tell Gradle that the Java 11+ variant, besides its dependency set, also should use the Java 11 toolchain?

I’m not sure what you mean.
If you configure the toolchain like you showed, the 11+ variant should already also use the Java 8 toolchain.

Sorry, my bad. I want the Java 11 variant to use the JVM v11. I edited the original post.

Ah, makes more sense then. :slight_smile:
Iirc, you just set a different toolchain for the compile task of that variant.

You could define an additional JavaCompile - Gradle DSL Version 7.6 task using examples from Using toolchains Sample :

tasks.register("compile11", type: JavaCompile) {
    javaCompiler = javaToolchains.compilerFor {
        languageVersion = JavaLanguageVersion.of(8)
    }
}

so you will have tasks for different versions simultaneously. But you need to define other related tasks, like packaging or testing:

task('tests14', type: Test) {
    javaLauncher = javaToolchains.launcherFor {
        languageVersion = JavaLanguageVersion.of(14)
    }
}

Or you could utilize -P key=val and embed key into:

JavaLanguageVersion.of(key)

This would be fine if I weren’t using variants. My understanding is that variants pre-generate compilation tasks; according to @Vampire (if I got it correctly), I only need to configure the compiler for these tasks.

Yes, you got me right.
The manual shenenigans @gavenkoa suggests are not needed when using proper feature variants as the feature variants already register and wire all necessary tasks.

Is there an example of variant redefinition for JavaCompiler version?

Modeling feature variants and optional dependencies (gradle.org)

Could I use anything supported in java when I inside registerFeature closure?

Could I use anything supported in java when I inside registerFeature closure?

No.
Well, you can, but will probably configure the main things, not the feature variant as having things inside is just the same as having them outside.
I strongly recommend using the Kotlin DSL, because then you have amazingly better IDE support and can properly see what is available where.

Is there an example of variant redefinition for JavaCompiler version?

No official: Example for automatic variant aware resolution for target Java version in docs · Issue #16908 · gradle/gradle · GitHub
The additional features register additional tasks, configure these tasks as you need them.
Don’t forget to set the capability of the additional variant so that a consuming Gradle project can automatically select the correct variant just depending on the Java version.