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
This commit is contained in:
Yahor Berdnikau
2021-07-28 16:23:07 +02:00
committed by Space
parent bab5a4a6c9
commit 90d15f156b
4 changed files with 53 additions and 19 deletions
@@ -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")
@@ -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()
@@ -75,14 +75,17 @@ internal abstract class DefaultKotlinJavaToolchain @Inject constructor(
)
.chainedFinalizeValueOnRead()
private fun getToolsJarFromJvm(jvmProvider: Provider<Jvm>): Provider<File?> {
private fun getToolsJarFromJvm(
jvmProvider: Provider<Jvm>,
javaVersionProvider: Provider<JavaVersion>
): Provider<File?> {
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<File?> = getToolsJarFromJvm(providedJvm)
internal val jdkToolsJar: Provider<File?> = getToolsJarFromJvm(providedJvm, javaVersion)
@get:Internal
internal val currentJvmJdkToolsJar: Provider<File?> = getToolsJarFromJvm(currentJvm)
internal val currentJvmJdkToolsJar: Provider<File?> = getToolsJarFromJvm(
currentJvm,
currentJvm.map {
// Current JVM should always have java version
it.javaVersion!!
}
)
final override val jdk: KotlinJavaToolchain.JdkSetter = DefaultJdkSetter(
providedJvm,
@@ -776,16 +776,16 @@ internal abstract class KotlinCompileWithWorkers @Inject constructor(
workerExecutor: WorkerExecutor
) : KotlinCompile(kotlinOptions) {
override val compilerRunner: Provider<GradleCompilerRunner> =
objects.propertyWithConvention(
gradleCompileTaskProvider.map {
defaultKotlinJavaToolchain.flatMap { toolchain ->
objects.property(gradleCompileTaskProvider.map {
GradleCompilerRunnerWithWorkers(
it,
null,
toolchain.currentJvmJdkToolsJar.orNull,
normalizedKotlinDaemonJvmArguments.orNull,
workerExecutor
) as GradleCompilerRunner
}
)
})
}
}
@CacheableTask