diff --git a/main/src/main/java/sbt/internal/ScalaTestFrameworkClassLoader.java b/main/src/main/java/sbt/internal/ScalaTestFrameworkClassLoader.java deleted file mode 100644 index 33d420bce..000000000 --- a/main/src/main/java/sbt/internal/ScalaTestFrameworkClassLoader.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * sbt - * Copyright 2011 - 2018, Lightbend, Inc. - * Copyright 2008 - 2010, Mark Harrah - * Licensed under Apache License 2.0 (see LICENSE) - */ - -package sbt.internal; - - import java.net.URL; - import java.net.URLClassLoader; - -final class ScalaTestFrameworkClassLoader extends URLClassLoader { - static { - ClassLoader.registerAsParallelCapable(); - } - - private final URL[] jars; - - ScalaTestFrameworkClassLoader(final URL[] jars, final ClassLoader parent) { - super(jars, parent); - this.jars = jars; - } - - @Override - public String toString() { - final StringBuilder builder = new StringBuilder(); - for (int i = 0; i < jars.length; ++ i) { - builder.append(jars[i].toString()); - if (i < jars.length - 2) builder.append(", "); - } - return "ScalaTestFrameworkClassLoader(" + builder + " parent = " + getParent() + ")"; - } -} diff --git a/main/src/main/scala/sbt/internal/ClassLoaders.scala b/main/src/main/scala/sbt/internal/ClassLoaders.scala index ff343c50b..56167c509 100644 --- a/main/src/main/scala/sbt/internal/ClassLoaders.scala +++ b/main/src/main/scala/sbt/internal/ClassLoaders.scala @@ -161,25 +161,11 @@ private[sbt] object ClassLoaders { val cpFiles = fullCP.map(_._1) val allDependencies = cpFiles.filter(allDependenciesSet) - /* - * We need to put scalatest and its dependencies (scala-xml) in its own layer so that the - * classloader for scalatest is generally not ever closed. This is because one project - * closing its scalatest loader can cause a crash in another project if that project - * is reading the scalatest bundle properties because the underlying JarFile instance is - * shared across URLClassLoaders if it points to the same jar. - * - * TODO: Make this configurable and/or add other frameworks in this layer. - */ - val (frameworkDependencies, otherDependencies) = allDependencies.partition { d => - val name = d.getName - name.startsWith("scalatest_") || name.startsWith("scalactic_") || - name.startsWith("scala-xml_") - } - def isReflectJar(f: File) = + def isReflectJar(f: File): Boolean = f.getName == "scala-reflect.jar" || f.getName.startsWith("scala-reflect-") - val scalaReflectJar = otherDependencies.collectFirst { - case f if isReflectJar(f) => si.allJars.find(isReflectJar).getOrElse(f) - } + val scalaReflectJar = allDependencies.collectFirst { + case f if isReflectJar(f) => si.allJars.find(isReflectJar) + }.flatten val scalaReflectLayer = scalaReflectJar .map { file => cache.apply( @@ -190,46 +176,35 @@ private[sbt] object ClassLoaders { } .getOrElse(scalaLibraryLayer) - // layer 2 framework jars - val frameworkLayer = - if (frameworkDependencies.isEmpty) scalaReflectLayer - else { - cache.apply( - frameworkDependencies.map(file => file -> IO.getModifiedTimeOrZero(file)).toList, - scalaLibraryLayer, - () => new ScalaTestFrameworkClassLoader(frameworkDependencies.urls, scalaReflectLayer) - ) - } - - // layer 3 (optional if in the test config and the runtime layer is not shared) + // layer 2 (optional if in the test config and the runtime layer is not shared) val dependencyLayer: ClassLoader = - if (layerDependencies && otherDependencies.nonEmpty) { + if (layerDependencies && allDependencies.nonEmpty) { cache( - otherDependencies.toList.map(f => f -> IO.getModifiedTimeOrZero(f)), - frameworkLayer, + allDependencies.toList.map(f => f -> IO.getModifiedTimeOrZero(f)), + scalaReflectLayer, () => new ReverseLookupClassLoaderHolder( - otherDependencies, - frameworkLayer, + allDependencies, + scalaReflectLayer, close, allowZombies, logger ) ) - } else frameworkLayer + } else scalaReflectLayer val scalaJarNames = (si.libraryJars ++ scalaReflectJar).map(_.getName).toSet // layer 3 val filteredSet = if (layerDependencies) allDependencies.toSet ++ si.libraryJars ++ scalaReflectJar - else Set(frameworkDependencies ++ si.libraryJars ++ scalaReflectJar: _*) + else Set(si.libraryJars ++ scalaReflectJar: _*) val dynamicClasspath = cpFiles.filterNot(f => filteredSet(f) || scalaJarNames(f.getName)) dependencyLayer match { case dl: ReverseLookupClassLoaderHolder => - dl.checkout(dynamicClasspath, tmp) + dl.checkout(cpFiles, tmp) case cl => cl.getParent match { - case dl: ReverseLookupClassLoaderHolder => dl.checkout(dynamicClasspath, tmp) + case dl: ReverseLookupClassLoaderHolder => dl.checkout(cpFiles, tmp) case _ => new LayeredClassLoader(dynamicClasspath.urls, cl, tmp, close, allowZombies, logger) } diff --git a/main/src/main/scala/sbt/internal/LayeredClassLoaders.scala b/main/src/main/scala/sbt/internal/LayeredClassLoaders.scala index 5b55bde01..579b08415 100644 --- a/main/src/main/scala/sbt/internal/LayeredClassLoaders.scala +++ b/main/src/main/scala/sbt/internal/LayeredClassLoaders.scala @@ -56,7 +56,7 @@ private[internal] final class ReverseLookupClassLoaderHolder( * * @return a ClassLoader */ - def checkout(dynamicClasspath: Seq[File], tempDir: File): ClassLoader = { + def checkout(fullClasspath: Seq[File], tempDir: File): ClassLoader = { if (closed.get()) { val msg = "Tried to extract class loader from closed ReverseLookupClassLoaderHolder. " + "Try running the `clearCaches` command and re-trying." @@ -69,7 +69,7 @@ private[internal] final class ReverseLookupClassLoaderHolder( reverseLookupClassLoader.setup(tempDir) new BottomClassLoader( ReverseLookupClassLoaderHolder.this, - dynamicClasspath.map(_.toURI.toURL).toArray, + fullClasspath.map(_.toURI.toURL).toArray, reverseLookupClassLoader, tempDir, closeThis,