Warn on using 'jdkHome' option in Gradle builds.

User should instead use KotlinJavaToolchain that will take care of
tracking major java version and provide nicer API.

Gradle will still pass jdkHome value to the compiler, but it should
be changed in Kotlin 1.6 release.

^KT-45611 Fixed
This commit is contained in:
Yahor Berdnikau
2021-05-06 17:28:19 +02:00
committed by TeamCityServer
parent 74d1812461
commit 800e382ba9
6 changed files with 76 additions and 8 deletions
@@ -30,6 +30,11 @@ class K2JVMCompilerArguments : CommonCompilerArguments() {
@Argument(value = "-include-runtime", description = "Include Kotlin runtime into the resulting JAR")
var includeRuntime: Boolean by FreezableVar(false)
@DeprecatedOption(
message = "This option is not working well with Gradle caching and will be removed in the future.",
removeAfter = "1.7",
level = DeprecationLevel.WARNING
)
@GradleOption(DefaultValues.StringNullDefault::class)
@Argument(
value = "-jdk-home",
@@ -5,13 +5,13 @@
package org.jetbrains.kotlin.gradle
import org.gradle.api.logging.LogLevel
import org.gradle.internal.jvm.JavaInfo
import org.gradle.internal.jvm.Jvm
import org.gradle.testkit.runner.BuildResult
import org.gradle.util.GradleVersion
import org.jetbrains.kotlin.gradle.testbase.*
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test
import java.io.File
class KotlinJavaToolchainTest : KGPBaseTest() {
@@ -213,12 +213,42 @@ class KotlinJavaToolchainTest : KGPBaseTest() {
}
}
@DisplayName("jdkHome Kotlin option should produce deprecation warning on Gradle builds")
@GradleTest
internal fun jdkHomeIsDeprecated(gradleVersion: GradleVersion) {
project(
projectName = "simple".fullProjectName,
gradleVersion = gradleVersion,
buildOptions = defaultBuildOptions.copy(logLevel = LogLevel.DEBUG)
) {
//language=Groovy
rootBuildGradle.append(
"""
import org.jetbrains.kotlin.gradle.dsl.KotlinCompile
tasks.withType(KotlinCompile).configureEach {
kotlinOptions {
jdkHome = "${getJdk9Path()}"
}
}
""".trimIndent()
)
build("assemble") {
assertDaemonIsUsingJdk(getUserJdk().javaExecutableRealPath)
assertOutputContains("'kotlinOptions.jdkHome' is deprecated and will ignored in Kotlin 1.6!")
assertOutputContains("-jdk-home ${getJdk9().javaHome.absolutePath}")
}
}
}
private fun BuildResult.assertDaemonIsUsingJdk(
javaexecPath: String
) = assertOutputContains("i: connected to the daemon. Daemon is using following 'java' executable to run itself: $javaexecPath")
private fun getUserJdk(): JavaInfo = Jvm.forHome(File(System.getenv("JAVA_HOME")))
private fun getJdk9(): JavaInfo = Jvm.forHome(File(System.getenv("JDK_9")))
// replace required for windows paths so Groovy will not complain about unexpected char '\'
private fun getJdk9Path(): String = getJdk9().javaHome.absolutePath.replace("\\", "\\\\")
private val JavaInfo.javaExecutableRealPath
get() = javaExecutable
.toPath()
@@ -229,8 +259,6 @@ class KotlinJavaToolchainTest : KGPBaseTest() {
private val String.fullProjectName get() = "kotlin-java-toolchain/$this"
private fun TestProject.useJdk9ToCompile() {
// replace required for windows paths so Groovy will not complain about unexpected char '\'
val jdk9Path = getJdk9().javaHome.absolutePath.replace("\\", "\\\\")
//language=Groovy
rootBuildGradle.append(
"""
@@ -241,7 +269,7 @@ class KotlinJavaToolchainTest : KGPBaseTest() {
.withType(UsesKotlinJavaToolchain.class)
.configureEach {
it.kotlinJavaToolchain.setJdkHome(
"$jdk9Path",
"${getJdk9Path()}",
JavaVersion.VERSION_1_9
)
}
@@ -21,6 +21,7 @@ interface KotlinJvmOptions : org.jetbrains.kotlin.gradle.dsl.KotlinCommonOption
* Include a custom JDK from the specified location into the classpath instead of the default JAVA_HOME
* Default value: null
*/
@Deprecated(message = "This option is not working well with Gradle caching and will be removed in the future.", level = DeprecationLevel.WARNING)
var jdkHome: kotlin.String?
/**
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.gradle.internal
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.CommonToolArguments
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.gradle.dsl.Coroutines
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptionsImpl
import org.jetbrains.kotlin.gradle.dsl.fillDefaultValues
import org.jetbrains.kotlin.gradle.logging.kotlinDebug
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile
@@ -103,6 +103,40 @@ internal open class KotlinJvmCompilerArgumentsContributor(
}
args.destinationAsFile = destinationDir
kotlinOptions.forEach { it?.updateArguments(args) }
warnJdkHomeNotUsed(kotlinOptions)
kotlinOptions.forEach { it.updateArguments(args) }
}
private fun warnJdkHomeNotUsed(kotlinOptions: List<KotlinJvmOptionsImpl>) {
kotlinOptions
.firstOrNull { it.jdkHome != null }
?.run {
logger.warn(
"""
'kotlinOptions.jdkHome' is deprecated and will ignored in Kotlin 1.6!
Consider using KotlinJavaToolchain:
- Kotlin DSL:
project.tasks
.withType<UsesKotlinJavaToolchain>()
.configureEach {
it.kotlinJavaToolchain.setJdkHome(
"/path/to/your/jdk",
JavaVersion.<JDK_VERSION>
)
}
- Groovy DSL
project.tasks
.withType(UsesKotlinJavaToolchain.class)
.configureEach {
it.kotlinJavaToolchain.setJdkHome(
'/path/to/your/jdk',
JavaVersion.<JDK_VERSION>
)
}
""".trimIndent()
)
}
}
}
@@ -51,7 +51,7 @@ internal object CompilerArgumentsGradleInput {
K2JVMCompilerArguments::destination, // handled by destinationDir
K2JVMCompilerArguments::classpath, // handled by classpath of the Gradle tasks
K2JVMCompilerArguments::friendPaths, // is part of the classpath
K2JVMCompilerArguments::jdkHome, // JDK can be both placed differently and contain different files on user machines
K2JVMCompilerArguments::jdkHome, // Gradle takes care of running Kotlin compilation with user specified JDK
K2JVMCompilerArguments::buildFile, // in Gradle build, these XMLs are transient and provide no useful info
K2JVMCompilerArguments::pluginOptions, // handled specially in the task
K2JVMCompilerArguments::pluginClasspaths, // handled in the task as classpath
@@ -375,7 +375,7 @@ class KotlinJvmCompilerArgumentsProvider
val friendPaths: FileCollection = taskProvider.friendPaths
val compileClasspath: Iterable<File> = taskProvider.classpath
val destinationDir: File = taskProvider.destinationDir
internal val kotlinOptions: List<KotlinJvmOptionsImpl?> = listOfNotNull(
internal val kotlinOptions: List<KotlinJvmOptionsImpl> = listOfNotNull(
taskProvider.parentKotlinOptionsImpl.orNull as? KotlinJvmOptionsImpl,
taskProvider.kotlinOptions as KotlinJvmOptionsImpl
)