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
|
LazyJettyRun6.scala
|
||||||
LazyJettyRun7.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 publishTo = Resolver.file("technically", new File("/var/dbwww/repo/"))
|
||||||
val technically = Resolver.url("technically.us", new URL("http://databinder.net/repo/"))(Resolver.ivyStylePatterns)
|
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 **/
|
/** 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.
|
// 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
|
fork match
|
||||||
{
|
{
|
||||||
case Some(fr: ForkScalaRun) => new ForkRun(fr)
|
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.io.File
|
||||||
import java.net.{URL, URLClassLoader}
|
import java.net.{URL, URLClassLoader}
|
||||||
|
import java.lang.reflect.Modifier.{isPublic, isStatic}
|
||||||
|
|
||||||
trait ScalaRun
|
trait ScalaRun
|
||||||
{
|
{
|
||||||
|
|
@ -35,14 +36,45 @@ class ForkRun(config: ForkScalaRun) extends ScalaRun
|
||||||
Some("Nonzero exit code returned from " + label + ": " + exitCode)
|
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.*/
|
/** 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 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 )
|
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.*/
|
/** This module is an interface to starting the scala interpreter or runner.*/
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue