Cucumber task not honoring toolchain

I have the following gradle task for cucumber (which is more or less the same as mentioned on the cucumber website).

task cucumber() {

    dependsOn assemble, testClasses
    def jacocoAgent = zipTree(configurations.jacocoAgent.singleFile).filter { it.name == "jacocoagent.jar" }.singleFile
    doLast {
        javaexec {
            main = "io.cucumber.core.cli.Main"
            classpath = configurations.cucumberRuntime + sourceSets.main.output + sourceSets.test.output
            jvmArgs = ["-javaagent:$jacocoAgent=destfile=$buildDir/jacoco/cucumber.exec,append=false"]
            args = ['--plugin', 'pretty', 'src/test/resources/features', '--glue', 'foo.bar.baz.cucumber.glue', '--glue', 'foo.bar.baz.cucumber.config']
        }
    }
}

Now we started (or starting) to use the toolchains to support java17 and run Gradle with java 11 and not to have to install java 17 ourselves. Compilation and regular tests run fine, but the cucumber stuff is using the JDK used to run gradle (which is 11, and thus fails with an unsupported class version).

I tried the solution as given on Shouldn't JavaExec default to using the project's toolchain if any? · Issue #16791 · gradle/gradle · GitHub

tasks.withType<JavaExec>().configureEach {
    javaLauncher.set(javaToolchains.launcherFor(java.toolchain))
}

But that doesn’t appear to work or being called at all.

According to the docs we should be able to set the javaLauncher property on the JavaExec directly but when doing so the build fails with an unknown property.

task cucumber() {

    dependsOn assemble, testClasses
    def jacocoAgent = zipTree(configurations.jacocoAgent.singleFile).filter { it.name == "jacocoagent.jar" }.singleFile
    doLast {
        javaexec {
            javaLauncher.set(javaToolchains.launcherFor(java.toolchain))
            main = "io.cucumber.core.cli.Main"
            classpath = configurations.cucumberRuntime + sourceSets.main.output + sourceSets.test.output
            jvmArgs = ["-javaagent:$jacocoAgent=destfile=$buildDir/jacoco/cucumber.exec,append=false"]
            args = ['--plugin', 'pretty', 'src/test/resources/features', '--glue', 'foo.bar.baz.cucumber.glue', '--glue', 'foo.bar.baz.cucumber.config']
        }
    }
}

This fails with

* What went wrong:
Execution failed for task ':cucumber'.
> Could not set unknown property 'javaLauncher' for object of type org.gradle.process.internal.DefaultJavaExecAction_Decorated.

So now I’m at a bit of a loss how to fix this for this task? Any pointers or obvious mistakes?

Is there any reason you are not using a task of type JavaExec, for which the withType and also the manual setting would have worked?

You are using a task of type DefaultTask where you use the javaexec { ... } method at task execution to do what a JavaExec task also would have done.

But at least from the shown snippet I don’t see any reason. You usually do this if you want to do multiple actions and one of them is the java exec, or if you register an additional action to an existing task.

But if the only execution time action is to call javaexec, there are only seldom cases where you couldn’t simply use a JavaExec task.

And if you insist on using or need to use the javaexe { ... } method, don’t try to set the toolchain tool, just set the executable like

executable javaToolchains.launcherFor(java.toolchain).get().executablePath