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") @Argument(value = "-include-runtime", description = "Include Kotlin runtime into the resulting JAR")
var includeRuntime: Boolean by FreezableVar(false) 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) @GradleOption(DefaultValues.StringNullDefault::class)
@Argument( @Argument(
value = "-jdk-home", value = "-jdk-home",
@@ -5,13 +5,13 @@
package org.jetbrains.kotlin.gradle package org.jetbrains.kotlin.gradle
import org.gradle.api.logging.LogLevel
import org.gradle.internal.jvm.JavaInfo import org.gradle.internal.jvm.JavaInfo
import org.gradle.internal.jvm.Jvm import org.gradle.internal.jvm.Jvm
import org.gradle.testkit.runner.BuildResult import org.gradle.testkit.runner.BuildResult
import org.gradle.util.GradleVersion import org.gradle.util.GradleVersion
import org.jetbrains.kotlin.gradle.testbase.* import org.jetbrains.kotlin.gradle.testbase.*
import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test
import java.io.File import java.io.File
class KotlinJavaToolchainTest : KGPBaseTest() { 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( private fun BuildResult.assertDaemonIsUsingJdk(
javaexecPath: String javaexecPath: String
) = assertOutputContains("i: connected to the daemon. Daemon is using following 'java' executable to run itself: $javaexecPath") ) = 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 getUserJdk(): JavaInfo = Jvm.forHome(File(System.getenv("JAVA_HOME")))
private fun getJdk9(): JavaInfo = Jvm.forHome(File(System.getenv("JDK_9"))) 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 private val JavaInfo.javaExecutableRealPath
get() = javaExecutable get() = javaExecutable
.toPath() .toPath()
@@ -229,8 +259,6 @@ class KotlinJavaToolchainTest : KGPBaseTest() {
private val String.fullProjectName get() = "kotlin-java-toolchain/$this" private val String.fullProjectName get() = "kotlin-java-toolchain/$this"
private fun TestProject.useJdk9ToCompile() { 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 //language=Groovy
rootBuildGradle.append( rootBuildGradle.append(
""" """
@@ -241,7 +269,7 @@ class KotlinJavaToolchainTest : KGPBaseTest() {
.withType(UsesKotlinJavaToolchain.class) .withType(UsesKotlinJavaToolchain.class)
.configureEach { .configureEach {
it.kotlinJavaToolchain.setJdkHome( it.kotlinJavaToolchain.setJdkHome(
"$jdk9Path", "${getJdk9Path()}",
JavaVersion.VERSION_1_9 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 * Include a custom JDK from the specified location into the classpath instead of the default JAVA_HOME
* Default value: null * 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? 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.CommonCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.CommonToolArguments import org.jetbrains.kotlin.cli.common.arguments.CommonToolArguments
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments 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.dsl.fillDefaultValues
import org.jetbrains.kotlin.gradle.logging.kotlinDebug import org.jetbrains.kotlin.gradle.logging.kotlinDebug
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile
@@ -103,6 +103,40 @@ internal open class KotlinJvmCompilerArgumentsContributor(
} }
args.destinationAsFile = destinationDir 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::destination, // handled by destinationDir
K2JVMCompilerArguments::classpath, // handled by classpath of the Gradle tasks K2JVMCompilerArguments::classpath, // handled by classpath of the Gradle tasks
K2JVMCompilerArguments::friendPaths, // is part of the classpath 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::buildFile, // in Gradle build, these XMLs are transient and provide no useful info
K2JVMCompilerArguments::pluginOptions, // handled specially in the task K2JVMCompilerArguments::pluginOptions, // handled specially in the task
K2JVMCompilerArguments::pluginClasspaths, // handled in the task as classpath K2JVMCompilerArguments::pluginClasspaths, // handled in the task as classpath
@@ -375,7 +375,7 @@ class KotlinJvmCompilerArgumentsProvider
val friendPaths: FileCollection = taskProvider.friendPaths val friendPaths: FileCollection = taskProvider.friendPaths
val compileClasspath: Iterable<File> = taskProvider.classpath val compileClasspath: Iterable<File> = taskProvider.classpath
val destinationDir: File = taskProvider.destinationDir val destinationDir: File = taskProvider.destinationDir
internal val kotlinOptions: List<KotlinJvmOptionsImpl?> = listOfNotNull( internal val kotlinOptions: List<KotlinJvmOptionsImpl> = listOfNotNull(
taskProvider.parentKotlinOptionsImpl.orNull as? KotlinJvmOptionsImpl, taskProvider.parentKotlinOptionsImpl.orNull as? KotlinJvmOptionsImpl,
taskProvider.kotlinOptions as KotlinJvmOptionsImpl taskProvider.kotlinOptions as KotlinJvmOptionsImpl
) )