diff options
author | Paul Phillips <paulp@improving.org> | 2011-11-03 04:51:58 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2011-11-03 04:51:58 +0000 |
commit | 5852fd01b78775dd8dc26af9ebd59bd1286816a3 (patch) | |
tree | 735ea1b7eea9d817e73d37642dc4981257768487 /src/compiler | |
parent | 938eab16f841fee67b2e34c983a7a2a6a5998127 (diff) | |
download | scala-5852fd01b78775dd8dc26af9ebd59bd1286816a3.tar.gz scala-5852fd01b78775dd8dc26af9ebd59bd1286816a3.tar.bz2 scala-5852fd01b78775dd8dc26af9ebd59bd1286816a3.zip |
Reflection classloader adjustment.
With this change, one can use the reflective compiler with the scala
libs on the boot classpath (the default) or not (with -nobootcp) and it
will work either way. Maybe it will work in sbt now too, but I haven't
tried it. Since I bet you will try it, review by grek.
Diffstat (limited to 'src/compiler')
3 files changed, 31 insertions, 6 deletions
diff --git a/src/compiler/scala/reflect/runtime/ToolBoxes.scala b/src/compiler/scala/reflect/runtime/ToolBoxes.scala index 6d2b97d0d1..7ec7d15fb7 100644 --- a/src/compiler/scala/reflect/runtime/ToolBoxes.scala +++ b/src/compiler/scala/reflect/runtime/ToolBoxes.scala @@ -120,7 +120,7 @@ trait ToolBoxes extends { self: Universe => lazy val exporter = importer.reverse - lazy val classLoader = new AbstractFileClassLoader(virtualDirectory, getClass.getClassLoader) + lazy val classLoader = new AbstractFileClassLoader(virtualDirectory, defaultReflectiveClassLoader) private def importAndTypeCheck(tree: rm.Tree, expectedType: rm.Type): compiler.Tree = { // need to establish a run an phase because otherwise we run into an assertion in TypeHistory diff --git a/src/compiler/scala/tools/nsc/interpreter/AbstractFileClassLoader.scala b/src/compiler/scala/tools/nsc/interpreter/AbstractFileClassLoader.scala index 85dcff2086..c79728d0b1 100644 --- a/src/compiler/scala/tools/nsc/interpreter/AbstractFileClassLoader.scala +++ b/src/compiler/scala/tools/nsc/interpreter/AbstractFileClassLoader.scala @@ -8,6 +8,7 @@ package interpreter import scala.tools.nsc.io.{ File, AbstractFile } import util.ScalaClassLoader import java.net.URL +import scala.collection.{ mutable, immutable } /** * A class loader that loads files from a {@link scala.tools.nsc.io.AbstractFile}. @@ -18,6 +19,15 @@ class AbstractFileClassLoader(root: AbstractFile, parent: ClassLoader) extends ClassLoader(parent) with ScalaClassLoader { + // private val defined = mutable.Map[String, Class[_]]() + private def cllog(msg: => String) { + if (trace) + println("[" + classLoaderUniqId + "] " + msg) + } + + override protected def trace = + sys.props contains "scala.debug.classloader" + protected def classNameToPath(name: String): String = if (name endsWith ".class") name else name.replace('.', '/') + ".class" @@ -46,10 +56,23 @@ class AbstractFileClassLoader(root: AbstractFile, parent: ClassLoader) case null => super.classBytes(name) case file => file.toByteArray } + override def loadClass(name: String, resolve: Boolean) = { + cllog("load " + name + ".") + super.loadClass(name, resolve) + } override def findClass(name: String): JClass = { val bytes = classBytes(name) - if (bytes.isEmpty) throw new ClassNotFoundException(name) - else defineClass(name, bytes, 0, bytes.length) + cllog("find %s: %s".format(name, + if (bytes.isEmpty) "failed." + else bytes.size + " bytes." + )) + if (bytes.isEmpty) + throw new ClassNotFoundException(name) + else { + val clazz = defineClass(name, bytes, 0, bytes.length) + // defined(name) = clazz + clazz + } } // Don't know how to construct an URL for something which exists only in memory // override def getResource(name: String): URL = findAbstractFile(name) match { diff --git a/src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala b/src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala index d048b75599..74a56fbc2c 100644 --- a/src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala +++ b/src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala @@ -26,6 +26,7 @@ trait HasClassPath { trait ScalaClassLoader extends JClassLoader { /** Override to see classloader activity traced */ protected def trace: Boolean = false + val classLoaderUniqId = "Cl#" + System.identityHashCode(this) /** Executing an action with this classloader as context classloader */ def asContext[T](action: => T): T = { @@ -50,13 +51,13 @@ trait ScalaClassLoader extends JClassLoader { override def findClass(name: String) = { val result = super.findClass(name) - if (trace) println("findClass(%s) = %s".format(name, result)) + // if (trace) println("findClass(%s) = %s".format(name, result)) result } override def loadClass(name: String, resolve: Boolean) = { val result = super.loadClass(name, resolve) - if (trace) println("loadClass(%s, %s) = %s".format(name, resolve, result)) + // if (trace) println("loadClass(%s, %s) = %s".format(name, resolve, result)) result } @@ -93,6 +94,7 @@ trait ScalaClassLoader extends JClassLoader { case null => Nil case p => p.loaderChain }) + override def toString = classLoaderUniqId } /** Methods for obtaining various classloaders. @@ -160,7 +162,7 @@ object ScalaClassLoader { classloaderURLs :+= url super.addURL(url) } - override def toString = urls.mkString("URLClassLoader(\n ", "\n ", "\n)\n") + def toLongString = urls.mkString("URLClassLoader(id=" + classLoaderUniqId + "\n ", "\n ", "\n)\n") } def fromURLs(urls: Seq[URL], parent: ClassLoader = null): URLClassLoader = |