scala.tools.nsc.util.ScalaClassLoader.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.apache.servicemix.bundles.scala-compiler
Show all versions of org.apache.servicemix.bundles.scala-compiler
This OSGi bundle wraps ${pkgArtifactId} ${pkgVersion} jar file.
/* NSC -- new Scala compiler
* Copyright 2005-2011 LAMP/EPFL
* @author Paul Phillips
*/
package scala.tools.nsc
package util
import java.lang.{ ClassLoader => JavaClassLoader }
import java.lang.reflect.{ Constructor, Modifier, Method }
import java.net.URL
import ScalaClassLoader._
import scala.util.control.Exception.{ catching }
trait ScalaClassLoader extends JavaClassLoader {
/** Override to see classloader activity traced */
protected def trace: Boolean = false
/** Executing an action with this classloader as context classloader */
def asContext[T](action: => T): T = {
val oldLoader = getContextLoader
try {
setContextLoader(this)
action
}
finally setContextLoader(oldLoader)
}
def setAsContext() { setContextLoader(this) }
/** Load and link a class with this classloader */
def tryToLoadClass[T <: AnyRef](path: String): Option[Class[T]] = tryClass(path, false)
/** Load, link and initialize a class with this classloader */
def tryToInitializeClass[T <: AnyRef](path: String): Option[Class[T]] = tryClass(path, 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
override def findClass(name: String) = {
val result = super.findClass(name)
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))
result
}
def constructorsOf[T <: AnyRef : Manifest]: List[Constructor[T]] =
manifest[T].erasure.getConstructors.toList map (_.asInstanceOf[Constructor[T]])
/** 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")
asContext(method.invoke(null, Array(arguments.toArray: AnyRef): _*)) // !!! : AnyRef shouldn't be necessary
}
}
object ScalaClassLoader {
implicit def apply(cl: JavaClassLoader): ScalaClassLoader = {
val loader = if (cl == null) JavaClassLoader.getSystemClassLoader() else cl
new JavaClassLoader(loader) with ScalaClassLoader
}
class URLClassLoader(urls: Seq[URL], parent: JavaClassLoader)
extends java.net.URLClassLoader(urls.toArray, parent)
with ScalaClassLoader {
private var classloaderURLs = urls.toList
private def classpathString = ClassPath.fromURLs(urls: _*)
/** Override to widen to public */
override def addURL(url: URL) = {
classloaderURLs +:= url
super.addURL(url)
}
override def run(objectName: String, arguments: Seq[String]) {
try super.run(objectName, arguments)
catch { case x: ClassNotFoundException =>
throw new ClassNotFoundException(objectName +
" (args = %s, classpath = %s)".format(arguments mkString ", ", classpathString))
}
}
override def toString = urls.mkString("URLClassLoader(\n ", "\n ", "\n)\n")
}
def setContextLoader(cl: JavaClassLoader) = Thread.currentThread.setContextClassLoader(cl)
def getContextLoader() = Thread.currentThread.getContextClassLoader()
def getSystemLoader(): ScalaClassLoader = ScalaClassLoader(null)
def defaultParentClassLoader() = findExtClassLoader()
def fromURLs(urls: Seq[URL], parent: ClassLoader = defaultParentClassLoader()): URLClassLoader =
new URLClassLoader(urls.toList, parent)
/** True if supplied class exists in supplied path */
def classExists(urls: Seq[URL], name: String): Boolean =
(fromURLs(urls) tryToLoadClass name).isDefined
// we cannot use the app classloader here or we get what looks to
// be classloader deadlock, but if we pass null we bypass the extension
// classloader and our extensions, so we search the hierarchy to find
// the classloader whose parent is null. Resolves bug #857.
def findExtClassLoader(): JavaClassLoader = {
def search(cl: JavaClassLoader): JavaClassLoader = {
if (cl == null) null
else if (cl.getParent == null) cl
else search(cl.getParent)
}
search(getContextLoader())
}
/** Finding what jar a clazz or instance came from */
def origin(x: Any): Option[URL] = originOfClass(x.asInstanceOf[AnyRef].getClass)
def originOfClass(x: Class[_]): Option[URL] =
Option(x.getProtectionDomain.getCodeSource) flatMap (x => Option(x.getLocation))
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy