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