diff options
author | Paul Phillips <paulp@improving.org> | 2011-12-21 12:48:39 -0800 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2011-12-30 11:19:05 -0800 |
commit | b2b59a124a2a8adf8e88c1e692c96263e0955b16 (patch) | |
tree | 5b6fdab06c9044e94cf697fa5b6c972f0aea098a | |
parent | 9ae096330d07c1a865b934bb2bc978464824bd7e (diff) | |
download | scala-b2b59a124a2a8adf8e88c1e692c96263e0955b16.tar.gz scala-b2b59a124a2a8adf8e88c1e692c96263e0955b16.tar.bz2 scala-b2b59a124a2a8adf8e88c1e692c96263e0955b16.zip |
Better hunting for tools.jar.
Attempting to make the repl find it based on fewer clues so
all can enjoy the javap goodness.
-rw-r--r-- | src/compiler/scala/tools/nsc/Properties.scala | 5 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/interpreter/ILoop.scala | 46 | ||||
-rw-r--r-- | src/compiler/scala/tools/util/Javap.scala | 22 | ||||
-rw-r--r-- | src/library/scala/util/Properties.scala | 5 |
4 files changed, 51 insertions, 27 deletions
diff --git a/src/compiler/scala/tools/nsc/Properties.scala b/src/compiler/scala/tools/nsc/Properties.scala index d33be5bca0..c83ccfeef1 100644 --- a/src/compiler/scala/tools/nsc/Properties.scala +++ b/src/compiler/scala/tools/nsc/Properties.scala @@ -22,9 +22,4 @@ object Properties extends scala.util.PropertiesTrait { // derived values def isEmacsShell = propOrEmpty("env.emacs") != "" def fileEndings = fileEndingString.split("""\|""").toList - - // System property java.home is the JRE root. - // Environment variable JAVA_HOME is (supposed to be) the jdk root. - // We need the latter to find javac, tools.jar, etc. - def jdkHome = envOrElse("JAVA_HOME", javaHome) } diff --git a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala index 3ddbffa75e..2159ecbb8a 100644 --- a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala +++ b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala @@ -11,6 +11,7 @@ import java.io.{ BufferedReader, FileReader } import java.util.concurrent.locks.ReentrantLock import scala.sys.process.Process import session._ +import scala.util.Properties.{ jdkHome, javaVersion } import scala.tools.util.{ Signallable, Javap } import scala.annotation.tailrec import scala.collection.mutable.ListBuffer @@ -377,14 +378,29 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter) } } + private def findToolsJar() = { + val jdkPath = Directory(jdkHome) + val jar = jdkPath / "lib" / "tools.jar" toFile; + + if (jar isFile) + Some(jar) + else if (jdkPath.isDirectory) + jdkPath.deepFiles find (_.name == "tools.jar") + else None + } private def addToolsJarToLoader() = { - val javaHome = Directory(sys.env("JAVA_HOME")) - val tools = javaHome / "lib" / "tools.jar" - if (tools.isFile) { - echo("Found tools.jar, adding for use by javap.") - ScalaClassLoader.fromURLs(Seq(tools.toURL), intp.classLoader) + val cl = findToolsJar match { + case Some(tools) => ScalaClassLoader.fromURLs(Seq(tools.toURL), intp.classLoader) + case _ => intp.classLoader + } + if (Javap.isAvailable(cl)) { + repldbg(":javap available.") + cl + } + else { + repldbg(":javap unavailable: no tools.jar at " + jdkHome) + intp.classLoader } - else intp.classLoader } protected def newJavap() = new JavapClass(addToolsJarToLoader(), new IMain.ReplStrippingWriter(intp)) { @@ -431,14 +447,16 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter) private def javapCommand(line: String): Result = { if (javap == null) - return ":javap unavailable on this platform." - if (line == "") - return ":javap [-lcsvp] [path1 path2 ...]" - - javap(words(line)) foreach { res => - if (res.isError) return "Failed: " + res.value - else res.show() - } + ":javap unavailable, no tools.jar at %s. Set JDK_HOME.".format(jdkHome) + else if (javaVersion startsWith "1.7") + ":javap not yet working with java 1.7" + else if (line == "") + ":javap [-lcsvp] [path1 path2 ...]" + else + javap(words(line)) foreach { res => + if (res.isError) return "Failed: " + res.value + else res.show() + } } private def keybindingsCommand(): Result = { if (in.keyBindings.isEmpty) "Key bindings unavailable." diff --git a/src/compiler/scala/tools/util/Javap.scala b/src/compiler/scala/tools/util/Javap.scala index 0c359a2619..6d5988d1dd 100644 --- a/src/compiler/scala/tools/util/Javap.scala +++ b/src/compiler/scala/tools/util/Javap.scala @@ -36,17 +36,21 @@ class JavapClass( lazy val parser = new JpOptions - val EnvClass = loader.tryToInitializeClass[FakeEnvironment](Env).orNull - val EnvCtr = EnvClass.getConstructor(List[Class[_]](): _*) - + val EnvClass = loader.tryToInitializeClass[FakeEnvironment](Env).orNull val PrinterClass = loader.tryToInitializeClass[FakePrinter](Printer).orNull - val PrinterCtr = PrinterClass.getConstructor(classOf[InputStream], classOf[PrintWriter], EnvClass) + private def failed = (EnvClass eq null) || (PrinterClass eq null) + + val PrinterCtr = ( + if (failed) null + else PrinterClass.getConstructor(classOf[InputStream], classOf[PrintWriter], EnvClass) + ) def findBytes(path: String): Array[Byte] = tryFile(path) getOrElse tryClass(path) def apply(args: Seq[String]): List[JpResult] = { - args.toList filterNot (_ startsWith "-") map { path => + if (failed) Nil + else args.toList filterNot (_ startsWith "-") map { path => val bytes = findBytes(path) if (bytes.isEmpty) new JpError("Could not find class bytes for '%s'".format(path)) else new JpSuccess(newPrinter(new ByteArrayInputStream(bytes), newEnv(args))) @@ -54,12 +58,14 @@ class JavapClass( } def newPrinter(in: InputStream, env: FakeEnvironment): FakePrinter = - PrinterCtr.newInstance(in, printWriter, env) + if (failed) null + else PrinterCtr.newInstance(in, printWriter, env) def newEnv(opts: Seq[String]): FakeEnvironment = { - val env: FakeEnvironment = EnvClass.newInstance() + lazy val env: FakeEnvironment = EnvClass.newInstance() - parser(opts) foreach { case (name, value) => + if (failed) null + else parser(opts) foreach { case (name, value) => val field = EnvClass getDeclaredField name field setAccessible true field.set(env, value.asInstanceOf[AnyRef]) diff --git a/src/library/scala/util/Properties.scala b/src/library/scala/util/Properties.scala index 998661895b..22de5544a8 100644 --- a/src/library/scala/util/Properties.scala +++ b/src/library/scala/util/Properties.scala @@ -142,6 +142,11 @@ private[scala] trait PropertiesTrait { */ def isWin = osName startsWith "Windows" def isMac = javaVendor startsWith "Apple" + + // This is looking for javac, tools.jar, etc. + // Tries JDK_HOME first, then the more common but likely jre JAVA_HOME, + // and finally the system property based javaHome. + def jdkHome = envOrElse("JDK_HOME", envOrElse("JAVA_HOME", javaHome)) def versionMsg = "Scala %s %s -- %s".format(propCategory, versionString, copyrightString) def scalaCmd = if (isWin) "scala.bat" else "scala" |