Close test and run classloaders

It's good practice to call close on a URLClassLoader when we're done
with it.
This commit is contained in:
Ethan Atkins 2019-04-02 16:37:04 -07:00
parent 8ef5a67b64
commit a4f1d23d71
3 changed files with 23 additions and 9 deletions

View File

@ -8,7 +8,7 @@
package sbt
import java.io.{ File, PrintWriter }
import java.net.{ URI, URL }
import java.net.{ URI, URL, URLClassLoader }
import java.util.Optional
import java.util.concurrent.{ Callable, TimeUnit }
@ -787,9 +787,14 @@ object Defaults extends BuildCommon {
// ((streams in test, loadedTestFrameworks, testLoader, testGrouping in test, testExecution in test, fullClasspath in test, javaHome in test, testForkedParallel, javaOptions in test) flatMap allTestGroupsTask).value,
testResultLogger in (Test, test) :== TestResultLogger.SilentWhenNoTests, // https://github.com/sbt/sbt/issues/1185
test := {
val loader = testLoader.value match { case u: URLClassLoader => Some(u); case _ => None }
val trl = (testResultLogger in (Test, test)).value
val taskName = Project.showContextKey(state.value).show(resolvedScoped.value)
trl.run(streams.value.log, executeTests.value, taskName)
try {
trl.run(streams.value.log, executeTests.value, taskName)
} finally {
loader.foreach(_.close())
}
},
testOnly := inputTests(testOnly).evaluated,
testQuick := inputTests(testQuick).evaluated

View File

@ -10,14 +10,15 @@ package sbt
import java.io.File
import java.lang.reflect.{ Method, Modifier }
import Modifier.{ isPublic, isStatic }
import sbt.internal.inc.classpath.ClasspathUtilities
import sbt.internal.inc.ScalaInstance
import sbt.internal.util.MessageOnlyException
import sbt.io.Path
import sbt.util.Logger
import scala.util.{ Try, Success, Failure }
import scala.reflect.internal.util.ScalaClassLoader.URLClassLoader
import scala.util.{ Failure, Success, Try }
import scala.util.control.NonFatal
import scala.sys.process.Process
@ -90,8 +91,15 @@ class Run(newLoader: Seq[File] => ClassLoader, trapExit: Boolean) extends ScalaR
): Unit = {
log.debug(" Classpath:\n\t" + classpath.mkString("\n\t"))
val loader = newLoader(classpath)
val main = getMainMethod(mainClassName, loader)
invokeMain(loader, main, options)
try {
val main = getMainMethod(mainClassName, loader)
invokeMain(loader, main, options)
} finally {
loader match {
case u: URLClassLoader => u.close()
case _ =>
}
}
}
private def invokeMain(
loader: ClassLoader,

View File

@ -48,9 +48,10 @@ Provided by:
Defined at:
\t(sbt.Defaults.testTasks) Defaults.scala:670
Dependencies:
\tTest / executeTests
\tTest / test / streams
\tTest / state
\tTest / testLoader
\tTest / test / streams
\tTest / executeTests
\tTest / test / testResultLogger
Delegates:
\tTest / test