Examples here don't seem to work: <https://docs.gr...
# community-support
s
Examples here don't seem to work: https://docs.gradle.org/current/userguide/toolchains.html
Copy code
def launcher = javaToolchains.launcherFor {
    languageVersion = JavaLanguageVersion.of(23)
}

tasks.named('anotherSampleTask') {
    javaHome = launcher.map { it.metadata.installationPath }
}
I don't get something I can use as a path to Java Home.
v
Can you elaborate? What does not work? What did you get? Can you share an MCVE?
s
I attempted to quickly hack together a task that calls `jlink`(I realize this isn't the best way to do this, it's just an example):
Copy code
def launcher = javaToolchains.launcherFor {
    languageVersion = JavaLanguageVersion.of(23)
}

task jlink(type:Exec) {
    def javaHome = launcher.map { it.metadata.installationPath }
    commandLine "${javaHome}/bin/jlink", "--help"
}
This results in an error:
Copy code
> A problem occured starting process 'command 'map(map(provider(?) (with side effect org.gradle.jvm.toolchain.internal.DefaultJavaToolchainService$$Lambda/0x000001929b9ef6b8@4a4d92c8)))/bin/jlink''
v
launcher.map
leaves you with a provider, you need to
.get()
it to get the actual value
Also, I strongly recommend switching to Kotlin DSL. By now it is the default DSL, you immediately get type-safe build scripts, actually helpful error messages if you mess up the syntax, and amazingly better IDE support if you use a good IDE like IntelliJ IDEA or Android Studio.
This might have made you aware of the type-problem yourself 🙂
s
Thank you. A more complete example would also have helped 😄 . Migrating build scripts to a new language is a big disruptive change. I will eventually get there, but I don't use IntelliJ or Android Studio, I've tried IntelliJ, but I just don't like it. I use NetBeans, which is great for Gradle/Java, but less so for Kotlin.
t
From the doc you linked:
WARNING
The examples above use tasks with RegularFileProperty and DirectoryProperty properties which allow lazy configuration. Doing respectively launcher.get().executablePath, launcher.get().metadata.installationPath or compiler.get().executablePath instead will give you the full path for the given toolchain but note that this may realize (and provision) a toolchain eagerly.
☝️ 1
👍 1
s
I read it, I just didn't fully appreciate what it was saying, it was particularly confusing as that
get()
in the warning is placed before the
.metadata.installationPath
so intuitively I thought the
map { it.metadta.installationPath }
was handling it.
v
myProvider.map { it.foo }.get()
==
myProvider.get().foo
Doing either is fine at execution time.
At configuration time you want to avoid using
get()
at all and instead map and wire things
s
How would my jlink example work while avoiding calling
get()
?
v
Probably many ways. One would be to not make a task of type
Exec
, but instead use
exec { ... }
at execution time
Another would be to set the
executable
to something that does the
get()
in its
toString()
so that it at least is delayed as far as possible
Probably with Gradle 9, you can set a provider as
executable
hopefully