From 13cdbb5ea681985a09f812826aeebd0099127f82 Mon Sep 17 00:00:00 2001 From: Ethan Atkins Date: Mon, 1 Apr 2019 14:22:33 -0700 Subject: [PATCH] Don't make redundant ClassLoaderCache instance I noticed that sometimes multiple ClassLoaderCache instances were created in each configuraiton. I believe this was due to the use of inConfig(...)(...) causing multiple caches to be created. Long term, I'm not sure that taskRepository and classLoaderCache are the right solutions so I made classLoaderCache private[sbt] as well. --- main/src/main/scala/sbt/Defaults.scala | 4 ++-- main/src/main/scala/sbt/Keys.scala | 2 +- .../main/scala/sbt/internal/ClassLoaderCache.scala | 13 ++++--------- main/src/main/scala/sbt/internal/ClassLoaders.scala | 6 +++--- 4 files changed, 10 insertions(+), 15 deletions(-) diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index 2b69c710a..9fc852485 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -1772,7 +1772,7 @@ object Defaults extends BuildCommon { Classpaths.addUnmanagedLibrary ++ Vector( TaskRepository.proxy( - classLoaderCache, + Compile / classLoaderCache, // We need a cache of size four so that the subset of the runtime dependencies that are used // by the test task layers may be cached without evicting the runtime classloader layers. The // cache size should be a multiple of two to support snapshot layers. @@ -1783,7 +1783,7 @@ object Defaults extends BuildCommon { lazy val testSettings: Seq[Setting[_]] = configSettings ++ testTasks ++ Vector( TaskRepository.proxy( - classLoaderCache, + Test / classLoaderCache, // We need a cache of size two for the test dependency layers (regular and snapshot). ClassLoaderCache(2) ) diff --git a/main/src/main/scala/sbt/Keys.scala b/main/src/main/scala/sbt/Keys.scala index a056afca2..0f5894bbf 100644 --- a/main/src/main/scala/sbt/Keys.scala +++ b/main/src/main/scala/sbt/Keys.scala @@ -503,7 +503,7 @@ object Keys { val resolvedScoped = Def.resolvedScoped val pluginData = taskKey[PluginData]("Information from the plugin build needed in the main build definition.").withRank(DTask) val globalPluginUpdate = taskKey[UpdateReport]("A hook to get the UpdateReport of the global plugin.").withRank(DTask) - val classLoaderCache = taskKey[internal.ClassLoaderCache]("The cache of ClassLoaders to be used for layering in tasks that invoke other java code").withRank(DTask) + private[sbt] val classLoaderCache = taskKey[internal.ClassLoaderCache]("The cache of ClassLoaders to be used for layering in tasks that invoke other java code").withRank(DTask) private[sbt] val taskRepository = AttributeKey[TaskRepository.Repr]("task-repository", "A repository that can be used to cache arbitrary values for a given task key that can be read or filled during task evaluation.", 10000) private[sbt] val taskCancelStrategy = settingKey[State => TaskCancellationStrategy]("Experimental task cancellation handler.").withRank(DTask) diff --git a/main/src/main/scala/sbt/internal/ClassLoaderCache.scala b/main/src/main/scala/sbt/internal/ClassLoaderCache.scala index 3a2c3db04..90f4ea53b 100644 --- a/main/src/main/scala/sbt/internal/ClassLoaderCache.scala +++ b/main/src/main/scala/sbt/internal/ClassLoaderCache.scala @@ -14,17 +14,17 @@ import sbt.internal.util.TypeFunctions.Id import scala.annotation.tailrec -sealed trait ClassLoaderCache +private[sbt] sealed trait ClassLoaderCache extends Repository[Id, (Seq[File], ClassLoader, Map[String, String], File), ClassLoader] -object ClassLoaderCache { +private[sbt] object ClassLoaderCache { private type Resources = Map[String, String] private sealed trait CachedClassLoader extends ClassLoader { def close(): Unit } private sealed trait StableClassLoader extends CachedClassLoader private sealed trait SnapshotClassLoader extends CachedClassLoader - def apply(maxSize: Int): ClassLoaderCache = + def apply(maxSize: Int): ClassLoaderCache = { new ClassLoaderCache { private final def mktmp(tmp: File): File = if (maxSize > 0) Files.createTempDirectory("sbt-jni").toFile else tmp @@ -89,10 +89,5 @@ object ClassLoaderCache { } } } - def empty(newLoader: (Seq[File], ClassLoader, Resources, File) => ClassLoader): ClassLoaderCache = - new ClassLoaderCache { - override def get(key: (Seq[File], ClassLoader, Resources, File)): ClassLoader = - newLoader.tupled(key) - override def close(): Unit = {} - } + } } diff --git a/main/src/main/scala/sbt/internal/ClassLoaders.scala b/main/src/main/scala/sbt/internal/ClassLoaders.scala index 79a303f80..865ee4be8 100644 --- a/main/src/main/scala/sbt/internal/ClassLoaders.scala +++ b/main/src/main/scala/sbt/internal/ClassLoaders.scala @@ -18,7 +18,7 @@ import sbt.internal.inc.classpath.{ ClasspathUtilities, DualLoader, NullLoader } import sbt.internal.util.Attributed import sbt.internal.util.Attributed.data import sbt.io.IO -import sbt.librarymanagement.Configurations.Runtime +import sbt.librarymanagement.Configurations.{ Runtime, Test } import PrettyPrint.indent import scala.annotation.tailrec @@ -55,7 +55,7 @@ private[sbt] object ClassLoaders { dependencyJars(dependencyClasspath).value.filterNot(exclude).toSet, interfaceLoader, (Runtime / classLoaderCache).value, - classLoaderCache.value, + (Test / classLoaderCache).value, ClasspathUtilities.createClasspathResources(fullCP, si), IO.createUniqueDirectory(taskTemporaryDirectory.value), resolvedScoped.value.scope @@ -88,7 +88,7 @@ private[sbt] object ClassLoaders { s.log.warn(s"$showJavaOptions will be ignored, $showFork is set to false") } val runtimeCache = (Runtime / classLoaderCache).value - val testCache = classLoaderCache.value + val testCache = (Test / classLoaderCache).value val exclude = dependencyJars(exportedProducts).value.toSet ++ instance.allJars val newLoader = (classpath: Seq[File]) => {