diff --git a/main/src/main/scala/sbt/ClassLoaderLayeringStrategy.scala b/main/src/main/scala/sbt/ClassLoaderLayeringStrategy.scala index 483900728..cfb360fc4 100644 --- a/main/src/main/scala/sbt/ClassLoaderLayeringStrategy.scala +++ b/main/src/main/scala/sbt/ClassLoaderLayeringStrategy.scala @@ -96,5 +96,5 @@ object ClassLoaderLayeringStrategy { /** * Add a layer on top of the ScalaLibrary layer for all of the jar dependencies. */ - object AllLibraryJars extends AllLibraryJars + case object AllLibraryJars extends AllLibraryJars } diff --git a/main/src/main/scala/sbt/internal/ClassLoaders.scala b/main/src/main/scala/sbt/internal/ClassLoaders.scala index 37ace0f72..773ec4813 100644 --- a/main/src/main/scala/sbt/internal/ClassLoaders.scala +++ b/main/src/main/scala/sbt/internal/ClassLoaders.scala @@ -105,7 +105,7 @@ private[sbt] object ClassLoaders { } /* * Create a layered classloader. There are up to four layers: - * 1) the scala instance class loader + * 1) the scala instance class loader (may actually be two layers if scala-reflect is used) * 2) the resource layer * 3) the dependency jars * 4) the rest of the classpath @@ -132,15 +132,21 @@ private[sbt] object ClassLoaders { case _: AllLibraryJars => true case _ => false } - val allDependenciesSet = allDependencies.toSet val scalaLibraryLayer = layer(si.libraryJars, interfaceLoader, cache, resources, tmp) val cpFiles = fullCP.map(_._1) + val scalaReflectJar = allDependencies.find(_.getName == "scala-reflect.jar") + val scalaReflectLayer = scalaReflectJar + .map { file => + layer(file :: Nil, scalaLibraryLayer, cache, resources, tmp) + } + .getOrElse(scalaLibraryLayer) + // layer 2 (resources) val resourceLayer = if (layerDependencies) - getResourceLayer(cpFiles, resourceCP, scalaLibraryLayer, cache, resources) - else scalaLibraryLayer + getResourceLayer(cpFiles, resourceCP, scalaReflectLayer, cache, resources) + else scalaReflectLayer // layer 3 (optional if in the test config and the runtime layer is not shared) val dependencyLayer = @@ -148,7 +154,10 @@ private[sbt] object ClassLoaders { else resourceLayer // layer 4 - val dynamicClasspath = cpFiles.filterNot(allDependenciesSet ++ si.libraryJars) + val filteredSet = + if (layerDependencies) allDependencies.toSet ++ si.libraryJars ++ scalaReflectJar + else Set(si.libraryJars ++ scalaReflectJar: _*) + val dynamicClasspath = cpFiles.filterNot(filteredSet) new LayeredClassLoader(dynamicClasspath, dependencyLayer, resources, tmp) } ClasspathUtilities.filterByClasspath(cpFiles, raw) diff --git a/sbt/src/sbt-test/classloader-cache/package-private/test b/sbt/src/sbt-test/classloader-cache/package-private/test index 64ef9d785..dd298596e 100644 --- a/sbt/src/sbt-test/classloader-cache/package-private/test +++ b/sbt/src/sbt-test/classloader-cache/package-private/test @@ -1,3 +1,5 @@ +> set Compile / classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.AllLibraryJars + -> run > set Compile / classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.Flat diff --git a/sbt/src/sbt-test/classloader-cache/scalatest/test b/sbt/src/sbt-test/classloader-cache/scalatest/test index 9b34bf4a6..055516751 100644 --- a/sbt/src/sbt-test/classloader-cache/scalatest/test +++ b/sbt/src/sbt-test/classloader-cache/scalatest/test @@ -1,3 +1,5 @@ +> set Test / classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.AllLibraryJars + > test > set Test / classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.Flat @@ -8,8 +10,14 @@ > test -> set Test / classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.AllLibraryJars - $ copy-file changes/bad.scala src/test/scala/sbt/ScalatestTest.scala -> test + +> set Test / classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.Flat + +-> test + +> set Test / classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.AllLibraryJars + +-> test