diff --git a/libraries/tools/kotlin-gradle-plugin-core/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt b/libraries/tools/kotlin-gradle-plugin-core/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt index 7f3f6bbb862..69fbd133d06 100644 --- a/libraries/tools/kotlin-gradle-plugin-core/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt +++ b/libraries/tools/kotlin-gradle-plugin-core/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt @@ -62,6 +62,8 @@ abstract class AbstractKotlinCompile() : AbstractCo var kotlinOptions: T = createBlankArgs() var kotlinDestinationDir: File? = destinationDir var compilerCalled: Boolean = false + // TODO: consider more reliable approach (see usage) + var anyClassesCompiled: Boolean = false private val loggerInstance = Logging.getLogger(this.javaClass) override fun getLogger() = loggerInstance @@ -361,6 +363,8 @@ open class KotlinCompile() : AbstractKotlinCompile() { fun outputRelativePath(f: File) = f.toRelativeString(outputDir) + anyClassesCompiled = false + // TODO: decide what to do if no files are considered dirty - rebuild or skip the module var (sourcesToCompile, isIncrementalDecided) = calculateSourcesToCompile() @@ -450,6 +454,9 @@ open class KotlinCompile() : AbstractKotlinCompile() { lookupStorage.flush(false) lookupStorage.close() caches.values.forEach { it.flush(false); it.close() } + if (allGeneratedFiles.isNotEmpty()) { + anyClassesCompiled = true + } } private data class CompileChangedResults(val exitCode: ExitCode, val generatedFiles: List>) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt index 1d8a8b97c43..718356ebf37 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt @@ -133,6 +133,20 @@ class Kotlin2JvmSourceSetProcessor( val javaTask = project.tasks.findByName(sourceSet.compileJavaTaskName) as AbstractCompile? if (javaTask != null) { + // Since we cannot update classpath statically, java not able to detect changes in the classpath after kotlin compiler. + // Therefore this (probably inefficient since java cannot decide "uptodateness" by the list of changed class files, but told + // explicitly being out of date whenever any kotlin files are compiled + kotlinTask.property("anyClassesCompiled")?.let { + kotlinTask.setProperty("anyClassesCompiled", false) + javaTask.outputs.upToDateWhen { task -> + val kotlinClassesCompiled = kotlinTask.property("anyClassesCompiled") as? Boolean ?: false + if (kotlinClassesCompiled) { + logger.info("Marking $task out of date, because kotlin classes are changed") + } + !kotlinClassesCompiled + } + } + javaTask.dependsOn(kotlinTaskName) javaTask.doFirst { javaTask.classpath += project.files(kotlinDestinationDir)