Use javac -release and kotlinc -Xjdk-release (#1080)

The change ensures the generated bytecode adheres to the APIs
for the target Java release.

Previously, only sourceCompatibility and targetCompatibility were used,
and they might cause issues like NoSuchMethodError when a newer javac
compiles with -target older_release.

Note: it is good to use a new an up to date javac to avoid issues
in the compiler itself, so having a proper `-release ..` configuration
is vital.

See https://www.morling.dev/blog/bytebuffer-and-the-dreaded-nosuchmethoderr
This commit is contained in:
Vladimir Sitnikov
2025-05-28 19:38:53 +03:00
committed by GitHub
parent a19e6bf684
commit 7d50c46c29
4 changed files with 15 additions and 18 deletions

View File

@@ -35,16 +35,18 @@ dependencies {
} }
java { java {
sourceCompatibility = JavaVersion.toVersion(toolchainVersion)
targetCompatibility = JavaVersion.toVersion(toolchainVersion)
toolchain { toolchain {
languageVersion = JavaLanguageVersion.of(toolchainVersion) languageVersion = JavaLanguageVersion.of(toolchainVersion)
vendor = JvmVendorSpec.ADOPTIUM vendor = JvmVendorSpec.ADOPTIUM
} }
} }
tasks.withType<JavaCompile>().configureEach { options.release = toolchainVersion }
kotlin { kotlin {
jvmToolchain(toolchainVersion) jvmToolchain(toolchainVersion)
compilerOptions { jvmTarget = JvmTarget.fromTarget(toolchainVersion.toString()) } compilerOptions {
jvmTarget = JvmTarget.fromTarget(toolchainVersion.toString())
freeCompilerArgs.add("-Xjdk-release=$toolchainVersion")
}
} }

View File

@@ -16,7 +16,7 @@
import com.diffplug.gradle.spotless.KotlinGradleExtension import com.diffplug.gradle.spotless.KotlinGradleExtension
import org.gradle.accessors.dm.LibrariesForLibs import org.gradle.accessors.dm.LibrariesForLibs
import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile
plugins { id("com.diffplug.spotless") } plugins { id("com.diffplug.spotless") }
@@ -52,15 +52,14 @@ configurations.all {
} }
plugins.withType(JavaPlugin::class).configureEach { plugins.withType(JavaPlugin::class).configureEach {
val java = project.extensions.getByType<JavaPluginExtension>() tasks.withType<JavaCompile>().configureEach { options.release = 17 }
java.sourceCompatibility = JavaVersion.VERSION_17
java.targetCompatibility = JavaVersion.VERSION_17
} }
tasks.withType<KotlinCompile>().configureEach { tasks.withType<KotlinJvmCompile>().configureEach {
compilerOptions { compilerOptions {
jvmTarget = JvmTarget.JVM_17 jvmTarget = JvmTarget.JVM_17
freeCompilerArgs.addAll("-Xjsr305=strict", "-Xjvm-default=all") freeCompilerArgs.addAll("-Xjsr305=strict", "-Xjvm-default=all")
freeCompilerArgs.add("-Xjdk-release=17")
} }
} }

View File

@@ -34,14 +34,9 @@ val libs = the<LibrariesForLibs>()
val info = project.extensions.getByType<BuildInfo>() val info = project.extensions.getByType<BuildInfo>()
java { java {
val jvmTarget = JavaVersion.toVersion(info.jvmTarget)
withSourcesJar() // creates `sourcesJar` task withSourcesJar() // creates `sourcesJar` task
withJavadocJar() withJavadocJar()
sourceCompatibility = jvmTarget
targetCompatibility = jvmTarget
toolchain { toolchain {
languageVersion = info.jdkToolchainVersion languageVersion = info.jdkToolchainVersion
vendor = info.jdkVendor vendor = info.jdkVendor
@@ -112,10 +107,8 @@ tasks.compileJava {
} }
tasks.withType<JavaCompile>().configureEach { tasks.withType<JavaCompile>().configureEach {
val jvmTarget = JavaVersion.toVersion(info.jvmTarget)
javaCompiler = info.javaCompiler javaCompiler = info.javaCompiler
sourceCompatibility = jvmTarget.majorVersion options.release = info.jvmTarget
targetCompatibility = jvmTarget.majorVersion
} }
tasks.withType<JavaExec>().configureEach { jvmArgs(info.jpmsAddModulesFlags) } tasks.withType<JavaExec>().configureEach { jvmArgs(info.jpmsAddModulesFlags) }

View File

@@ -42,5 +42,8 @@ tasks.compileKotlin {
} }
tasks.withType<KotlinJvmCompile>().configureEach { tasks.withType<KotlinJvmCompile>().configureEach {
compilerOptions { jvmTarget = JvmTarget.fromTarget(buildInfo.jvmTarget.toString()) } compilerOptions {
jvmTarget = JvmTarget.fromTarget(buildInfo.jvmTarget.toString())
freeCompilerArgs.addAll("-Xjdk-release=${buildInfo.jvmTarget}")
}
} }