Don't validate JVM target on empty Java sources.

When toolchain is not configured, Kotlin sets by default JVM target to
"1.8". Compiling Kotlin project on JDK 9+ produces JVM target mismatch
warning even if Java sources are empty.

Skip the jvm validation check if associated Java task sources are empty.

^KT-48745 Fixed
This commit is contained in:
Yahor Berdnikau
2021-09-20 17:14:47 +02:00
committed by Space
parent 708931b404
commit 8b594e295c
2 changed files with 102 additions and 17 deletions
@@ -14,6 +14,9 @@ import org.gradle.util.GradleVersion
import org.jetbrains.kotlin.gradle.testbase.*
import org.junit.jupiter.api.DisplayName
import java.io.File
import kotlin.io.path.ExperimentalPathApi
import kotlin.io.path.createDirectories
import kotlin.io.path.writeText
@SimpleGradlePluginTests
@DisplayName("Kotlin Java Toolchain support")
@@ -682,6 +685,78 @@ class KotlinJavaToolchainTest : KGPBaseTest() {
}
}
@DisplayName("Should skip JVM target validation if no java sources are available")
@GradleTest
internal fun shouldSkipJvmTargetValidationNoJavaSources(gradleVersion: GradleVersion) {
project(
projectName = "simple".fullProjectName,
gradleVersion = gradleVersion,
buildJdk = getJdk11().javaHome // should differ from default Kotlin jvm target value
) {
//language=properties
gradleProperties.append(
"""
kotlin.jvm.target.validation.mode = error
""".trimIndent()
)
build("assemble")
}
}
@DisplayName("Should do JVM target validation if java sources are added and configuration cache is reused")
@GradleTestVersions(minVersion = "6.6.1")
@GradleTest
@ExperimentalPathApi
internal fun shouldDoJvmTargetValidationOnNewJavaSourcesAndConfigurationCacheReuse(gradleVersion: GradleVersion) {
project(
projectName = "simple".fullProjectName,
gradleVersion = gradleVersion,
buildOptions = defaultBuildOptions.copy(
configurationCache = true,
configurationCacheProblems = BaseGradleIT.ConfigurationCacheProblems.FAIL
),
buildJdk = getJdk11().javaHome // should differ from default Kotlin jvm target value
) {
// Validation mode should be 'warning' because of https://github.com/gradle/gradle/issues/9339
// which is fixed in Gradle 7.2
//language=properties
gradleProperties.append(
"""
kotlin.jvm.target.validation.mode = warning
""".trimIndent()
)
build("assemble") {
assertOutputDoesNotContain(
"'compileJava' task (current target is 11) and 'compileKotlin' task (current target is 1.8) jvm target compatibility should be set to the same Java version."
)
}
projectPath.resolve("src/main/java/demo").run {
createDirectories()
//language=Java
resolve("HelloWorld.java").writeText(
"""
package demo;
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello world!");
}
}
""".trimIndent()
)
}
build("assemble") {
assertOutputContains(
"'compileJava' task (current target is 11) and 'compileKotlin' task (current target is 1.8) jvm target compatibility should be set to the same Java version."
)
}
}
}
@DisplayName("Build should not produce warninings when '-no-jdk' option is present")
@GradleTestVersions(minVersion = "6.7.1")
@GradleTest
@@ -532,6 +532,11 @@ abstract class KotlinCompile @Inject constructor(
task.associatedJavaCompileTaskTargetCompatibility.set(
compileJavaTaskProvider.map { it.targetCompatibility }
)
task.associatedJavaCompileTaskSources.from(
compileJavaTaskProvider.map { javaTask ->
javaTask.source
}
)
task.associatedJavaCompileTaskName.set(
compileJavaTaskProvider.map { it.name }
)
@@ -642,6 +647,9 @@ abstract class KotlinCompile @Inject constructor(
@get:Internal
internal abstract val associatedJavaCompileTaskTargetCompatibility: Property<String>
@get:Internal
internal abstract val associatedJavaCompileTaskSources: ConfigurableFileCollection
@get:Internal
internal abstract val associatedJavaCompileTaskName: Property<String>
@@ -733,24 +741,26 @@ abstract class KotlinCompile @Inject constructor(
}
private fun validateKotlinAndJavaHasSameTargetCompatibility(args: K2JVMCompilerArguments) {
associatedJavaCompileTaskTargetCompatibility.orNull?.let { targetCompatibility ->
val normalizedJavaTarget = when (targetCompatibility) {
"6" -> "1.6"
"7" -> "1.7"
"8" -> "1.8"
"1.9" -> "9"
else -> targetCompatibility
}
if (!associatedJavaCompileTaskSources.isEmpty) {
associatedJavaCompileTaskTargetCompatibility.orNull?.let { targetCompatibility ->
val normalizedJavaTarget = when (targetCompatibility) {
"6" -> "1.6"
"7" -> "1.7"
"8" -> "1.8"
"1.9" -> "9"
else -> targetCompatibility
}
if (normalizedJavaTarget != args.jvmTarget) {
val javaTaskName = associatedJavaCompileTaskName.get()
val errorMessage = "'$javaTaskName' task (current target is $targetCompatibility) and " +
"'$name' task (current target is ${args.jvmTarget}) " +
"jvm target compatibility should be set to the same Java version."
when (jvmTargetValidationMode.get()) {
PropertiesProvider.JvmTargetValidationMode.ERROR -> throw GradleException(errorMessage)
PropertiesProvider.JvmTargetValidationMode.WARNING -> logger.warn(errorMessage)
else -> Unit
if (normalizedJavaTarget != args.jvmTarget) {
val javaTaskName = associatedJavaCompileTaskName.get()
val errorMessage = "'$javaTaskName' task (current target is $targetCompatibility) and " +
"'$name' task (current target is ${args.jvmTarget}) " +
"jvm target compatibility should be set to the same Java version."
when (jvmTargetValidationMode.get()) {
PropertiesProvider.JvmTargetValidationMode.ERROR -> throw GradleException(errorMessage)
PropertiesProvider.JvmTargetValidationMode.WARNING -> logger.warn(errorMessage)
else -> Unit
}
}
}
}