diff options
author | Lex Spoon <lex@lexspoon.org> | 2007-07-13 19:26:01 +0000 |
---|---|---|
committer | Lex Spoon <lex@lexspoon.org> | 2007-07-13 19:26:01 +0000 |
commit | 7e617efa8fb2a2f04672f1aa77430535a4c89d3e (patch) | |
tree | 2db3dd5156f41272b0ff9af03994522e7af12f0c | |
parent | f6a91763080edaf39e94983f1da7156139b6b491 (diff) | |
download | scala-7e617efa8fb2a2f04672f1aa77430535a4c89d3e.tar.gz scala-7e617efa8fb2a2f04672f1aa77430535a4c89d3e.tar.bz2 scala-7e617efa8fb2a2f04672f1aa77430535a4c89d3e.zip |
- set the Java "context classloader" in ObjectR...
- set the Java "context classloader" in ObjectRunner and InterpreterLoop
- tweaked the start up of the interactive shell so that a prompt appears
more quickly
-rw-r--r-- | src/compiler/scala/tools/nsc/InterpreterLoop.scala | 17 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/ObjectRunner.scala | 55 |
2 files changed, 41 insertions, 31 deletions
diff --git a/src/compiler/scala/tools/nsc/InterpreterLoop.scala b/src/compiler/scala/tools/nsc/InterpreterLoop.scala index d0b39d1fcd..3d587d7279 100644 --- a/src/compiler/scala/tools/nsc/InterpreterLoop.scala +++ b/src/compiler/scala/tools/nsc/InterpreterLoop.scala @@ -20,7 +20,7 @@ import nsc.{InterpreterResults=>IR} * After instantiation, clients should call the <code>main()</code> method. * * @author Lex Spoon - * @version 1.0 + * @version 1.1 */ class InterpreterLoop(in0: BufferedReader, out: PrintWriter) { def this() = this(new BufferedReader(new InputStreamReader(System.in)), @@ -34,6 +34,10 @@ class InterpreterLoop(in0: BufferedReader, out: PrintWriter) { */ var interactive = true + /** The context class loader at the time this object was created */ + protected val originalClassLoader = + Thread.currentThread.getContextClassLoader + var settings: Settings = _ // set by main() var interpreter: Interpreter = null // set by createInterpreter() def isettings = interpreter.isettings @@ -55,6 +59,7 @@ class InterpreterLoop(in0: BufferedReader, out: PrintWriter) { if (interpreter ne null) { interpreter.close interpreter = null + Thread.currentThread.setContextClassLoader(originalClassLoader) } } @@ -72,6 +77,7 @@ class InterpreterLoop(in0: BufferedReader, out: PrintWriter) { interpreter = new Interpreter(settings, out) { override protected def parentClassLoader = parentClassLoader0 } + interpreter.setContextClassLoader() } /** Bind the settings so that evaluated code can modiy them */ @@ -96,10 +102,11 @@ class InterpreterLoop(in0: BufferedReader, out: PrintWriter) { } /** Print a welcome message */ - def printWelcome { + def printWelcome() { out.println("Welcome to Scala version " + Properties.versionString + ".") out.println("Type in expressions to have them evaluated.") out.println("Type :help for more information.") + out.flush() } /** Prompt to print when awaiting input */ @@ -267,9 +274,9 @@ class InterpreterLoop(in0: BufferedReader, out: PrintWriter) { try { if (interpreter.reporter.hasErrors) { return // it is broken on startup; go ahead and exit - } - printWelcome - repl + } + printWelcome() + repl() } finally { closeInterpreter() } diff --git a/src/compiler/scala/tools/nsc/ObjectRunner.scala b/src/compiler/scala/tools/nsc/ObjectRunner.scala index b674e18755..f2fb6d6cd7 100644 --- a/src/compiler/scala/tools/nsc/ObjectRunner.scala +++ b/src/compiler/scala/tools/nsc/ObjectRunner.scala @@ -14,22 +14,19 @@ import java.net.{URL, URLClassLoader} /** An object that runs another object specified by name. * * @author Lex Spoon - * @version 1.0, 15/06/2006 + * @version 1.1, 2007/7/13 */ object ObjectRunner { + /** Create a class loader for the specified class path */ + private def makeClassLoader(classpath: List[URL]) = + new URLClassLoader(classpath.toArray, null) - /** Look up a class with a given class path. - * - * @param classpath ... - * @param objectName ... - * @return ... - */ - private def findClass(classpath: List[URL], objectName: String) + /** Look up a class with a given class path. */ + private def findClass(loader: ClassLoader, objectName: String) : Option[Class] = { try { - val mainLoader = new URLClassLoader(classpath.toArray, null) - Some(Class.forName(objectName, true, mainLoader)) + Some(Class.forName(objectName, true, loader)) } catch { case e: SecurityException => Console.println(e.getMessage) @@ -40,28 +37,32 @@ object ObjectRunner { } /** Check whether a class with the specified name - * exists on the specified class path. - * - * @param classpath ... - * @param objectName ... - * @return <code>true</code> iff ... - */ + * exists on the specified class path. */ def classExists(classpath: List[URL], objectName: String): Boolean = - !findClass(classpath, objectName).isEmpty + !findClass(makeClassLoader(classpath), objectName).isEmpty + + /** Set the Java context class loader while executing an action */ + def withContextClassLoader[T](loader: ClassLoader)(action: =>T): T = { + val oldLoader = Thread.currentThread.getContextClassLoader + try { + Thread.currentThread.setContextClassLoader(loader) + action + } finally { + Thread.currentThread.setContextClassLoader(oldLoader) + } + } + /** Run a given object, specified by name, using a * specified classpath and argument list. * - * @param classpath ... - * @param objectName ... - * @param arguments ... - * - * @throws ClassNotFoundException ... - * @throws NoSuchMethodError ... - * @throws InvocationTargetException ... + * @throws ClassNotFoundException + * @throws NoSuchMethodError + * @throws InvocationTargetException */ def run(classpath: List[URL], objectName: String, arguments: Seq[String]) { - val clsToRun = findClass(classpath, objectName) match { + val loader = makeClassLoader(classpath) + val clsToRun = findClass(loader, objectName) match { case Some(cls) => cls case None => throw new ClassNotFoundException(objectName) } @@ -70,6 +71,8 @@ object ObjectRunner { if ((method.getModifiers & Modifier.STATIC) == 0) throw new NoSuchMethodException(objectName + ".main is not static") - method.invoke(null, List(arguments.toArray).toArray) + withContextClassLoader(loader) { + method.invoke(null, List(arguments.toArray).toArray) + } } } |