From 90d15f156bb0ec35375a5d98114dcd65071b783b Mon Sep 17 00:00:00 2001 From: Yahor Berdnikau Date: Wed, 28 Jul 2021 16:23:07 +0200 Subject: [PATCH] Fix toolchain may fail to find tools.jar and false-fail the build. This may happen when build itself is running on JDK9+ and toolchain is set to <=JDK1.8. CompilerEnvironment gets 'tools.jar' from the current Gradle Daemon JDK, but there was a check if exception should be thrown that uses 'javaVersion' from toolchain provided JDK. Additionally also fixed 'tools.jar' was not provided for 'KotlinCompileWithWorkers' task. ^KT-47940 Fixed --- .../kotlin/gradle/KotlinJavaToolchainTest.kt | 15 ++++++++++ .../kotlin/gradle/testbase/testDsl.kt | 30 ++++++++++++------- .../tasks/DefaultKotlinJavaToolchain.kt | 17 ++++++++--- .../jetbrains/kotlin/gradle/tasks/Tasks.kt | 10 +++---- 4 files changed, 53 insertions(+), 19 deletions(-) diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinJavaToolchainTest.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinJavaToolchainTest.kt index bba1d195d1d..909f5b5e02e 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinJavaToolchainTest.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinJavaToolchainTest.kt @@ -671,6 +671,21 @@ class KotlinJavaToolchainTest : KGPBaseTest() { } } + @DisplayName("Toolchain should not make an exception when build is running on JDK 11, but toolchain is set to JDK 1.8") + @GradleTestVersions(minVersion = "6.7.1") + @GradleTest + internal fun shouldNotRaiseErrorOnJDK11withJDK1_8Toolchain(gradleVersion: GradleVersion) { + project( + projectName = "simple".fullProjectName, + gradleVersion = gradleVersion, + buildJdk = getJdk11().javaHome + ) { + useToolchainExtension(8) + + build("assemble", forceOutput = true) + } + } + private fun BuildResult.assertJdkHomeIsUsingJdk( javaexecPath: String ) = assertOutputContains("[KOTLIN] Kotlin compilation 'jdkHome' argument: $javaexecPath") diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/testDsl.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/testDsl.kt index 54e641bd118..0a335de6a54 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/testDsl.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/testDsl.kt @@ -23,7 +23,7 @@ import kotlin.test.assertTrue * * @param [projectName] test project name in 'src/test/resources/testProject` directory. * @param [buildOptions] common Gradle build options - * @param [buildJdk] path to JDK build should run with. *Note*: providing it disables debug! + * @param [buildJdk] path to JDK build should run with. *Note* Only append to 'gradle.properties'! */ fun KGPBaseTest.project( projectName: String, @@ -33,7 +33,7 @@ fun KGPBaseTest.project( addHeapDumpOptions: Boolean = true, enableGradleDebug: Boolean = false, projectPathAdditionalSuffix: String = "", - buildJdk: String? = null, + buildJdk: File? = null, test: TestProject.() -> Unit ): TestProject { val projectPath = setupProjectFromTestResources( @@ -52,9 +52,6 @@ fun KGPBaseTest.project( .withProjectDir(projectPath.toFile()) .withTestKitDir(testKitDir.toAbsolutePath().toFile()) .withGradleVersion(gradleVersion.version) - .also { - if (buildJdk != null) it.withEnvironment(mapOf("JAVA_HOME" to buildJdk)) - } val testProject = TestProject( gradleRunner, @@ -65,6 +62,9 @@ fun KGPBaseTest.project( enableGradleDebug, forceOutput ) + + if (buildJdk != null) testProject.setupNonDefaultJdk(buildJdk) + testProject.test() return testProject } @@ -241,6 +241,16 @@ private fun Path.addDefaultBuildFiles() { } } +private fun TestProject.setupNonDefaultJdk(pathToJdk: File) { + gradleProperties.modify { + """ + |org.gradle.java.home=${pathToJdk.absolutePath.replace('\\', '/')} + | + |$it + """.trimMargin() + } +} + @OptIn(ExperimentalPathApi::class) internal fun Path.enableAndroidSdk() { val androidSdk = KtTestUtil.findAndroidSdk() @@ -326,11 +336,11 @@ private fun Path.addHeapDumpOptions() { if (existingJvmArgsLine.isEmpty()) { propertiesFile.writeText( """ - # modified in addHeapDumpOptions - org.gradle.jvmargs=$heapDumpOutOfErrorStr $heapDumpPathStr - - $propertiesContent - """.trimIndent() + |# modified in addHeapDumpOptions + |org.gradle.jvmargs=$heapDumpOutOfErrorStr $heapDumpPathStr + | + |$propertiesContent + """.trimMargin() ) } else { val argsLine = existingJvmArgsLine.first() diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/DefaultKotlinJavaToolchain.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/DefaultKotlinJavaToolchain.kt index 2ae4f445bb5..faaf82c404e 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/DefaultKotlinJavaToolchain.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/DefaultKotlinJavaToolchain.kt @@ -75,14 +75,17 @@ internal abstract class DefaultKotlinJavaToolchain @Inject constructor( ) .chainedFinalizeValueOnRead() - private fun getToolsJarFromJvm(jvmProvider: Provider): Provider { + private fun getToolsJarFromJvm( + jvmProvider: Provider, + javaVersionProvider: Provider + ): Provider { return objects .propertyWithConvention( jvmProvider.flatMap { jvm -> objects.propertyWithConvention(jvm.toolsJar) } ) - .orElse(javaVersion.flatMap { + .orElse(javaVersionProvider.flatMap { if (it < JavaVersion.VERSION_1_9) { throw GradleException( "Kotlin could not find the required JDK tools in the Java installation. " + @@ -95,10 +98,16 @@ internal abstract class DefaultKotlinJavaToolchain @Inject constructor( } @get:Internal - internal val jdkToolsJar: Provider = getToolsJarFromJvm(providedJvm) + internal val jdkToolsJar: Provider = getToolsJarFromJvm(providedJvm, javaVersion) @get:Internal - internal val currentJvmJdkToolsJar: Provider = getToolsJarFromJvm(currentJvm) + internal val currentJvmJdkToolsJar: Provider = getToolsJarFromJvm( + currentJvm, + currentJvm.map { + // Current JVM should always have java version + it.javaVersion!! + } + ) final override val jdk: KotlinJavaToolchain.JdkSetter = DefaultJdkSetter( providedJvm, diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt index f54cc90398c..b8006c146f8 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt @@ -776,16 +776,16 @@ internal abstract class KotlinCompileWithWorkers @Inject constructor( workerExecutor: WorkerExecutor ) : KotlinCompile(kotlinOptions) { override val compilerRunner: Provider = - objects.propertyWithConvention( - gradleCompileTaskProvider.map { + defaultKotlinJavaToolchain.flatMap { toolchain -> + objects.property(gradleCompileTaskProvider.map { GradleCompilerRunnerWithWorkers( it, - null, + toolchain.currentJvmJdkToolsJar.orNull, normalizedKotlinDaemonJvmArguments.orNull, workerExecutor ) as GradleCompilerRunner - } - ) + }) + } } @CacheableTask