Fix runtime scala-reflect layer

For best caching performance, we want to use the scala-reflect.jar that
is found in the scala instance. Also, in the runtime configuration,
caching didn't work correctly because we filtered the scala reflect
library from the dependency jars. We really only wanted to filter out
the library jars.

It also was problematic to use a LayeredClassLoader for the scala
reflect layer because in a subsequent commit I add the capability for a
layered classloader to load classes from its descendant loaders. This
caused problems when the scala-reflect layer was a LayeredClassLoader.
Instead, I add the ScalaReflectClassLoader class for better reporting.
This commit is contained in:
Ethan Atkins 2019-06-03 14:00:48 -07:00
parent dc20eb2d4a
commit a3cde88db4
1 changed files with 17 additions and 4 deletions

View File

@ -76,7 +76,7 @@ private[sbt] object ClassLoaders {
)
s.log.warn(s"$showJavaOptions will be ignored, $showFork is set to false")
}
val exclude = dependencyJars(exportedProducts).value.toSet ++ instance.allJars
val exclude = dependencyJars(exportedProducts).value.toSet ++ instance.libraryJars
val allDeps = dependencyJars(dependencyClasspath).value.filterNot(exclude)
val newLoader =
(classpath: Seq[File]) => {
@ -135,10 +135,22 @@ private[sbt] object ClassLoaders {
val scalaLibraryLayer = layer(si.libraryJars, interfaceLoader, cache, resources, tmp)
val cpFiles = fullCP.map(_._1)
val scalaReflectJar = allDependencies.find(_.getName == "scala-reflect.jar")
val scalaReflectJar = allDependencies.collectFirst {
case f if f.getName == "scala-reflect.jar" =>
si.allJars.find(_.getName == "scala-reflect.jar")
}.flatten
class ScalaReflectClassLoader(jar: File)
extends URLClassLoader(Array(jar.toURI.toURL), scalaLibraryLayer) {
override def toString: String =
s"ScalaReflectClassLoader($jar, parent = $scalaLibraryLayer)"
}
val scalaReflectLayer = scalaReflectJar
.map { file =>
layer(file :: Nil, scalaLibraryLayer, cache, resources, tmp)
cache.apply(
file -> IO.getModifiedTimeOrZero(file) :: Nil,
scalaLibraryLayer,
() => new ScalaReflectClassLoader(file)
)
}
.getOrElse(scalaLibraryLayer)
@ -153,11 +165,12 @@ private[sbt] object ClassLoaders {
if (layerDependencies) layer(allDependencies, resourceLayer, cache, resources, tmp)
else resourceLayer
val scalaJarNames = (si.libraryJars ++ scalaReflectJar).map(_.getName).toSet
// layer 4
val filteredSet =
if (layerDependencies) allDependencies.toSet ++ si.libraryJars ++ scalaReflectJar
else Set(si.libraryJars ++ scalaReflectJar: _*)
val dynamicClasspath = cpFiles.filterNot(filteredSet)
val dynamicClasspath = cpFiles.filterNot(f => filteredSet(f) || scalaJarNames(f.getName))
new LayeredClassLoader(dynamicClasspath, dependencyLayer, resources, tmp)
}
ClasspathUtilities.filterByClasspath(cpFiles, raw)