diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt index ad300fb2bce..d2868b24721 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt @@ -545,9 +545,15 @@ open class NewMultiplatformIT : BaseGradleIT() { } gradleBuildScript().modify { - if (testJavaSupportInJvmTargets) { + """ + apply plugin: 'com.github.johnrengelman.shadow' + apply plugin: 'application' + apply plugin: 'kotlin-kapt' // Check that Kapts works, generates and compiles sources + """.trimIndent() + if (testJavaSupportInJvmTargets) { it + "\nkotlin.jvm(\"jvm6\") { " + - "${KotlinJvmTarget::withJava.name.plus("();").repeat(2)} " + // also check that the function is idempotent + "${ + KotlinJvmTarget::withJava.name.plus("();").repeat(2) + } " + // also check that the function is idempotent "}" } else { it.replace("presets.jvm", "presets.jvmWithJava").replace("jvm(", "targetFromPreset(presets.jvmWithJava, ") @@ -562,10 +568,6 @@ open class NewMultiplatformIT : BaseGradleIT() { } } - apply plugin: 'com.github.johnrengelman.shadow' - apply plugin: 'application' - apply plugin: 'kotlin-kapt' // Check that Kapts works, generates and compiles sources - mainClassName = 'com.example.lib.CommonKt' dependencies { diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinSourceSetProcessor.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinSourceSetProcessor.kt index 3a7bb3767d7..eb5dfa7e8d5 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinSourceSetProcessor.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinSourceSetProcessor.kt @@ -29,7 +29,7 @@ import java.util.concurrent.Callable internal abstract class KotlinSourceSetProcessor>( val tasksProvider: KotlinTasksProvider, val taskDescription: String, - kotlinCompilation: KotlinCompilationInfo + kotlinCompilation: KotlinCompilationInfo, ) : KotlinCompilationProcessor(kotlinCompilation) { protected abstract fun doTargetSpecificProcessing() protected val logger = Logging.getLogger(this.javaClass)!! @@ -41,13 +41,7 @@ internal abstract class KotlinSourceSetProcessor>( protected val javaSourceSet: SourceSet? get() = when (val compilation = compilationInfo.safeAs()?.origin) { is KotlinWithJavaCompilation<*, *> -> compilation.javaSourceSet - is KotlinJvmCompilation -> if (compilation.target.withJavaEnabled) { - project.variantImplementationFactory() - .getInstance(project) - .sourceSets - .maybeCreate(compilation.name) - } else null - + is KotlinJvmCompilation -> compilation.javaSourceSet.getOrNull() else -> null } @@ -154,4 +148,4 @@ internal abstract class KotlinSourceSetProcessor>( } protected abstract fun doRegisterTask(project: Project, taskName: String): TaskProvider -} \ No newline at end of file +} 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 d94bf81d479..33a609520fe 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 @@ -7,9 +7,11 @@ package org.jetbrains.kotlin.gradle.plugin.mpp import org.gradle.api.provider.Provider +import org.gradle.api.tasks.SourceSet import org.gradle.api.tasks.TaskProvider import org.gradle.api.tasks.compile.JavaCompile -import org.jetbrains.kotlin.gradle.dsl.* +import org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompilerOptions +import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions import org.jetbrains.kotlin.gradle.plugin.HasCompilerOptions import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationWithResources import org.jetbrains.kotlin.gradle.plugin.internal.JavaSourceSetsAccessor @@ -17,10 +19,13 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationI import org.jetbrains.kotlin.gradle.plugin.variantImplementationFactory import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask +import org.jetbrains.kotlin.gradle.utils.LenientFuture +import org.jetbrains.kotlin.gradle.utils.future +import org.jetbrains.kotlin.gradle.utils.lenient import javax.inject.Inject open class KotlinJvmCompilation @Inject internal constructor( - compilation: KotlinCompilationImpl + compilation: KotlinCompilationImpl, ) : AbstractKotlinCompilationToRunnableFiles(compilation), KotlinCompilationWithResources { @@ -62,14 +67,18 @@ open class KotlinJvmCompilation @Inject internal constructor( * 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) + .provider { javaSourceSet.getOrNull() } + .flatMap { javaSourceSet -> + @Suppress("RedundantRequireNotNullCall") // IDE and CLI disagree here + checkNotNull(javaSourceSet) + project.tasks.named(javaSourceSet.compileJavaTaskName, JavaCompile::class.java) } + internal val javaSourceSet: LenientFuture = target.project.future { + target.withJavaEnabledFuture.await() + target.project.javaSourceSets.maybeCreate(compilationName) + }.lenient + 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/targets/jvm/KotlinJvmTarget.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmTarget.kt index bc3802fc97c..61d15055706 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmTarget.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmTarget.kt @@ -30,8 +30,9 @@ import org.jetbrains.kotlin.gradle.targets.jvm.tasks.KotlinJvmRunDsl import org.jetbrains.kotlin.gradle.targets.jvm.tasks.KotlinJvmRunDslImpl import org.jetbrains.kotlin.gradle.targets.jvm.tasks.registerMainRunTask import org.jetbrains.kotlin.gradle.tasks.withType +import org.jetbrains.kotlin.gradle.utils.* +import org.jetbrains.kotlin.gradle.utils.CompletableFuture import org.jetbrains.kotlin.gradle.utils.Future -import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation import org.jetbrains.kotlin.gradle.utils.findAppliedAndroidPluginIdOrNull import org.jetbrains.kotlin.gradle.utils.future import org.jetbrains.kotlin.utils.addToStdlib.cast @@ -90,10 +91,16 @@ abstract class KotlinJvmTarget @Inject constructor( mainRun.await()?.configure() } + /** + * Future that will complete once [withJava] is called and java support for this target + * was established. + */ + internal val withJavaEnabledFuture: Future get() = withJavaEnabledFutureImpl + private val withJavaEnabledFutureImpl = CompletableFuture() + var withJavaEnabled = false private set - @Suppress("unused") // user DSL fun withJava() { if (withJavaEnabled) @@ -164,6 +171,8 @@ abstract class KotlinJvmTarget @Inject constructor( copyUserDefinedAttributesToJavaConfigurations(javaSourceSet) } } + + withJavaEnabledFutureImpl.complete(Unit) } private fun setupJavaSourceSetSourcesAndResources(