diff options
author | Eugene Burmako <xeno.by@gmail.com> | 2013-05-20 11:29:10 +0200 |
---|---|---|
committer | Eugene Burmako <xeno.by@gmail.com> | 2013-05-20 11:40:41 +0200 |
commit | 8f6b4743a0fac93f671e9eff3fca2b4dec4bf935 (patch) | |
tree | c49f6d0997ca9799535ffc311ae2c07f531c432c /src/compiler | |
parent | 01dec25425cefb6acc147d8341893eb70ca76245 (diff) | |
download | scala-8f6b4743a0fac93f671e9eff3fca2b4dec4bf935.tar.gz scala-8f6b4743a0fac93f671e9eff3fca2b4dec4bf935.tar.bz2 scala-8f6b4743a0fac93f671e9eff3fca2b4dec4bf935.zip |
Moves AbstractFileClassLoader to scala-reflect.jar
Its string name was used in ReflectionUtils and became broken after repl
got factored out. This hints that that classloader belongs to where it is
used, i.e. to scala-reflect.jar.
Moreover AbstractFile is defined in scala-reflect.jar, so it's only
logical to also define a derived classloader in scala-reflect.jar.
Diffstat (limited to 'src/compiler')
3 files changed, 9 insertions, 246 deletions
diff --git a/src/compiler/scala/tools/nsc/util/AbstractFileClassLoader.scala b/src/compiler/scala/tools/nsc/util/AbstractFileClassLoader.scala deleted file mode 100644 index b204c39e9c..0000000000 --- a/src/compiler/scala/tools/nsc/util/AbstractFileClassLoader.scala +++ /dev/null @@ -1,122 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2013 LAMP/EPFL - */ - -package scala.tools.nsc -package util - -import scala.tools.nsc.io.AbstractFile -import java.security.cert.Certificate -import java.security.{ ProtectionDomain, CodeSource } -import java.net.{ URL, URLConnection, URLStreamHandler } -import scala.collection.{ mutable, immutable } - -/** - * A class loader that loads files from a {@link scala.tools.nsc.io.AbstractFile}. - * - * @author Lex Spoon - */ -class AbstractFileClassLoader(val root: AbstractFile, parent: ClassLoader) - extends ClassLoader(parent) - with ScalaClassLoader -{ - protected def classNameToPath(name: String): String = - if (name endsWith ".class") name - else name.replace('.', '/') + ".class" - - protected def findAbstractFile(name: String): AbstractFile = { - var file: AbstractFile = root - val pathParts = name split '/' - - for (dirPart <- pathParts.init) { - file = file.lookupName(dirPart, directory = true) - if (file == null) - return null - } - - file.lookupName(pathParts.last, directory = false) match { - case null => null - case file => file - } - } - - protected def dirNameToPath(name: String): String = - name.replace('.', '/') - - protected def findAbstractDir(name: String): AbstractFile = { - var file: AbstractFile = root - val pathParts = dirNameToPath(name) split '/' - - for (dirPart <- pathParts) { - file = file.lookupName(dirPart, directory = true) - if (file == null) - return null - } - - file - } - - // parent delegation in JCL uses getResource; so either add parent.getResAsStream - // or implement findResource, which we do here as a study in scarlet (my complexion - // after looking at CLs and URLs) - override def findResource(name: String): URL = findAbstractFile(name) match { - case null => null - case file => new URL(null, "repldir:" + file.path, new URLStreamHandler { - override def openConnection(url: URL): URLConnection = new URLConnection(url) { - override def connect() { } - override def getInputStream = file.input - } - }) - } - - // this inverts delegation order: super.getResAsStr calls parent.getRes if we fail - override def getResourceAsStream(name: String) = findAbstractFile(name) match { - case null => super.getResourceAsStream(name) - case file => file.input - } - // ScalaClassLoader.classBytes uses getResAsStream, so we'll try again before delegating - override def classBytes(name: String): Array[Byte] = findAbstractFile(classNameToPath(name)) match { - case null => super.classBytes(name) - case file => file.toByteArray - } - override def findClass(name: String): Class[_] = { - val bytes = classBytes(name) - if (bytes.length == 0) - throw new ClassNotFoundException(name) - else - defineClass(name, bytes, 0, bytes.length, protectionDomain) - } - - lazy val protectionDomain = { - val cl = Thread.currentThread().getContextClassLoader() - val resource = cl.getResource("scala/runtime/package.class") - if (resource == null || resource.getProtocol != "jar") null else { - val s = resource.getPath - val n = s.lastIndexOf('!') - if (n < 0) null else { - val path = s.substring(0, n) - new ProtectionDomain(new CodeSource(new URL(path), null.asInstanceOf[Array[Certificate]]), null, this, null) - } - } - } - - private val packages = mutable.Map[String, Package]() - - override def definePackage(name: String, specTitle: String, specVersion: String, specVendor: String, implTitle: String, implVersion: String, implVendor: String, sealBase: URL): Package = { - throw new UnsupportedOperationException() - } - - override def getPackage(name: String): Package = { - findAbstractDir(name) match { - case null => super.getPackage(name) - case file => packages.getOrElseUpdate(name, { - val ctor = classOf[Package].getDeclaredConstructor(classOf[String], classOf[String], classOf[String], classOf[String], classOf[String], classOf[String], classOf[String], classOf[URL], classOf[ClassLoader]) - ctor.setAccessible(true) - ctor.newInstance(name, null, null, null, null, null, null, null, this) - }) - } - } - - override def getPackages(): Array[Package] = - root.iterator.filter(_.isDirectory).map(dir => getPackage(dir.name)).toArray -} diff --git a/src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala b/src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala deleted file mode 100644 index 3899ef24c7..0000000000 --- a/src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala +++ /dev/null @@ -1,124 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2013 LAMP/EPFL - * @author Paul Phillips - */ - -package scala.tools.nsc -package util - -import java.lang.{ ClassLoader => JClassLoader } -import java.lang.reflect.{ Constructor, Modifier, Method } -import java.io.{ File => JFile } -import java.net.{ URLClassLoader => JURLClassLoader } -import java.net.URL -import scala.reflect.runtime.ReflectionUtils.unwrapHandler -import ScalaClassLoader._ -import scala.util.control.Exception.{ catching } -import scala.language.implicitConversions -import scala.reflect.{ ClassTag, classTag } - -trait HasClassPath { - def classPathURLs: Seq[URL] -} - -/** A wrapper around java.lang.ClassLoader to lower the annoyance - * of java reflection. - */ -trait ScalaClassLoader extends JClassLoader { - /** Executing an action with this classloader as context classloader */ - def asContext[T](action: => T): T = { - val saved = contextLoader - try { setContext(this) ; action } - finally setContext(saved) - } - def setAsContext() { setContext(this) } - - /** Load and link a class with this classloader */ - def tryToLoadClass[T <: AnyRef](path: String): Option[Class[T]] = tryClass(path, initialize = false) - /** Load, link and initialize a class with this classloader */ - def tryToInitializeClass[T <: AnyRef](path: String): Option[Class[T]] = tryClass(path, initialize = true) - - private def tryClass[T <: AnyRef](path: String, initialize: Boolean): Option[Class[T]] = - catching(classOf[ClassNotFoundException], classOf[SecurityException]) opt - Class.forName(path, initialize, this).asInstanceOf[Class[T]] - - /** Create an instance of a class with this classloader */ - def create(path: String): AnyRef = - tryToInitializeClass[AnyRef](path) map (_.newInstance()) orNull - - /** The actual bytes for a class file, or an empty array if it can't be found. */ - def classBytes(className: String): Array[Byte] = classAsStream(className) match { - case null => Array() - case stream => io.Streamable.bytes(stream) - } - - /** An InputStream representing the given class name, or null if not found. */ - def classAsStream(className: String) = - getResourceAsStream(className.replaceAll("""\.""", "/") + ".class") - - /** Run the main method of a class to be loaded by this classloader */ - def run(objectName: String, arguments: Seq[String]) { - val clsToRun = tryToInitializeClass(objectName) getOrElse ( - throw new ClassNotFoundException(objectName) - ) - val method = clsToRun.getMethod("main", classOf[Array[String]]) - if (!Modifier.isStatic(method.getModifiers)) - throw new NoSuchMethodException(objectName + ".main is not static") - - try asContext(method.invoke(null, Array(arguments.toArray: AnyRef): _*)) // !!! : AnyRef shouldn't be necessary - catch unwrapHandler({ case ex => throw ex }) - } -} - -/** Methods for obtaining various classloaders. - * appLoader: the application classloader. (Also called the java system classloader.) - * extLoader: the extension classloader. - * bootLoader: the boot classloader. - * contextLoader: the context classloader. - */ -object ScalaClassLoader { - /** Returns loaders which are already ScalaClassLoaders unaltered, - * and translates java.net.URLClassLoaders into scala URLClassLoaders. - * Otherwise creates a new wrapper. - */ - implicit def apply(cl: JClassLoader): ScalaClassLoader = cl match { - case cl: ScalaClassLoader => cl - case cl: JURLClassLoader => new URLClassLoader(cl.getURLs.toSeq, cl.getParent) - case _ => new JClassLoader(cl) with ScalaClassLoader - } - def contextLoader = apply(Thread.currentThread.getContextClassLoader) - def appLoader = apply(JClassLoader.getSystemClassLoader) - def setContext(cl: JClassLoader) = - Thread.currentThread.setContextClassLoader(cl) - def savingContextLoader[T](body: => T): T = { - val saved = contextLoader - try body - finally setContext(saved) - } - - class URLClassLoader(urls: Seq[URL], parent: JClassLoader) - extends JURLClassLoader(urls.toArray, parent) - with ScalaClassLoader - with HasClassPath { - - private var classloaderURLs: Seq[URL] = urls - def classPathURLs: Seq[URL] = classloaderURLs - - /** Override to widen to public */ - override def addURL(url: URL) = { - classloaderURLs :+= url - super.addURL(url) - } - } - - def fromURLs(urls: Seq[URL], parent: ClassLoader = null): URLClassLoader = - new URLClassLoader(urls, parent) - - /** True if supplied class exists in supplied path */ - def classExists(urls: Seq[URL], name: String): Boolean = - fromURLs(urls) tryToLoadClass name isDefined - - /** Finding what jar a clazz or instance came from */ - def originOfClass(x: Class[_]): Option[URL] = - Option(x.getProtectionDomain.getCodeSource) flatMap (x => Option(x.getLocation)) -} diff --git a/src/compiler/scala/tools/nsc/util/package.scala b/src/compiler/scala/tools/nsc/util/package.scala index 5faa2f7513..1e43d18900 100644 --- a/src/compiler/scala/tools/nsc/util/package.scala +++ b/src/compiler/scala/tools/nsc/util/package.scala @@ -133,4 +133,13 @@ package object util { @deprecated("Moved to scala.reflect.internal.util.BatchSourceFile", "2.10.0") type BatchSourceFile = scala.reflect.internal.util.BatchSourceFile + + @deprecated("Moved to scala.reflect.internal.util.AbstractFileClassLoader", "2.11.0") + type AbstractFileClassLoader = scala.reflect.internal.util.AbstractFileClassLoader + + @deprecated("Moved to scala.reflect.internal.util.ScalaClassLoader", "2.11.0") + val ScalaClassLoader = scala.reflect.internal.util.ScalaClassLoader + + @deprecated("Moved to scala.reflect.internal.util.ScalaClassLoader", "2.11.0") + type ScalaClassLoader = scala.reflect.internal.util.ScalaClassLoader } |