Close classloader in ScalaRun.run

It is necessary to close the run classloader in order to reuse the
dependency layer in the next run. If the loader needs to survive past
the main method, as is the case with `run` and `runMain`, then the
runWithLoader api should be used instead.

This mostly restores the behavior of classloader closing to 1.3.0 for
the tasks that use ScalaRun except for `run` and `runMain`. But unlike
1.3.0, if the classloader is closed it can still spawn a zombie
classloader.

Fixes #5124.
This commit is contained in:
Ethan Atkins 2019-09-24 11:42:07 -07:00
parent ccecf1e412
commit cfa29bafe7
1 changed files with 8 additions and 2 deletions

View File

@ -12,7 +12,7 @@ import java.lang.reflect.Method
import java.lang.reflect.Modifier.{ isPublic, isStatic }
import sbt.internal.inc.ScalaInstance
import sbt.internal.inc.classpath.ClasspathUtilities
import sbt.internal.inc.classpath.{ ClasspathFilter, ClasspathUtilities }
import sbt.internal.util.MessageOnlyException
import sbt.io.Path
import sbt.util.Logger
@ -95,7 +95,13 @@ class Run(private[sbt] val newLoader: Seq[File] => ClassLoader, trapExit: Boolea
/** Runs the class 'mainClass' using the given classpath and options using the scala runner.*/
def run(mainClass: String, classpath: Seq[File], options: Seq[String], log: Logger): Try[Unit] = {
runWithLoader(newLoader(classpath), classpath, mainClass, options, log)
val loader = newLoader(classpath)
try runWithLoader(loader, classpath, mainClass, options, log)
finally loader match {
case ac: AutoCloseable => ac.close()
case c: ClasspathFilter => c.close()
case _ =>
}
}
private def invokeMain(
loader: ClassLoader,