Upgrade JVM toolchain to 25 and Kotlin toolchain to 2.3.20 (#1516)

Motivation
- Enable correct NullAway analysis
- Pick up toolchain fixes and improvements

Toolchains
- Require JDK 25 for JVM toolchain (keep Java 17 runtime compatibility)
- Require Kotlin 2.3.20 for Kotlin toolchain (keep Kotlin 2.2 runtime
compatibility)
- Require JDK 25 for Gradle daemon JVM (via
gradle-daemon-jvm.properties)
- Fix javac and kotlinc warnings from toolchain upgrades

CI
- Bump GitHub workflows to JDK 25

Building Kotlin
- Bump Kotlin language level to 2.2 to match stdlib version
- Consolidate build logic into pklKotlinBase.gradle.kts
- Adopt modern Kotlin plugin syntax
- Fix new kotlinc warnings
- Update ktfmt to 0.62
  - first version compatible with Kotlin 2.3.20
  - changes formatting compared to 0.61
- Replace dependency resolution rule with BOM alignment
  - rule was too broad and interfered with toolchain/runtime separation

Testing
- Expand matrix to JDK 25 (LTS) and 26
- Ensure each matrix task can be run independently
- Fix KotlinCodeGeneratorsTest and EmbeddedExecutorsTest on affected
JDKs
- Disable one test in CliCommandTest on affected JDKs (failure cause
unknown)

Compatibility fixes
- Fix reflective access in DocGenerator on affected JDKs

Build fixes
- Fix misuse of `task.enabled` vs. `report.required`
- Fix `gradlew tasks` on Windows
- Downgrade Spotless to 8.3.0 to (hopefully) work around sporadic
NoClassDefFoundError

Result
- NullAway runs correctly
- Broader JDK test coverage
- More reproducible and potentially faster builds
This commit is contained in:
odenix
2026-04-14 11:57:09 -07:00
committed by GitHub
parent 20f403e751
commit 2d4286ee7b
49 changed files with 1347 additions and 1096 deletions
+27 -28
View File
@@ -1,5 +1,5 @@
/*
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
* Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,7 +20,6 @@ plugins {
pklAllProjects
pklJavaLibrary
pklPublishLibrary
pklKotlinTest
}
val pklDistributionCurrent: Configuration by configurations.creating
@@ -55,7 +54,7 @@ publishing {
description.set(
"""
Library for executing Pkl code in a sandboxed environment.
"""
"""
.trimIndent()
)
}
@@ -65,37 +64,37 @@ publishing {
sourceSets { main { java { srcDir("src/main/java") } } }
val prepareHistoricalDistributions by
tasks.registering {
val outputDir = layout.buildDirectory.dir("pklHistoricalDistributions")
inputs.files(pklHistoricalDistributions.files)
outputs.dir(outputDir)
doLast {
val distributionDir = outputDir.get().asFile.toPath().also(Files::createDirectories)
for (file in pklHistoricalDistributions.files) {
val target = distributionDir.resolve(file.name)
// Create normal files on Windows, symlink on macOS/linux (need admin privileges to create
// symlinks on Windows)
if (buildInfo.os.isWindows) {
if (!Files.isRegularFile(target, LinkOption.NOFOLLOW_LINKS)) {
if (Files.exists(target)) {
Files.delete(target)
}
Files.copy(file.toPath(), target)
val prepareHistoricalDistributions by tasks.registering {
val outputDir = layout.buildDirectory.dir("pklHistoricalDistributions")
inputs.files(pklHistoricalDistributions.files)
outputs.dir(outputDir)
doLast {
val distributionDir = outputDir.get().asFile.toPath().also(Files::createDirectories)
for (file in pklHistoricalDistributions.files) {
val target = distributionDir.resolve(file.name)
// Create normal files on Windows, symlink on macOS/linux (need admin privileges to create
// symlinks on Windows)
if (buildInfo.os.isWindows) {
if (!Files.isRegularFile(target, LinkOption.NOFOLLOW_LINKS)) {
if (Files.exists(target)) {
Files.delete(target)
}
} else {
if (!Files.isSymbolicLink(target)) {
if (Files.exists(target)) {
Files.delete(target)
}
Files.createSymbolicLink(target, file.toPath())
Files.copy(file.toPath(), target)
}
} else {
if (!Files.isSymbolicLink(target)) {
if (Files.exists(target)) {
Files.delete(target)
}
Files.createSymbolicLink(target, file.toPath())
}
}
}
}
}
val prepareTest by
tasks.registering { dependsOn(pklDistributionCurrent, prepareHistoricalDistributions) }
val prepareTest by tasks.registering {
dependsOn(pklDistributionCurrent, prepareHistoricalDistributions)
}
tasks.test { dependsOn(prepareTest) }