mirror of https://github.com/sbt/sbt.git
Make 'run' reuse warm Scala class loader and same JLine as sbt
This commit is contained in:
parent
250a05c4a3
commit
3493aa5285
|
|
@ -1,2 +1,5 @@
|
|||
LazyJettyRun6.scala
|
||||
LazyJettyRun7.scala
|
||||
install/project/boot/
|
||||
scripted/project/boot/
|
||||
project/plugins/project/
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ class SbtProject(info: ProjectInfo) extends DefaultProject(info) with test.SbtSc
|
|||
//val publishTo = Resolver.file("technically", new File("/var/dbwww/repo/"))
|
||||
val technically = Resolver.url("technically.us", new URL("http://databinder.net/repo/"))(Resolver.ivyStylePatterns)
|
||||
|
||||
override def compileOptions = Nil
|
||||
override def compileOptions = CompileOption("-Xno-varargs-conversion") :: Nil
|
||||
|
||||
/** configuration of scripted testing **/
|
||||
// Set to false to show logging as it happens without buffering, true to buffer until it completes and only show if the task fails.
|
||||
|
|
|
|||
|
|
@ -250,7 +250,7 @@ abstract class BasicScalaProject extends ScalaProject with BasicDependencyProjec
|
|||
fork match
|
||||
{
|
||||
case Some(fr: ForkScalaRun) => new ForkRun(fr)
|
||||
case _ => new Run(buildCompiler)
|
||||
case _ => new Run(buildScalaInstance)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import scala.tools.nsc.util.ClassPath
|
|||
|
||||
import java.io.File
|
||||
import java.net.{URL, URLClassLoader}
|
||||
import java.lang.reflect.Modifier.{isPublic, isStatic}
|
||||
|
||||
trait ScalaRun
|
||||
{
|
||||
|
|
@ -35,14 +36,45 @@ class ForkRun(config: ForkScalaRun) extends ScalaRun
|
|||
Some("Nonzero exit code returned from " + label + ": " + exitCode)
|
||||
}
|
||||
}
|
||||
class Run(compiler: xsbt.AnalyzingCompiler) extends ScalaRun
|
||||
class Run(instance: xsbt.ScalaInstance) extends ScalaRun
|
||||
{
|
||||
/** Runs the class 'mainClass' using the given classpath and options using the scala runner.*/
|
||||
def run(mainClass: String, classpath: Iterable[Path], options: Seq[String], log: Logger) =
|
||||
{
|
||||
def execute = compiler.run(Set() ++ classpath.map(_.asFile), mainClass, options, log)
|
||||
log.info("Running " + mainClass + " " + options.mkString(" "))
|
||||
|
||||
def execute =
|
||||
try { run0(mainClass, classpath, options, log) }
|
||||
catch { case e: java.lang.reflect.InvocationTargetException => throw e.getCause }
|
||||
|
||||
Run.executeTrapExit( execute, log )
|
||||
}
|
||||
private def run0(mainClassName: String, classpath: Iterable[Path], options: Seq[String], log: Logger)
|
||||
{
|
||||
val loader = getLoader(classpath, log)
|
||||
val main = getMainMethod(mainClassName, loader)
|
||||
|
||||
val currentThread = Thread.currentThread
|
||||
val oldLoader = Thread.currentThread.getContextClassLoader()
|
||||
currentThread.setContextClassLoader(loader)
|
||||
try { main.invoke(null, options.toArray[String].asInstanceOf[Array[String]] ) }
|
||||
finally { currentThread.setContextClassLoader(oldLoader) }
|
||||
}
|
||||
def getMainMethod(mainClassName: String, loader: ClassLoader) =
|
||||
{
|
||||
val mainClass = Class.forName(mainClassName, true, loader)
|
||||
val method = mainClass.getMethod("main", classOf[Array[String]])
|
||||
val modifiers = method.getModifiers
|
||||
if(!isPublic(modifiers)) throw new NoSuchMethodException(mainClassName + ".main is not public")
|
||||
if(!isStatic(modifiers)) throw new NoSuchMethodException(mainClassName + ".main is not static")
|
||||
method
|
||||
}
|
||||
def getLoader(classpath: Iterable[Path], log: Logger) =
|
||||
{
|
||||
val classpathURLs = classpath.toSeq.map(_.asURL).toArray
|
||||
log.debug(" Classpath:\n\t" + classpathURLs.mkString("\n\t"))
|
||||
new URLClassLoader( classpathURLs, instance.loader)
|
||||
}
|
||||
}
|
||||
|
||||
/** This module is an interface to starting the scala interpreter or runner.*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue