It seems that setting `kotlin.jvmToolchain(8)` imp...
# gradle
e
It seems that setting
kotlin.jvmToolchain(8)
implies I have a JDK 8 on my machine. I don't get why an higher JDK (e.g., 17) is not picked up automatically. Is this an expected behavior?
h
The toolchain property does exactly this: it uses a JVM with the version you specified. If you want to use a higher JVM but use JVM 8 as target code, use the target property.
e
@hfhbd Thanks! Apparently my problem is I'm also configuring Java with
kotlin.jvm.withJava()
This might mean, besides setting
jvmTarget = "1.8"
, I also need to change the target version for the Java compilations
h
I don’t get it.
withJava
applies the java Gradle plugin. Do you really need this plugin? The Kotlin compiler is able to compile Java source code too. And setting the release option in the JVM toolchain function should be enough, it should set up the Java and Kotlin compiler options correctly.
e
Do you really need this plugin
Good question. Not really, I can remove the call. But to understand the error I was getting, take this sample setup
Copy code
kotlin.jvmToolchain(17)
kotlin.jvm {
  withJava()

  compilations.configureEach {
    kotlinOptions {
      jvmTarget = "1.8"
  ...
With the above you get
Copy code
> 'compileJava' task (current target is 17) and 'compileKotlinJvm' task (current target is 1.8) jvm target compatibility should be set to the same Java version.
  Consider using JVM toolchain: <https://kotl.in/gradle/jvm/toolchain>
Removing
withJava
obviously makes it compile correctly.
h
Well, you applied the Java plugin and the Java compiler explicitly. The Java target is JvM 17 due to the toolchain, which sets up the target automatically, but you specify the Kotlin JVM target to 1.8 only, so there is a mismatch. Either remove the Java plugin, if you don’t need it, or setup the Java target too.
e
Removed the Java plugin, so it's done. Thanks!
v
Alternatively, you could simply set the toolchain in
java { toolchain...
, then the Kotlin plugin also picks it up and the tasks are configured consistently.
If you set toolchains, not only compliation tasks use that toolchain, but also test tasks and so on. And also it makes sure that compilation happens against the correct API. For example in Java 13 the API of some
ByteBuffer
methods changed in a binary incompatible way as the return type changed from
Buffer
to
ByteBuffer
. If you now compile some code that uses these methods with Java 13+ but target Java 8, your classes can run on Java 8 class-version wise, but will fail if the code path that uses those methods is executed as you will get exception about missing method while it works fine on Java 13+.
But setting a toolchain does not necessarily mean you need to have the target toolchain installed, Gradle can auto-provision the needed JVM toolchains, you just need to apply one settings plugin that configures where to auto-provision the toolchains from like documented. 🙂
c
you just need to apply one settings plugin that configures where to auto-provision the toolchains from like documented.
Can you clarify where that is documented? I've seen people mention this multiple times but I've never seen what exactly needs to be done
v
In the docs about toolchains. You need to apply the foojay resolver plugin. Don't get confused by the "foo" in the name, this is not a made-up example but a real thing.
c
Thanks. Am I correct that this is not needed for Gradle 7 and lower, and Gradle 8 will work fine without it as long as it can find the toolchains locally?
v
In Gradle 7 some resolver is built-in, but afair only for Adoptium toolchains. I'm not sure whether the resolver plugin would also work in Gradle 7 or whether it was added in 8. But yeah, it should work fine in 7 and 8 as long as an Adoptium toolchain can satisfy the dependencies and you ignore the warning in 8, will probably fail in 9. And yes, all this is only for auto-provisioning. If the necessary toolchain is already auto-provisioned by some other build, or otherwise available locally and detected, it works without. You can even disable auto-provisioning if you like.
gratitude thank you 1
e
Thanks everyone! I've setup the foojay plugin and now I can see it downloads JDKs automatically in the CI machine
👌 1