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 9ccd28d3ef2..26811e13444 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 @@ -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 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 2cd7a37adb9..2ff1babf1ac 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 @@ -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 + @get:Internal + internal abstract val associatedJavaCompileTaskSources: ConfigurableFileCollection + @get:Internal internal abstract val associatedJavaCompileTaskName: Property @@ -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 + } } } }