[Gradle] Fix classpath cache key in ClassLoadersCachingBuildService

Lists have defined contracts for equals and hashCode and thus might be used as map keys for the sake of caching. Gradle's file collections do not follow those contracts, leading to cache misses and creating too many classloaders.
#KT-61426 Fixed
This commit is contained in:
Alexander.Likhachev
2023-08-18 15:26:42 +02:00
committed by Space Team
parent 693b4cf308
commit a3e8767fb1
2 changed files with 6 additions and 5 deletions
@@ -33,13 +33,14 @@ internal abstract class ClassLoadersCachingBuildService : BuildService<BuildServ
private val logger = Logging.getLogger(javaClass)
fun getClassLoader(
classpath: Iterable<File>,
classpath: List<File>,
parentClassLoaderProvider: ParentClassLoaderProvider = DefaultParentClassLoaderProvider()
) =
classLoaders.computeIfAbsent(ClassLoaderCacheKey(classpath, parentClassLoaderProvider)) {
): ClassLoader {
return classLoaders.computeIfAbsent(ClassLoaderCacheKey(classpath, parentClassLoaderProvider)) {
logger.debug("Creating a new classloader for classpath $classpath")
URLClassLoader(classpath.map { it.toURI().toURL() }.toTypedArray(), parentClassLoaderProvider.getClassLoader())
}
}
override fun close() {
logger.debug("Clearing ${classLoaders.size} cached classloaders")
@@ -59,7 +60,7 @@ internal abstract class ClassLoadersCachingBuildService : BuildService<BuildServ
}
private data class ClassLoaderCacheKey(
val classpath: Iterable<File>,
val classpath: List<File>,
val parentClassLoaderProvider: ParentClassLoaderProvider,
)
@@ -50,7 +50,7 @@ abstract class BuildToolsApiClasspathEntrySnapshotTransform : TransformAction<Bu
try {
val classLoader = parameters.classLoadersCachingService.get()
.getClassLoader(parameters.classpath, SharedApiClassesClassLoaderProvider)
.getClassLoader(parameters.classpath.toList(), SharedApiClassesClassLoaderProvider)
val compilationService = CompilationService.loadImplementation(classLoader)
val snapshot = compilationService.calculateClasspathSnapshot(classpathEntryInputDirOrJar, granularity)
snapshot.saveSnapshot(snapshotOutputFile)