blog-2024-02-09-bytecode-version

JVM bytecode level selection with kotlin and gradle

Given the following problem:

toolchain selection does not equal bytecode level selection. i had the problem that locally, i was using a JDK 21 while having all other JDKs (1.8, 11, 17, 21 and various graalvm) installed. one user required JRE 11 (bytecode level 55) compatibility, while a server application from the same project had to run on a JRE 17.

setting gradle's toolchain selection for the kotlin plugin to 11 worked locally but failed on the build server, which used an JDK 17 image.

the solution that finally worked was defining the following properties for every module:

kotlin {
    compilerOptions {
        // 11 for all libraries and 17 for the one server module
        jvmTarget.set(JvmTarget.JVM_11)
    }
}

java {
    // 11 for all libraries and 17 for the one server module
    targetCompatibility = JavaVersion.VERSION_11
}

what doesn't work

kotlin {
    jvmToolchain(11)
}

this works locally, where JDK 11 is among the JDKs installed, but fails on the build server where the only JDK present is 17 (so no automatic 17-to-11 compatibility assumption).

several factors are at play here:

  1. the bytecode version generated by the kotlin compiler
  2. the bytecode version generated by the java compiler
  3. the java toolchain used

while i got it to work i feel like i'm stuck in a dangerous half-knowledge state.


nothing's linking here.

last edited by: stefs at Friday, February 9, 2024, 12:32:21 PM Central European Standard Time


edit history source