From f3acd8d10c95dbcbd95f0f795def2ae2275574f7 Mon Sep 17 00:00:00 2001 From: Ivan Gavrilovic Date: Fri, 2 Aug 2019 10:33:30 +0100 Subject: [PATCH] KT-33028, KT-33050: Fix how kapt invokes javac on JDK 9+ This commit fixes KT-33028 by not setting empty boot classpath when running on JDK9+. When compiling with -source 8 and below, this allows classes from java.base module to be available in the boot classpath. This commit also fixes KT-33050 by passing the source level of Java compile task in the KAPT javac options. This is important as some annotation processors are using ProcessingEnvironment.getSourceVersion() in order to decide what code to generate. Test: Kapt3IT test added for worker and non-worker invocations --- .../org/jetbrains/kotlin/gradle/Kapt3IT.kt | 43 +++++++++++++------ .../kapt/Kapt3KotlinGradleSubplugin.kt | 18 +++++--- .../kotlin/kapt3/base/KaptContext.kt | 8 ++-- 3 files changed, 47 insertions(+), 22 deletions(-) diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kapt3IT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kapt3IT.kt index 917dea64d45..ea7aaa114a3 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kapt3IT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kapt3IT.kt @@ -69,28 +69,30 @@ class Kapt3WorkersIT : Kapt3IT() { } } - private fun testSimpleWithCustomJdk(gradleVersion: String, javaHome: File, jdkDescription: String) { - val gradleVersionRequired = GradleVersionRequired.AtLeast(gradleVersion) - - Assume.assumeTrue("$jdkDescription isn't available", javaHome.isDirectory) + @Test + fun testSimpleWithJdk10() { + val javaHome = File(System.getProperty("jdk10Home")!!) + Assume.assumeTrue("JDK 10 isn't available", javaHome.isDirectory) val options = defaultBuildOptions().copy(javaHome = javaHome) - val project = - Project("simple", directoryPrefix = "kapt2", gradleVersionRequirement = gradleVersionRequired) + val project = Project("simple", directoryPrefix = "kapt2", gradleVersionRequirement = GradleVersionRequired.AtLeast("4.7")) project.build("build", options = options) { assertSuccessful() assertKaptSuccessful() } } - @Test - fun testSimpleWithJdk10() { - testSimpleWithCustomJdk("4.7", File(System.getProperty("jdk10Home")!!), "JDK 10") - } - @Test fun testSimpleWithJdk11() { - testSimpleWithCustomJdk("5.0", File(System.getProperty("jdk11Home")!!), "JDK 11") + val javaHome = File(System.getProperty("jdk11Home")!!) + Assume.assumeTrue("JDK 11 isn't available", javaHome.isDirectory) + val options = defaultBuildOptions().copy(javaHome = javaHome) + + val project = Project("simple", directoryPrefix = "kapt2", gradleVersionRequirement = GradleVersionRequired.AtLeast("5.0")) + project.build("build", options = options) { + assertSuccessful() + assertKaptSuccessful() + } } } @@ -641,4 +643,21 @@ open class Kapt3IT : Kapt3BaseIT() { assertTasksSkipped(":compileJava") } } + + @Test + fun testSimpleWithJdk11AndSourceLevel8() { + val javaHome = File(System.getProperty("jdk11Home")!!) + Assume.assumeTrue("JDK 11 isn't available", javaHome.isDirectory) + val options = defaultBuildOptions().copy(javaHome = javaHome) + + val project = Project("simple", directoryPrefix = "kapt2", gradleVersionRequirement = GradleVersionRequired.AtLeast("5.0")).also { + it.setupWorkingDir() + it.gradleBuildScript().appendText("\nsourceCompatibility = '8'") + } + project.build("build", options = options) { + assertSuccessful() + assertKaptSuccessful() + assertContains("Javac options: {-source=1.8}") + } + } } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/Kapt3KotlinGradleSubplugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/Kapt3KotlinGradleSubplugin.kt index d2f6cfb1ca5..2e85752949f 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/Kapt3KotlinGradleSubplugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/Kapt3KotlinGradleSubplugin.kt @@ -260,7 +260,7 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin { } // This method should be called no more than once for each Kapt3SubpluginContext - private fun Kapt3SubpluginContext.buildOptions(aptMode: String): List { + private fun Kapt3SubpluginContext.buildOptions(aptMode: String, javacOptions: Map): List { val pluginOptions = mutableListOf() val generatedFilesDir = getKaptGeneratedSourcesDir(project, sourceSetName) @@ -285,7 +285,7 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin { pluginOptions += CompositeSubpluginOption("apoptions", lazy { encodeList(apOptions.associate { it.key to it.value }) }, apOptions) - pluginOptions += SubpluginOption("javacArguments", encodeList(kaptExtension.getJavacOptions())) + pluginOptions += SubpluginOption("javacArguments", encodeList(javacOptions)) pluginOptions += SubpluginOption("includeCompileClasspath", includeCompileClasspath.toString()) @@ -326,9 +326,9 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin { subluginOptionsFromProvidedApOptions } - private fun Kapt3SubpluginContext.buildAndAddOptionsTo(task: Task, container: CompilerPluginOptions, aptMode: String) { + private fun Kapt3SubpluginContext.buildAndAddOptionsTo(task: Task, container: CompilerPluginOptions, aptMode: String, javacOptions: Map) { val compilerPluginId = getCompilerPluginId() - val kaptSubpluginOptions = buildOptions(aptMode) + val kaptSubpluginOptions = buildOptions(aptMode, javacOptions) task.registerSubpluginOptionsAsInputs(compilerPluginId, kaptSubpluginOptions) for (option in kaptSubpluginOptions) { @@ -431,6 +431,10 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin { kaptTask.annotationProcessorOptionProviders.add(it) } + val dslJavacOptions = kaptExtension.getJavacOptions().toMutableMap() + if (javaCompile != null && "-source" !in dslJavacOptions && "--release" !in dslJavacOptions) { + dslJavacOptions["-source"] = javaCompile.sourceCompatibility + } if (kaptTask is KaptWithKotlincTask) { if (kaptTask.isIncremental) { kaptTask.pluginOptions.addPluginArgument( @@ -438,7 +442,7 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin { SubpluginOption("incrementalCache", kaptTask.incAptCache!!.absolutePath)) } - buildAndAddOptionsTo(kaptTask, kaptTask.pluginOptions, aptMode = "apt") + buildAndAddOptionsTo(kaptTask, kaptTask.pluginOptions, aptMode = "apt", javacOptions = dslJavacOptions) } if (kaptTask is KaptWithoutKotlincTask) { @@ -447,7 +451,7 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin { mapDiagnosticLocations = kaptExtension.mapDiagnosticLocations annotationProcessorFqNames = kaptExtension.processors.split(',').filter { it.isNotEmpty() } processorOptions = getAPOptions().map { it.key to it.value }.toMap() - javacOptions = kaptExtension.getJavacOptions() + javacOptions = dslJavacOptions } } @@ -493,7 +497,7 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin { PropertiesProvider(project).mapKotlinTaskProperties(kaptTask) kaptTask.kaptClasspathConfigurations = kaptClasspathConfigurations - buildAndAddOptionsTo(kaptTask, kaptTask.pluginOptions, aptMode = "stubs") + buildAndAddOptionsTo(kaptTask, kaptTask.pluginOptions, aptMode = "stubs", javacOptions = kaptExtension.getJavacOptions()) return kaptTask } diff --git a/plugins/kapt3/kapt3-base/src/org/jetbrains/kotlin/kapt3/base/KaptContext.kt b/plugins/kapt3/kapt3-base/src/org/jetbrains/kotlin/kapt3/base/KaptContext.kt index 7ff6f738b67..64bb524ee85 100644 --- a/plugins/kapt3/kapt3-base/src/org/jetbrains/kotlin/kapt3/base/KaptContext.kt +++ b/plugins/kapt3/kapt3-base/src/org/jetbrains/kotlin/kapt3/base/KaptContext.kt @@ -94,9 +94,11 @@ open class KaptContext(val options: KaptOptions, val withJdk: Boolean, val logge put(Option.PROC, "only") // Only process annotations - if (!withJdk) { - @Suppress("SpellCheckingInspection") - putJavacOption("BOOTCLASSPATH", "BOOT_CLASS_PATH", "") // No boot classpath + if (!withJdk && !isJava9OrLater()) { + // No boot classpath for JDK 8 and below. When running on JDK9+ and specifying source level 8 and below, + // boot classpath is not set to empty. This is to allow types to be resolved using boot classpath which defaults to + // classes defined in java.base module. See https://youtrack.jetbrains.com/issue/KT-33028 for details. + put(Option.valueOf("BOOTCLASSPATH"), "") } if (isJava9OrLater()) {