alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Scala example source code file (ScalaClassLoader.scala)

This example Scala source code file (ScalaClassLoader.scala) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Scala tags/keywords

anyref, anyref, boolean, classnotfoundexception, javaclassloader, javaclassloader, net, network, option, reflection, scalaclassloader, scalaclassloader, seq, string, string, t, urlclassloader

The Scala ScalaClassLoader.scala source code

/* 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))
}

Other Scala examples (source code examples)

Here is a short list of links related to this Scala ScalaClassLoader.scala source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.