@@ -39,6 +39,7 @@ import org.gradle.api.provider.MapProperty
3939import org.gradle.api.provider.Property
4040import org.gradle.api.provider.Provider
4141import org.gradle.api.provider.SetProperty
42+ import org.gradle.api.services.ServiceReference
4243import org.gradle.api.tasks.CacheableTask
4344import org.gradle.api.tasks.Classpath
4445import org.gradle.api.tasks.IgnoreEmptyDirectories
@@ -95,6 +96,9 @@ abstract class KspAATask @Inject constructor(
9596 @get:Nested
9697 abstract val commandLineArgumentProviders: ListProperty <CommandLineArgumentProvider >
9798
99+ @get:ServiceReference(" KspAAService" )
100+ abstract val kspAAService: Property <KspAAService >
101+
98102 @TaskAction
99103 fun execute (inputChanges : InputChanges ) {
100104 // FIXME: Create a class loader with clean classpath instead of shadowing existing ones. It'll require either:
@@ -155,6 +159,7 @@ abstract class KspAATask @Inject constructor(
155159 it.removedSources = removedSources
156160 it.isInputChangeIncremental = inputChanges.isIncremental
157161 it.changedClasses = changedClasses
162+ it.kspAAService.set(kspAAService)
158163 }
159164 }
160165
@@ -167,6 +172,11 @@ abstract class KspAATask @Inject constructor(
167172 kspExtension : KspExtension ,
168173 ): TaskProvider <KspAATask > {
169174 val project = kotlinCompilation.target.project
175+ val kspAAServiceProvider = project.gradle.sharedServices.registerIfAbsent(
176+ " KspAAService" ,
177+ KspAAService ::class .java
178+ ) {}
179+
170180 val target = kotlinCompilation.target.name
171181 val sourceSetName = kotlinCompilation.defaultSourceSet.name
172182 val kspTaskName = kotlinCompileProvider.name.replaceFirst(" compile" , " ksp" )
@@ -190,6 +200,7 @@ abstract class KspAATask @Inject constructor(
190200 kspAATask.onlyIf {
191201 ! incomingProcessors.isEmpty
192202 }
203+ kspAATask.kspAAService.set(kspAAServiceProvider)
193204 kspAATask.kspClasspath.from(kspAADepCfg.incoming.artifactView { }.files)
194205 kspAATask.kspConfig.let { cfg ->
195206 cfg.processorClasspath.from(incomingProcessors)
@@ -539,25 +550,23 @@ interface KspAAWorkParameter : WorkParameters {
539550 var removedSources: List <File >
540551 var changedClasses: List <String >
541552 var isInputChangeIncremental: Boolean
553+ var kspAAService: Property <KspAAService >
542554}
543555
544- var isolatedClassLoaderCache = mutableMapOf<String , URLClassLoader >()
545556val doNotGC = mutableSetOf<Any >()
546557
547558abstract class KspAAWorkerAction : WorkAction <KspAAWorkParameter > {
548559 override fun execute () {
549560 val gradleCfg = parameters.config
550561 val kspClasspath = parameters.kspClasspath
562+ val isolatedClassLoaderCache = parameters.kspAAService.get().isolatedClassLoaderCache
551563 val key = kspClasspath.files.map { it.toURI().toURL() }.joinToString { it.path }
552- synchronized(isolatedClassLoaderCache) {
553- if (isolatedClassLoaderCache[key] == null ) {
554- isolatedClassLoaderCache[key] = URLClassLoader (
555- kspClasspath.files.map { it.toURI().toURL() }.toTypedArray(),
556- ClassLoader .getPlatformClassLoader()
557- )
558- }
564+ val isolatedClassLoader = isolatedClassLoaderCache.computeIfAbsent(key) {
565+ URLClassLoader (
566+ kspClasspath.files.map { it.toURI().toURL() }.toTypedArray(),
567+ ClassLoader .getPlatformClassLoader()
568+ )
559569 }
560- val isolatedClassLoader = isolatedClassLoaderCache[key]!!
561570
562571 // Clean stale files for now.
563572 // TODO: support incremental processing.
0 commit comments