Enable kotlin java toolchain support for kapt task.

With this change 'KaptWithoutKotlincTask' will also support overriding
default Gradle JDK to run kapt. In such case only 'in-process' kapt
 worker isolation mode is supported.

If user does not provide custom JDK, kapt worker isolation mode will
be 'no-isolation' as before.

^KT-45611 In Progress
This commit is contained in:
Yahor Berdnikau
2021-05-04 17:21:36 +02:00
parent afa1b8bfdc
commit c6fc393417
16 changed files with 255 additions and 48 deletions
@@ -11,6 +11,7 @@ import org.gradle.testkit.runner.BuildResult
import org.gradle.util.GradleVersion
import org.jetbrains.kotlin.gradle.testbase.*
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test
import java.io.File
class KotlinJavaToolchainTest : KGPBaseTest() {
@@ -106,6 +107,112 @@ class KotlinJavaToolchainTest : KGPBaseTest() {
}
}
@DisplayName("Kapt task should use only process worker isolation when kotlin java toolchain is set")
@GradleTest
internal fun kaptTasksShouldUseProcessWorkersIsolation(gradleVersion: GradleVersion) {
project(
projectName = "simpleWithKapt".fullProjectName,
gradleVersion = gradleVersion,
) {
useJdk9ToCompile()
gradleProperties.append(
"kapt.workers.isolation = none"
)
build("assemble") {
assertDaemonIsUsingJdk(getJdk9().javaExecutableRealPath)
assertOutputContains("Using workers PROCESS isolation mode to run kapt")
assertOutputContains("Using non-default Kotlin java toolchain - 'kapt.workers.isolation == none' property is ignored!")
}
}
}
@DisplayName("Kapt task should use worker no-isolation mode when build is using Gradle JDK")
@GradleTest
internal fun kaptTasksShouldUseNoIsolationModeOnDefaultJvm(gradleVersion: GradleVersion) {
project(
projectName = "simpleWithKapt".fullProjectName,
gradleVersion = gradleVersion,
) {
build("assemble") {
assertOutputContains("Using workers NONE isolation mode to run kapt")
assertOutputDoesNotContain("Using non-default Kotlin java toolchain - 'kapt.workers.isolation == none' property is ignored!")
}
}
}
@DisplayName("Kapt tasks with custom JDK should be cacheable")
@GradleTest
internal fun kaptTasksWithCustomJdkCacheable(gradleVersion: GradleVersion) {
val buildCache = workingDir.resolve("custom-jdk-build-cache")
project(
projectName = "simpleWithKapt".fullProjectName,
gradleVersion = gradleVersion,
projectPathAdditionalSuffix = "1/cache-test",
buildOptions = defaultBuildOptions.copy(buildCacheEnabled = true)
) {
enableLocalBuildCache(buildCache)
useJdk9ToCompile()
build("assemble")
}
project(
projectName = "simpleWithKapt".fullProjectName,
gradleVersion = gradleVersion,
projectPathAdditionalSuffix = "2/cache-test",
buildOptions = defaultBuildOptions.copy(buildCacheEnabled = true),
) {
enableLocalBuildCache(buildCache)
useJdk9ToCompile()
build("assemble") {
assertTasksFromCache(
":kaptGenerateStubsKotlin",
":kaptKotlin",
":compileKotlin"
)
}
}
}
@DisplayName("Kapt tasks with default JDK and different isolation modes should be cacheable")
@GradleTest
internal fun kaptCacheableOnSwitchingIsolationModeAndDefaultJDK(gradleVersion: GradleVersion) {
val buildCache = workingDir.resolve("custom-jdk-build-cache")
project(
projectName = "simpleWithKapt".fullProjectName,
gradleVersion = gradleVersion,
projectPathAdditionalSuffix = "1/cache-test",
buildOptions = defaultBuildOptions.copy(buildCacheEnabled = true)
) {
enableLocalBuildCache(buildCache)
build("assemble")
}
project(
projectName = "simpleWithKapt".fullProjectName,
gradleVersion = gradleVersion,
projectPathAdditionalSuffix = "2/cache-test",
buildOptions = defaultBuildOptions.copy(buildCacheEnabled = true),
) {
enableLocalBuildCache(buildCache)
gradleProperties.append(
"kapt.workers.isolation = process"
)
build("assemble") {
assertTasksFromCache(
":kaptGenerateStubsKotlin",
":kaptKotlin",
":compileKotlin"
)
}
}
}
private fun BuildResult.assertDaemonIsUsingJdk(
javaexecPath: String
) = assertOutputContains("i: connected to the daemon. Daemon is using following 'java' executable to run itself: $javaexecPath")
@@ -18,6 +18,7 @@ internal val DEFAULT_GROOVY_SETTINGS_FILE =
plugins {
id "org.jetbrains.kotlin.jvm" version "${'$'}kotlin_version"
id "org.jetbrains.kotlin.kapt" version "${'$'}kotlin_version"
}
}
""".trimIndent()
@@ -0,0 +1,18 @@
plugins {
id "org.jetbrains.kotlin.jvm"
id "org.jetbrains.kotlin.kapt"
id "java"
}
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
implementation "org.jetbrains.kotlin:annotation-processor-example:$kotlin_version"
kapt "org.jetbrains.kotlin:annotation-processor-example:$kotlin_version"
testImplementation 'junit:junit:4.12'
}
compileKotlin.kotlinOptions.allWarningsAsErrors = true
@@ -0,0 +1,5 @@
package foo
internal class InternalDummy {
internal val x = "InternalDummy.x"
}
@@ -0,0 +1,7 @@
package foo
internal class InternalDummyUser {
internal fun use(dummy: InternalDummy) {
if (dummy.x != "InternalDummy.x") throw AssertionError("dummy.x = ${dummy.x}")
}
}
@@ -0,0 +1,28 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package javaPackage;
public class JavaClass {
public void test() {
System.out.println(example.TestClassGenerated.class.getName());
System.out.println(example.SourceAnnotatedTestClassGenerated.class.getName());
System.out.println(example.BinaryAnnotatedTestClassGenerated.class.getName());
System.out.println(example.RuntimeAnnotatedTestClassGenerated.class.getName());
}
}
@@ -0,0 +1,15 @@
package example
@example.ExampleAnnotation
@example.ExampleSourceAnnotation
@example.ExampleBinaryAnnotation
@example.ExampleRuntimeAnnotation
public class TestClass {
@example.ExampleAnnotation
public val testVal: String = "text"
@example.ExampleAnnotation
public fun testFunction(): TestClassGenerated = TestClassGenerated()
}
@@ -0,0 +1,12 @@
package example;
import org.junit.Assert;
import org.junit.Test;
public class JavaTest {
@Test
public void test() {
TestClass testClass = new TestClass();
Assert.assertEquals("text", testClass.getTestVal());
}
}
@@ -0,0 +1,12 @@
package foo
import org.junit.Test
class InternalDummyTest {
@Test
fun testDummy() {
val dummy = InternalDummy()
val dummyUser = InternalDummyUser()
dummyUser.use(dummy)
}
}