Allow to configure non-default JDK using toolchain via extension.

Add method into "kotlin" extension to set toolchain for all tasks.
This will also set toolchain for java compile tasks. Also user may
set toolchain via "java" extension and it will be applied to Kotlin
tasks as well.

^KT-43092 In Progress
This commit is contained in:
Yahor Berdnikau
2021-05-21 16:45:55 +02:00
committed by Space
parent 8e1c420c9f
commit 4c943e7cd1
10 changed files with 427 additions and 100 deletions
@@ -11,6 +11,7 @@ import org.gradle.api.tasks.Input
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.Nested
import org.gradle.jvm.toolchain.JavaLauncher
import org.gradle.util.GradleVersion
import java.io.File
interface UsesKotlinJavaToolchain {
@@ -66,4 +67,8 @@ interface KotlinJavaToolchain {
javaLauncher: Provider<JavaLauncher>
)
}
companion object {
val TOOLCHAIN_SUPPORTED_VERSION: GradleVersion = GradleVersion.version("6.7")
}
}
@@ -12,12 +12,14 @@ 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
@SimpleGradlePluginPTests
@DisplayName("Kotlin Java Toolchain support")
class KotlinJavaToolchainTest : KGPBaseTest() {
@GradleTestVersions(additionalVersions = ["6.7.1"])
@GradleTest
@DisplayName("Should use by default same jvm as Gradle daemon")
internal fun byDefaultShouldUseGradleJDK(gradleVersion: GradleVersion) {
@@ -31,6 +33,28 @@ class KotlinJavaToolchainTest : KGPBaseTest() {
}
}
@GradleTestVersions(minVersion = "6.7.1")
@GradleTest
@DisplayName("Default Kotlin toolchain should still allow to set Java source and target compatibility")
internal fun shouldNotFailWithDefaultJdkAndCompatibility(gradleVersion: GradleVersion) {
project(
projectName = "simple".fullProjectName,
gradleVersion = gradleVersion
) {
//lang=Groovy
rootBuildGradle.append(
"""
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
""".trimIndent()
)
build("assemble")
}
}
@GradleTestVersions(maxVersion = "6.6.1")
@GradleTest
@DisplayName("Should use provided jdk location to compile Kotlin sources")
internal fun customJdkHomeLocation(gradleVersion: GradleVersion) {
@@ -46,6 +70,18 @@ class KotlinJavaToolchainTest : KGPBaseTest() {
}
}
@Test
@DisplayName("Should fail the build on setting custom JDK when toolchain is available")
internal fun errorOnSettingJdkWhenToolchainIsAvailable() {
project(
projectName = "simple".fullProjectName,
gradleVersion = GradleVersion.version("6.7.1"),
) {
useJdk9ToCompile()
buildAndFail("assemble")
}
}
@GradleTest
@DisplayName("KotlinCompile task should use build cache when using provided JDK")
internal fun customJdkBuildCache(gradleVersion: GradleVersion) {
@@ -57,7 +93,11 @@ class KotlinJavaToolchainTest : KGPBaseTest() {
buildOptions = defaultBuildOptions.copy(buildCacheEnabled = true)
) {
enableLocalBuildCache(buildCache)
useJdk9ToCompile()
if (shouldUseToolchain(gradleVersion)) {
useToolchainExtension(11)
} else {
useJdk9ToCompile()
}
build("assemble")
}
@@ -69,7 +109,11 @@ class KotlinJavaToolchainTest : KGPBaseTest() {
buildOptions = defaultBuildOptions.copy(buildCacheEnabled = true)
) {
enableLocalBuildCache(buildCache)
useJdk9ToCompile()
if (shouldUseToolchain(gradleVersion)) {
useToolchainExtension(11)
} else {
useJdk9ToCompile()
}
build("assemble") {
assertTasksFromCache(":compileKotlin")
@@ -90,7 +134,11 @@ class KotlinJavaToolchainTest : KGPBaseTest() {
) {
enableLocalBuildCache(buildCache)
enableBuildCacheDebug()
useJdk9ToCompile()
if (shouldUseToolchain(gradleVersion)) {
useToolchainExtension(11)
} else {
useJdk9ToCompile()
}
build("assemble")
}
@@ -116,13 +164,23 @@ class KotlinJavaToolchainTest : KGPBaseTest() {
projectName = "simpleWithKapt".fullProjectName,
gradleVersion = gradleVersion,
) {
useJdk9ToCompile()
if (shouldUseToolchain(gradleVersion)) {
useToolchainExtension(11)
} else {
useJdk9ToCompile()
}
gradleProperties.append(
"kapt.workers.isolation = none"
)
build("assemble") {
assertDaemonIsUsingJdk(getJdk9().javaExecutableRealPath)
assertDaemonIsUsingJdk(
if (shouldUseToolchain(gradleVersion)) {
getToolchainExecPathFromLogs()
} else {
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!")
@@ -155,7 +213,11 @@ class KotlinJavaToolchainTest : KGPBaseTest() {
buildOptions = defaultBuildOptions.copy(buildCacheEnabled = true)
) {
enableLocalBuildCache(buildCache)
useJdk9ToCompile()
if (shouldUseToolchain(gradleVersion)) {
useToolchainExtension(11)
} else {
useJdk9ToCompile()
}
build("assemble")
}
@@ -167,7 +229,11 @@ class KotlinJavaToolchainTest : KGPBaseTest() {
buildOptions = defaultBuildOptions.copy(buildCacheEnabled = true),
) {
enableLocalBuildCache(buildCache)
useJdk9ToCompile()
if (shouldUseToolchain(gradleVersion)) {
useToolchainExtension(11)
} else {
useJdk9ToCompile()
}
build("assemble") {
assertTasksFromCache(
@@ -244,7 +310,7 @@ class KotlinJavaToolchainTest : KGPBaseTest() {
}
@DisplayName("Should allow to set JDK version for tasks via Java toolchain")
@GradleTestVersions(minVersion = "6.7")
@GradleTestVersions(minVersion = "6.7.1")
@GradleTest
internal fun setJdkUsingJavaToolchain(gradleVersion: GradleVersion) {
project(
@@ -259,6 +325,22 @@ class KotlinJavaToolchainTest : KGPBaseTest() {
}
}
@DisplayName("Should allow to set Java toolchain via extension")
@GradleTestVersions(minVersion = "6.7.1")
@GradleTest
internal fun setJdkUsingJavaToolchainViaExtension(gradleVersion: GradleVersion) {
project(
projectName = "simple".fullProjectName,
gradleVersion = gradleVersion,
forceOutput = true
) {
useToolchainExtension(11)
build("assemble") {
assertDaemonIsUsingJdk(getToolchainExecPathFromLogs())
}
}
}
private fun BuildResult.assertDaemonIsUsingJdk(
javaexecPath: String
) = assertOutputContains("i: connected to the daemon. Daemon is using following 'java' executable to run itself: $javaexecPath")
@@ -303,13 +385,8 @@ class KotlinJavaToolchainTest : KGPBaseTest() {
"""
import org.jetbrains.kotlin.gradle.tasks.UsesKotlinJavaToolchain
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of($jdkVersion))
}
}
def toolchain = project.extensions.getByType(JavaPluginExtension.class).toolchain
toolchain.languageVersion.set(JavaLanguageVersion.of($jdkVersion))
def service = project.extensions.getByType(JavaToolchainService.class)
def defaultLauncher = service.launcherFor(toolchain)
@@ -328,6 +405,34 @@ class KotlinJavaToolchainTest : KGPBaseTest() {
)
}
private fun TestProject.useToolchainExtension(
jdkVersion: Int
) {
//language=Groovy
rootBuildGradle.append(
"""
import org.gradle.api.plugins.JavaPluginExtension
import org.gradle.jvm.toolchain.JavaLanguageVersion
import org.gradle.jvm.toolchain.JavaToolchainService
kotlin {
toolchain {
languageVersion.set(JavaLanguageVersion.of($jdkVersion))
}
}
afterEvaluate {
def toolchain = project.extensions.getByType(JavaPluginExtension.class).toolchain
def service = project.extensions.getByType(JavaToolchainService.class)
def defaultLauncher = service.launcherFor(toolchain)
logger.info("Toolchain exec path: ${'$'}{defaultLauncher.get().executablePath.asFile.absolutePath}")
}
""".trimIndent()
)
}
private fun shouldUseToolchain(gradleVersion: GradleVersion) = gradleVersion >= GradleVersion.version("6.7")
private fun BuildResult.getToolchainExecPathFromLogs() = output
.lineSequence()
.first { it.startsWith("Toolchain exec path:") }
@@ -6,9 +6,11 @@
package org.jetbrains.kotlin.gradle.dsl
import groovy.lang.Closure
import org.gradle.api.Action
import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.Project
import org.gradle.api.internal.plugins.DslObject
import org.gradle.jvm.toolchain.JavaToolchainSpec
import org.gradle.util.ConfigureUtil
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget
@@ -53,13 +55,23 @@ internal val Project.multiplatformExtension: KotlinMultiplatformExtension
internal val Project.pm20Extension: KotlinPm20ProjectExtension
get() = extensions.getByName(KOTLIN_PROJECT_EXTENSION_NAME) as KotlinPm20ProjectExtension
open class KotlinTopLevelExtension (internal val project: Project) {
val experimental: ExperimentalExtension
get() = DslObject(this).extensions.getByType(ExperimentalExtension::class.java)
lateinit var coreLibrariesVersion: String
private val toolchainSupport = ToolchainSupport.createToolchain(project)
/**
* Configures [Java toolchain](https://docs.gradle.org/current/userguide/toolchains.html) both for Kotlin and Java tasks.
*
* @param action - action to configure [JavaToolchainSpec]. You could safely cast `Any` into `JavaToolchainSpec`.
*/
fun toolchain(action: Action<Any>) {
toolchainSupport.applyToolchain(action)
}
var explicitApi: ExplicitApiMode? = null
fun explicitApi() {
@@ -0,0 +1,99 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.gradle.dsl
import org.gradle.api.Action
import org.gradle.api.GradleException
import org.gradle.api.Project
import org.gradle.api.plugins.ExtensionContainer
import org.gradle.api.plugins.JavaPluginExtension
import org.gradle.internal.jvm.Jvm
import org.gradle.jvm.toolchain.JavaLanguageVersion
import org.gradle.jvm.toolchain.JavaToolchainService
import org.gradle.jvm.toolchain.JavaToolchainSpec
import org.gradle.jvm.toolchain.internal.DefaultToolchainSpec
import org.gradle.util.GradleVersion
import org.jetbrains.kotlin.gradle.tasks.KotlinJavaToolchain.Companion.TOOLCHAIN_SUPPORTED_VERSION
import org.jetbrains.kotlin.gradle.tasks.UsesKotlinJavaToolchain
import org.jetbrains.kotlin.gradle.tasks.withType
import org.jetbrains.kotlin.gradle.utils.newInstance
import javax.inject.Inject
internal interface ToolchainSupport {
fun applyToolchain(action: Action<Any>)
companion object {
internal fun createToolchain(
project: Project
): ToolchainSupport {
val currentVersion = GradleVersion.version(project.gradle.gradleVersion)
return when {
currentVersion < TOOLCHAIN_SUPPORTED_VERSION -> project.objects.newInstance<NonExistingToolchainSupport>()
else -> project.objects.newInstance<DefaultToolchainSupport>(project.extensions).also {
configureDefaultToolchain(project)
}
}
}
private fun configureDefaultToolchain(project: Project) {
project.plugins.withId("org.gradle.java-base") {
project
.tasks
.withType<UsesKotlinJavaToolchain>()
.configureEach {
val javaToolchainService = project
.extensions
.findByType(JavaToolchainService::class.java)!!
val javaToolchainSpec = project
.extensions
.getByType(JavaPluginExtension::class.java)
.toolchain
val toolchainSpec = if (!javaToolchainSpec.languageVersion.isPresent) {
// We can't reuse java toolchain and just set 'languageVersion' to it
// as build will fail when java source and/or target compatibility is set
project.objects.newInstance<DefaultToolchainSpec>().apply {
languageVersion.set(
JavaLanguageVersion.of(
Jvm.current().javaVersion!!.majorVersion
)
)
}
} else {
javaToolchainSpec
}
it.kotlinJavaToolchain.toolchain.use(
javaToolchainService.launcherFor(toolchainSpec)
)
}
}
}
}
}
internal abstract class NonExistingToolchainSupport : ToolchainSupport {
override fun applyToolchain(
action: Action<Any>
) {
throw GradleException("JavaToolchain support is only available from Gradle 6.7")
}
}
internal abstract class DefaultToolchainSupport @Inject constructor(
private val extensions: ExtensionContainer
) : ToolchainSupport {
private val toolchainSpec: JavaToolchainSpec
get() = extensions
.getByType(JavaPluginExtension::class.java)
.toolchain
override fun applyToolchain(
action: Action<Any>
) {
action.execute(toolchainSpec)
}
}
@@ -7,7 +7,6 @@ import org.gradle.api.internal.ConventionTask
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.Property
import org.gradle.api.provider.ProviderFactory
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.*
import org.gradle.api.tasks.incremental.IncrementalTaskInputs
@@ -121,8 +120,10 @@ abstract class KaptTask @Inject constructor(
@get:Internal
abstract val classpath: ConfigurableFileCollection
final override val kotlinJavaToolchainProvider: Provider<KotlinJavaToolchainProvider> =
objectFactory.propertyWithNewInstance()
final override val kotlinJavaToolchainProvider: Provider<KotlinJavaToolchainProvider> = objectFactory
.propertyWithNewInstance(
project.gradle
)
@Suppress("unused", "DeprecatedCallableAddReplaceWith")
@Deprecated(
@@ -114,8 +114,8 @@ abstract class KaptWithKotlincTask @Inject constructor(
val compilerRunner = GradleCompilerRunner(
taskProvider,
kotlinJavaToolchainProvider.get().javaExecutable.get().asFile,
kotlinJavaToolchainProvider.get().jdkToolsJar.orNull
kotlinJavaToolchainProvider.get().jdkProvider.javaExecutable.get().asFile,
kotlinJavaToolchainProvider.get().jdkProvider.jdkToolsJar.orNull
)
compilerRunner.runJvmCompilerAsync(
sourcesToCompile = emptyList(),
@@ -160,7 +160,9 @@ abstract class KaptWithoutKotlincTask @Inject constructor(
val kaptClasspath = kaptJars.toList() + kotlinStdlibClasspath
val isolationMode = getWorkerIsolationMode()
logger.info("Using workers $isolationMode isolation mode to run kapt")
val toolsJarURLSpec = kotlinJavaToolchainProvider.get().jdkToolsJar.orNull?.toURI()?.toURL()?.toString().orEmpty()
val toolsJarURLSpec = kotlinJavaToolchainProvider.get()
.jdkProvider
.jdkToolsJar.orNull?.toURI()?.toURL()?.toString().orEmpty()
submitWork(
isolationMode,
@@ -171,12 +173,12 @@ abstract class KaptWithoutKotlincTask @Inject constructor(
}
private fun getWorkerIsolationMode(): IsolationMode {
val kotlinJavaToolchain = kotlinJavaToolchainProvider.get()
val gradleJvm = kotlinJavaToolchain.currentJvm.get()
val jdkProvider = kotlinJavaToolchainProvider.get().jdkProvider
val gradleJvm = jdkProvider.currentJvm.get()
// Ensuring Gradle build JDK is set to kotlin toolchain by also comparing javaExecutable paths,
// as user may set JDK with same major Java version, but from different vendor
val isRunningOnGradleJvm = gradleJvm.javaVersion == kotlinJavaToolchain.javaVersion.get() &&
gradleJvm.javaExecutable.absolutePath == kotlinJavaToolchain.javaExecutable.get().asFile.absolutePath
val isRunningOnGradleJvm = gradleJvm.javaVersion == jdkProvider.javaVersion.get() &&
gradleJvm.javaExecutable.absolutePath == jdkProvider.javaExecutable.get().asFile.absolutePath
val isolationModeStr = getValue("kapt.workers.isolation")?.toLowerCase()
return when {
(isolationModeStr == null || isolationModeStr == "none") && isRunningOnGradleJvm -> IsolationMode.NONE
@@ -201,7 +203,11 @@ abstract class KaptWithoutKotlincTask @Inject constructor(
// for tests
it.forkOptions.jvmArgs("-verbose:class")
}
it.forkOptions.executable = kotlinJavaToolchainProvider.get().javaExecutable.asFile.get().absolutePath
it.forkOptions.executable = kotlinJavaToolchainProvider.get()
.jdkProvider
.javaExecutable
.asFile.get()
.absolutePath
logger.info("Kapt worker classpath: ${it.classpath}")
}
IsolationMode.NONE -> workerExecutor.noIsolation()
@@ -9,12 +9,15 @@ import org.gradle.api.GradleException
import org.gradle.api.JavaVersion
import org.gradle.api.file.ProjectLayout
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.invocation.Gradle
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.Property
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.Internal
import org.gradle.internal.jvm.Jvm
import org.gradle.jvm.toolchain.JavaLauncher
import org.gradle.jvm.toolchain.*
import org.gradle.util.GradleVersion
import org.jetbrains.kotlin.gradle.tasks.KotlinJavaToolchain.Companion.TOOLCHAIN_SUPPORTED_VERSION
import org.jetbrains.kotlin.gradle.utils.chainedFinalizeValueOnRead
import org.jetbrains.kotlin.gradle.utils.property
import org.jetbrains.kotlin.gradle.utils.propertyWithConvention
@@ -23,98 +26,187 @@ import javax.inject.Inject
abstract class KotlinJavaToolchainProvider @Inject constructor(
objects: ObjectFactory,
files: ProjectLayout
projectLayout: ProjectLayout,
gradle: Gradle
) : KotlinJavaToolchain {
@get:Internal
internal val currentJvm: Property<Jvm> = objects
.property<Jvm>(Jvm.current())
.chainedFinalizeValueOnRead()
private val _javaVersion: Property<JavaVersion> = objects
.propertyWithConvention(
currentJvm.map { jvm ->
jvm.javaVersion
?: throw GradleException(
"Kotlin could not get java version for the JDK installation: " +
jvm.javaHome?.let { "'$it' " }.orEmpty()
)
}
private val defaultJdkSetter by lazy(LazyThreadSafetyMode.NONE) {
DefaultJdkSetter(
objects,
projectLayout,
GradleVersion.version(gradle.gradleVersion)
)
}
private val defaultJavaToolchainSetter by lazy(LazyThreadSafetyMode.NONE) {
if (GradleVersion.version(gradle.gradleVersion) >= TOOLCHAIN_SUPPORTED_VERSION) {
DefaultJavaToolchainSetter(objects)
} else {
null
}
}
@get:Internal
internal val jdkProvider: JdkProvider =
if (GradleVersion.version(gradle.gradleVersion) < TOOLCHAIN_SUPPORTED_VERSION) {
defaultJdkSetter
} else {
defaultJavaToolchainSetter!!
}
final override val javaVersion: Provider<JavaVersion>
get() = _javaVersion
get() = jdkProvider.javaVersion
@get:Internal
internal val javaExecutable: RegularFileProperty = objects
.fileProperty()
.convention(
currentJvm.flatMap { jvm ->
files.file(
objects.property<File>(
jvm.javaExecutable
?: throw GradleException(
"Kotlin could not find 'java' executable in the JDK installation: " +
jvm.javaHome?.let { "'$it' " }.orEmpty()
)
final override val jdk: KotlinJavaToolchain.JdkSetter get() = defaultJdkSetter
final override val toolchain: KotlinJavaToolchain.JavaToolchainSetter
get() = defaultJavaToolchainSetter
?: throw GradleException("Toolchain support is available from $TOOLCHAIN_SUPPORTED_VERSION")
internal interface JdkProvider {
val currentJvm: Property<Jvm>
val javaExecutable: RegularFileProperty
val javaVersion: Property<JavaVersion>
val jdkToolsJar: Provider<File?>
companion object {
fun jdkToolsProperty(
objectsFactory: ObjectFactory,
currentJvm: Provider<Jvm>
): Property<File?> = objectsFactory
.propertyWithConvention(
currentJvm.flatMap { jvm ->
objectsFactory.propertyWithConvention(jvm.toolsJar)
}
)
fun defaultJdkToolsJarProvider(
objectsFactory: ObjectFactory,
javaVersion: Property<JavaVersion>,
jdkTools: Property<File?>
): Provider<File?> = jdkTools
.orElse(javaVersion.flatMap {
if (it < JavaVersion.VERSION_1_9) {
throw GradleException(
"Kotlin could not find the required JDK tools in the Java installation. " +
"Make sure Kotlin compilation is running on a JDK, not JRE."
)
} else {
objectsFactory.propertyWithConvention<File?>(null)
}
})
}
}
private class DefaultJdkSetter(
private val objectsFactory: ObjectFactory,
projectLayout: ProjectLayout,
private val currentGradleVersion: GradleVersion
) : KotlinJavaToolchain.JdkSetter,
JdkProvider {
override val currentJvm: Property<Jvm> = objectsFactory
.property(Jvm.current())
.chainedFinalizeValueOnRead()
override val javaExecutable: RegularFileProperty = objectsFactory
.fileProperty()
.convention(
currentJvm.flatMap { jvm ->
projectLayout.file(
objectsFactory.property<File>(
jvm.javaExecutable
?: throw GradleException(
"Kotlin could not find 'java' executable in the JDK installation: " +
jvm.javaHome?.let { "'$it' " }.orEmpty()
)
)
)
)
}
}
)
.chainedFinalizeValueOnRead()
override val javaVersion: Property<JavaVersion> = objectsFactory
.propertyWithConvention(
currentJvm.map { jvm ->
jvm.javaVersion
?: throw GradleException(
"Kotlin could not get java version for the JDK installation: " +
jvm.javaHome?.let { "'$it' " }.orEmpty()
)
}
)
private val _jdkToolsJar: Property<File?> = JdkProvider.jdkToolsProperty(
objectsFactory,
currentJvm
)
.chainedFinalizeValueOnRead()
private val _jdkToolsJar = objects
.propertyWithConvention(
currentJvm.flatMap { jvm ->
objects.propertyWithConvention(jvm.toolsJar)
}
override val jdkToolsJar: Provider<File?> = JdkProvider.defaultJdkToolsJarProvider(
objectsFactory,
javaVersion,
_jdkToolsJar
)
.chainedFinalizeValueOnRead()
@get:Internal
internal val jdkToolsJar: Provider<File?> = _jdkToolsJar
.orElse(javaVersion.flatMap {
if (it < JavaVersion.VERSION_1_9) {
throw GradleException(
"Kotlin could not find the required JDK tools in the Java installation. " +
"Make sure Kotlin compilation is running on a JDK, not JRE."
)
}
objects.propertyWithConvention<File?>(null)
})
override val jdk: KotlinJavaToolchain.JdkSetter = DefaultJdkSetter()
override val toolchain: KotlinJavaToolchain.JavaToolchainSetter = DefaultJavaToolchainSetter()
private inner class DefaultJdkSetter : KotlinJavaToolchain.JdkSetter {
override fun use(
jdkHomeLocation: File,
jdkVersion: JavaVersion
) {
if (currentGradleVersion >= TOOLCHAIN_SUPPORTED_VERSION) {
throw GradleException(
"Please use Java toolchains instead"
)
}
val jvm = Jvm.forHome(jdkHomeLocation) as Jvm
javaExecutable.set(jvm.javaExecutable)
_jdkToolsJar.set(jvm.toolsJar)
_javaVersion.set(jdkVersion)
javaVersion.set(jdkVersion)
}
}
private inner class DefaultJavaToolchainSetter : KotlinJavaToolchain.JavaToolchainSetter {
private class DefaultJavaToolchainSetter(
objectsFactory: ObjectFactory
) : KotlinJavaToolchain.JavaToolchainSetter,
JdkProvider {
private val javaLauncher: Property<JavaLauncher> = objectsFactory.property()
override val currentJvm: Property<Jvm> = objectsFactory
.propertyWithConvention(
javaLauncher.map {
Jvm.forHome(it.metadata.installationPath.asFile) as Jvm
}
)
override val javaExecutable: RegularFileProperty = objectsFactory
.fileProperty()
.apply {
set(javaLauncher.map { it.executablePath })
}
override val javaVersion: Property<JavaVersion> = objectsFactory
.property(
javaLauncher.map {
JavaVersion.toVersion(it.metadata.languageVersion.asInt())
}
)
private val _jdkToolsJar = JdkProvider.jdkToolsProperty(
objectsFactory,
currentJvm
)
override val jdkToolsJar: Provider<File?> = JdkProvider.defaultJdkToolsJarProvider(
objectsFactory,
javaVersion,
_jdkToolsJar
)
override fun use(
javaLauncher: Provider<JavaLauncher>
) {
javaExecutable.set(javaLauncher.map { it.executablePath })
_javaVersion.set(
javaLauncher.map {
JavaVersion.toVersion(it.metadata.languageVersion)
}
)
_jdkToolsJar.set(
javaLauncher.map {
Jvm.forHome(it.metadata.installationPath.asFile).toolsJar
}
)
this.javaLauncher.set(javaLauncher)
}
}
}
@@ -245,16 +245,18 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> : AbstractKotl
private val kotlinLogger by lazy { GradleKotlinLogger(logger) }
final override val kotlinJavaToolchainProvider: Provider<KotlinJavaToolchainProvider> =
objects.propertyWithNewInstance()
final override val kotlinJavaToolchainProvider: Provider<KotlinJavaToolchainProvider> = objects
.propertyWithNewInstance(
project.gradle
)
@get:Internal
internal val compilerRunner: Provider<GradleCompilerRunner> =
objects.propertyWithConvention(
kotlinJavaToolchainProvider.map {
compilerRunner(
it.javaExecutable.get().asFile,
it.jdkToolsJar.orNull
it.jdkProvider.javaExecutable.get().asFile,
it.jdkProvider.jdkToolsJar.orNull
)
}
)
@@ -42,6 +42,8 @@ internal inline fun <reified T : Any?> ObjectFactory.property() = property(T::cl
internal inline fun <reified T : Any?> ObjectFactory.property(initialValue: T) = property<T>().value(initialValue)
internal inline fun <reified T : Any?> ObjectFactory.property(initialValue: Provider<T>) = property<T>().value(initialValue)
internal inline fun <reified T : Any?> ObjectFactory.propertyWithConvention(
conventionValue: Provider<T>
) = property<T>().convention(conventionValue)
@@ -52,9 +54,12 @@ internal inline fun <reified T : Any?> ObjectFactory.propertyWithConvention(
internal inline fun <reified T : Any> ObjectFactory.newInstance() = newInstance(T::class.java)
internal inline fun <reified T : Any> ObjectFactory.newInstance(vararg parameters: Any) =
newInstance(T::class.java, *parameters)
internal inline fun <reified T : Any> ObjectFactory.propertyWithNewInstance(
vararg parameters: Any
) = propertyWithConvention(newInstance(T::class.java, parameters))
) = propertyWithConvention(newInstance(T::class.java, *parameters))
internal inline fun <reified T : Any> ObjectFactory.propertyWithNewInstance() =
propertyWithConvention(newInstance<T>())