From a90664574c3ba447f8ca721556b06db78b1d3356 Mon Sep 17 00:00:00 2001 From: Yahor Berdnikau Date: Fri, 25 Nov 2022 11:16:54 +0100 Subject: [PATCH] Fix jvm target validation does not work for MPP JVM withJava target Related KotlinCompile to JavaCompile wiring is happening on KotlinJvmTarget initialization before 'withJava' configuration runs. At that point linked JavaCompile task is null. Fix delays wiring to execution phase when such task should be available. ^KT-55119 Fixed --- .../kotlin/gradle/JvmTargetValidationTest.kt | 54 ++++++++++++++++++- .../targets/jvm/KotlinJvmCompilation.kt | 20 ++++++- .../configuration/KotlinCompileConfig.kt | 8 +-- tests/mute-common.csv | 1 - 4 files changed, 76 insertions(+), 7 deletions(-) diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/JvmTargetValidationTest.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/JvmTargetValidationTest.kt index 894d9266d1d..99fa22450c0 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/JvmTargetValidationTest.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/JvmTargetValidationTest.kt @@ -321,7 +321,6 @@ class JvmTargetValidationTest : KGPBaseTest() { } @DisplayName("Validation should work correctly for KaptGenerateStubs task") - @GradleTestVersions @GradleTest internal fun kaptGenerateStubsValidateCorrect(gradleVersion: GradleVersion) { project( @@ -387,6 +386,59 @@ class JvmTargetValidationTest : KGPBaseTest() { } } + @MppGradlePluginTests + @DisplayName("Validation should show error for MPP JVM target withJava") + @GradleTest + internal fun mppWithJavaFailValidation(gradleVersion: GradleVersion) { + project("kt-31468-multiple-jvm-targets-with-java", gradleVersion) { + gradleProperties.append( + """ + kotlin.jvm.target.validation.mode = error + """.trimIndent() + ) + + subProject("lib").buildGradleKts.appendText( + """ + | + |java { + | targetCompatibility = JavaVersion.VERSION_17 + | sourceCompatibility = JavaVersion.VERSION_17 + |} + """.trimMargin() + ) + + buildAndFail(":lib:compileKotlinJvmWithJava") { + assertOutputContains("'compileJava' task (current target is 17) and 'compileKotlinJvmWithJava' task" + + " (current target is 1.8) jvm target compatibility should be set to the same Java version.") + } + } + } + + @MppGradlePluginTests + @DisplayName("Validation should not run MPP JVM target without withJava") + @GradleTest + internal fun mppJvmNotFailValidation(gradleVersion: GradleVersion) { + project("kt-31468-multiple-jvm-targets-with-java", gradleVersion) { + gradleProperties.append( + """ + kotlin.jvm.target.validation.mode = error + """.trimIndent() + ) + + subProject("lib").buildGradleKts.appendText( + """ + | + |java { + | targetCompatibility = JavaVersion.VERSION_17 + | sourceCompatibility = JavaVersion.VERSION_17 + |} + """.trimMargin() + ) + + build(":lib:compileKotlinPlainJvm") + } + } + private fun TestProject.setJavaCompilationCompatibility( target: JavaVersion ) { diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmCompilation.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmCompilation.kt index a4c33fb323e..d94bf81d479 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmCompilation.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmCompilation.kt @@ -6,6 +6,7 @@ @file:Suppress("PackageDirectoryMismatch") // Old package for compatibility package org.jetbrains.kotlin.gradle.plugin.mpp +import org.gradle.api.provider.Provider import org.gradle.api.tasks.TaskProvider import org.gradle.api.tasks.compile.JavaCompile import org.jetbrains.kotlin.gradle.dsl.* @@ -23,7 +24,7 @@ open class KotlinJvmCompilation @Inject internal constructor( ) : AbstractKotlinCompilationToRunnableFiles(compilation), KotlinCompilationWithResources { - override val target: KotlinJvmTarget = compilation.target as KotlinJvmTarget + final override val target: KotlinJvmTarget = compilation.target as KotlinJvmTarget override val compilerOptions: HasCompilerOptions = compilation.compilerOptions.castCompilerOptionsType() @@ -42,6 +43,10 @@ open class KotlinJvmCompilation @Inject internal constructor( override val compileTaskProvider: TaskProvider> get() = compilation.compileTaskProvider as TaskProvider> + /** + * **Note**: requesting this too early (right after target creation and before any target configuration) may falsely return `null` + * value, but later target will be configured to run with Java enabled. If possible, please use [compileJavaTaskProviderSafe]. + */ val compileJavaTaskProvider: TaskProvider? get() = if (target.withJavaEnabled) { val project = target.project @@ -52,6 +57,19 @@ open class KotlinJvmCompilation @Inject internal constructor( project.tasks.withType(JavaCompile::class.java).named(javaSourceSet.compileJavaTaskName) } else null + /** + * Alternative to [compileJavaTaskProvider] to safely receive [JavaCompile] task provider when [KotlinJvmTarget.withJavaEnabled] + * will be enabled after call to this method. + */ + internal val compileJavaTaskProviderSafe: Provider = target.project.providers + .provider { if (target.withJavaEnabled) Unit else null } + .map { + project.javaSourceSets.getByName(compilationName).compileJavaTaskName + } + .flatMap { + project.tasks.named(it, JavaCompile::class.java) + } + override val processResourcesTaskName: String get() = compilation.processResourcesTaskName ?: error("Missing 'processResourcesTaskName'") } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/KotlinCompileConfig.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/KotlinCompileConfig.kt index 05ad6156da6..29b463d9bff 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/KotlinCompileConfig.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/KotlinCompileConfig.kt @@ -70,7 +70,7 @@ internal open class BaseKotlinCompileConfig : AbstractKotl constructor(compilationInfo: KotlinCompilationInfo) : super(compilationInfo) { val javaTaskProvider = when (val compilation = compilationInfo.tcsOrNull?.compilation) { - is KotlinJvmCompilation -> compilation.compileJavaTaskProvider + is KotlinJvmCompilation -> compilation.compileJavaTaskProviderSafe is KotlinJvmAndroidCompilation -> compilation.compileJavaTaskProvider is KotlinWithJavaCompilation<*, *> -> compilation.compileJavaTaskProvider else -> null @@ -78,9 +78,9 @@ internal open class BaseKotlinCompileConfig : AbstractKotl configureTaskProvider { taskProvider -> taskProvider.configure { task -> - javaTaskProvider?.let { - task.associatedJavaCompileTaskTargetCompatibility.value(javaTaskProvider.map { it.targetCompatibility }) - task.associatedJavaCompileTaskName.value(javaTaskProvider.name) + javaTaskProvider?.let { javaTask -> + task.associatedJavaCompileTaskTargetCompatibility.value(javaTask.map { it.targetCompatibility }) + task.associatedJavaCompileTaskName.value(javaTask.map { it.name }) } @Suppress("DEPRECATION") diff --git a/tests/mute-common.csv b/tests/mute-common.csv index 5fd119dbb8d..32fdcb3b849 100644 --- a/tests/mute-common.csv +++ b/tests/mute-common.csv @@ -55,7 +55,6 @@ org.jetbrains.kotlin.idea.navigation.GotoWithMultipleLibrariesTest.testOneHasSou org.jetbrains.kotlin.idea.navigation.GotoWithMultipleLibrariesTest.testSeveralWithSource,,, FLAKY org.jetbrains.kotlin.tools.projectWizard.wizard.ProjectTemplateNewWizardProjectImportTestGenerated.GradleGroovy.testMultiplatformApplication,,, org.jetbrains.kotlin.tools.projectWizard.wizard.ProjectTemplateNewWizardProjectImportTestGenerated.GradleKts.testMultiplatformApplication,,, -org.jetbrains.kotlin.gradle.NewMultiplatformIT.testJavaSupportInJvmTargets,,, org.jetbrains.kotlin.checkers.JavaAgainstKotlinBinariesCheckerTestGenerated.testJvmOverloadsFunctions,,, FLAKY org.jetbrains.kotlin.checkers.JavaAgainstKotlinBinariesCheckerTestGenerated.testReturnInnerClasses,,, FLAKY org.jetbrains.kotlin.checkers.JavaAgainstKotlinBinariesCheckerTestGenerated.testThrowsOnGenericMethod,,, FLAKY