## JVM bytecode level selection with kotlin and gradle
Given the following problem:
* a [Gradle]-[kotlin] multimodule project
* several modules containing [kotlin] code
* targetting the [JVM]
* developed locally with a JDK-21 and on the build server with a JDK-17, targetting both JRE 11 and JRE 17.
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
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.