diff --git a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/KonanCliRunnerIsolatedClassLoadersService.kt b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/KonanCliRunnerIsolatedClassLoadersService.kt new file mode 100644 index 00000000000..51d8dd6aee1 --- /dev/null +++ b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/KonanCliRunnerIsolatedClassLoadersService.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2010-2024 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.plugin.konan + +import org.gradle.api.Project +import org.gradle.api.Task +import org.gradle.api.services.BuildService +import org.gradle.api.services.BuildServiceParameters +import org.gradle.kotlin.dsl.registerIfAbsent +import java.net.URLClassLoader +import java.util.concurrent.ConcurrentHashMap + +abstract class KonanCliRunnerIsolatedClassLoadersService : BuildService, AutoCloseable { + val isolatedClassLoaders = ConcurrentHashMap() + + override fun close() { + isolatedClassLoaders.clear() + } + + companion object { + fun registerIfAbsent(project: Project) = project.gradle.sharedServices.registerIfAbsent("KonanCliRunnerIsolatedClassLoadersService", KonanCliRunnerIsolatedClassLoadersService::class.java) {} + + fun attachingToTask(task: Task): KonanCliRunnerIsolatedClassLoadersService { + val service = registerIfAbsent(task.project) + task.usesService(service) + return service.get() + } + } +} \ No newline at end of file diff --git a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/KonanToolRunner.kt b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/KonanToolRunner.kt index 15a359a34f3..da04d94169c 100644 --- a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/KonanToolRunner.kt +++ b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/KonanToolRunner.kt @@ -11,15 +11,12 @@ import org.jetbrains.kotlin.gradle.plugin.konan.KonanPlugin.ProjectProperty.KONA import org.jetbrains.kotlin.konan.target.HostManager import org.jetbrains.kotlin.konan.target.KonanTarget import java.nio.file.Files -import org.jetbrains.kotlin.* import org.jetbrains.kotlin.konan.properties.resolvablePropertyString import org.jetbrains.kotlin.konan.util.DependencyDirectories import java.io.File import java.util.Properties import org.jetbrains.kotlin.compilerRunner.KotlinToolRunner import org.jetbrains.kotlin.konan.target.AbstractToolConfig -import java.net.URLClassLoader -import java.util.concurrent.ConcurrentHashMap internal interface KonanToolRunner { fun run(args: List) @@ -33,6 +30,7 @@ private const val runFromDaemonPropertyName = "kotlin.native.tool.runFromDaemon" internal abstract class KonanCliRunner( protected val toolName: String, project: Project, + isolatedClassLoadersService: KonanCliRunnerIsolatedClassLoadersService, val additionalJvmArgs: List = emptyList(), val konanHome: String = project.konanHome ) : KotlinToolRunner(project), KonanToolRunner { @@ -79,8 +77,7 @@ internal abstract class KonanCliRunner( final override val isolatedClassLoaderCacheKey get() = IsolatedClassLoaderCacheKey(classpath) // A separate map for each build for automatic cleaning the daemon after the build have finished. - @Suppress("UNCHECKED_CAST") - final override val isolatedClassLoaders = project.project(":kotlin-native").ext["toolClassLoadersMap"] as ConcurrentHashMap + final override val isolatedClassLoaders = isolatedClassLoadersService.isolatedClassLoaders override fun transformArgs(args: List) = listOf(toolName) + args @@ -90,10 +87,11 @@ internal abstract class KonanCliRunner( /** Kotlin/Native compiler runner */ internal class KonanCliCompilerRunner( project: Project, + isolatedClassLoadersService: KonanCliRunnerIsolatedClassLoadersService, additionalJvmArgs: List = emptyList(), val useArgFile: Boolean = true, konanHome: String = project.konanHome -) : KonanCliRunner("konanc", project, additionalJvmArgs, konanHome) { +) : KonanCliRunner("konanc", project, isolatedClassLoadersService, additionalJvmArgs, konanHome) { override fun transformArgs(args: List): List { if (!useArgFile) return super.transformArgs(args) @@ -127,9 +125,10 @@ internal class CliToolConfig(konanHome: String, target: String) : AbstractToolCo /** Kotlin/Native C-interop tool runner */ internal class KonanCliInteropRunner( private val project: Project, + isolatedClassLoadersService: KonanCliRunnerIsolatedClassLoadersService, additionalJvmArgs: List = emptyList(), konanHome: String = project.konanHome -) : KonanCliRunner("cinterop", project, additionalJvmArgs, konanHome) { +) : KonanCliRunner("cinterop", project, isolatedClassLoadersService, additionalJvmArgs, konanHome) { private val projectDir = project.projectDir.toString() override val mustRunViaExec: Boolean @@ -173,9 +172,3 @@ internal class KonanCliInteropRunner( null } } - -internal class KonanKlibRunner( - project: Project, - additionalJvmArgs: List = emptyList(), - konanHome: String = project.konanHome -) : KonanCliRunner("klib", project, additionalJvmArgs, konanHome) diff --git a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/tasks/KonanCacheTask.kt b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/tasks/KonanCacheTask.kt index cd4812570d8..88e3aa0b35d 100644 --- a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/tasks/KonanCacheTask.kt +++ b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/tasks/KonanCacheTask.kt @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.konan.target.Distribution import org.jetbrains.kotlin.konan.target.PlatformManager import org.jetbrains.kotlin.library.uniqueName import org.jetbrains.kotlin.* +import org.jetbrains.kotlin.gradle.plugin.konan.KonanCliRunnerIsolatedClassLoadersService import org.jetbrains.kotlin.util.Logger import java.io.File import java.util.* @@ -82,6 +83,8 @@ abstract class KonanCacheTask : DefaultTask() { @get:Input var cachedLibraries: Map = emptyMap() + private val isolatedClassLoadersService = KonanCliRunnerIsolatedClassLoadersService.attachingToTask(this) + @TaskAction fun compile() { // This code uses bootstrap version of util-klib and fails due to the older default ABI than library being used @@ -112,6 +115,6 @@ abstract class KonanCacheTask : DefaultTask() { args += "-Xmake-per-file-cache" args += additionalCacheFlags args += cachedLibraries.map { "-Xcached-library=${it.key},${it.value}" } - KonanCliCompilerRunner(project, konanHome = konanHome).run(args) + KonanCliCompilerRunner(project, isolatedClassLoadersService, konanHome = konanHome).run(args) } } \ No newline at end of file diff --git a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/tasks/KonanCompileTask.kt b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/tasks/KonanCompileTask.kt index cb87d3930b1..a27d24212bd 100644 --- a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/tasks/KonanCompileTask.kt +++ b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/tasks/KonanCompileTask.kt @@ -22,7 +22,7 @@ import javax.inject.Inject abstract class KonanCompileTask @Inject constructor(private val layout: ProjectLayout): KonanBuildingTask(), KonanCompileSpec { @get:Internal - override val toolRunner = KonanCliCompilerRunner(project, project.konanExtension.jvmArgs) + override val toolRunner = KonanCliCompilerRunner(project, KonanCliRunnerIsolatedClassLoadersService.attachingToTask(this), project.konanExtension.jvmArgs) abstract val produce: CompilerOutputKind @Internal get diff --git a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/tasks/KonanInteropTask.kt b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/tasks/KonanInteropTask.kt index 0347558bedf..9bd79e801fd 100644 --- a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/tasks/KonanInteropTask.kt +++ b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/tasks/KonanInteropTask.kt @@ -28,7 +28,7 @@ import javax.inject.Inject abstract class KonanInteropTask @Inject constructor(private val workerExecutor: WorkerExecutor) : KonanBuildingTask(), KonanInteropSpec { - private val interopRunner = KonanCliInteropRunner(project, project.konanExtension.jvmArgs) + private val interopRunner = KonanCliInteropRunner(project, KonanCliRunnerIsolatedClassLoadersService.attachingToTask(this), project.konanExtension.jvmArgs) @get:Internal override val toolRunner: KonanToolRunner = interopRunner diff --git a/kotlin-native/build.gradle b/kotlin-native/build.gradle index a4d6aec91d7..10f138cda8a 100644 --- a/kotlin-native/build.gradle +++ b/kotlin-native/build.gradle @@ -63,9 +63,6 @@ ext { cacheableTargetNames = platformManager.hostPlatform.cacheableTargets cacheableTargets = cacheableTargetNames.collect { platformManager.targetByName(it) } - - // A separate map for each build for automatic cleaning the daemon after the build have finished. - toolClassLoadersMap = new ConcurrentHashMap() } allprojects {