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

Scala example source code file (ReflectionUtils.scala)

This example Scala source code file (ReflectionUtils.scala) is included in my "Source Code Warehouse" project. The intent of this project is to help you more easily find Scala source code examples by using tags.

All credit for the original source code belongs to scala-lang.org; I'm just trying to make examples easier to find. (For my Scala work, see my Scala examples and tutorials.)

Scala tags/keywords

abstractfile, anyref, class, classloader, io, none, option, partialfunction, reflection, string, t, throwable, utilities

The ReflectionUtils.scala Scala example source code

/* NSC -- new Scala compiler
 * Copyright 2005-2013 LAMP/EPFL
 * @author  Paul Phillips
 */

package scala
package reflect.runtime

import java.lang.{Class => jClass}
import java.lang.reflect.{ Method, InvocationTargetException, UndeclaredThrowableException }
import scala.reflect.internal.util.AbstractFileClassLoader
import scala.reflect.io._
import java.io.{File => JFile}

/** A few java-reflection oriented utility functions useful during reflection bootstrapping.
 */
object ReflectionUtils {
  // Unwraps some chained exceptions which arise during reflective calls.
  def unwrapThrowable(x: Throwable): Throwable = x match {
    case  _: InvocationTargetException |      // thrown by reflectively invoked method or constructor
          _: ExceptionInInitializerError |    // thrown when running a static initializer (e.g. a scala module constructor)
          _: UndeclaredThrowableException |   // invocation on a proxy instance if its invocation handler's `invoke` throws an exception
          _: ClassNotFoundException |         // no definition for a class instantiated by name
          _: NoClassDefFoundError             // the definition existed when the executing class was compiled, but can no longer be found
            if x.getCause != null =>
              unwrapThrowable(x.getCause)
    case _ => x
  }
  // Transforms an exception handler into one which will only receive the unwrapped
  // exceptions (for the values of wrap covered in unwrapThrowable.)
  def unwrapHandler[T](pf: PartialFunction[Throwable, T]): PartialFunction[Throwable, T] = {
    case ex if pf isDefinedAt unwrapThrowable(ex)   => pf(unwrapThrowable(ex))
  }

  def show(cl: ClassLoader): String = {
    import scala.language.reflectiveCalls

    def isAbstractFileClassLoader(clazz: Class[_]): Boolean = {
      if (clazz == null) return false
      if (clazz == classOf[AbstractFileClassLoader]) return true
      isAbstractFileClassLoader(clazz.getSuperclass)
    }
    def inferClasspath(cl: ClassLoader): String = cl match {
      case cl: java.net.URLClassLoader =>
        (cl.getURLs mkString ",")
      case cl if cl != null && isAbstractFileClassLoader(cl.getClass) =>
        cl.asInstanceOf[{val root: scala.reflect.io.AbstractFile}].root.canonicalPath
      case null =>
        val loadBootCp = (flavor: String) => scala.util.Properties.propOrNone(flavor + ".boot.class.path")
        loadBootCp("sun") orElse loadBootCp("java") getOrElse "<unknown>"
      case _ =>
        "<unknown>"
    }
    cl match {
      case cl if cl != null =>
        "%s of type %s with classpath [%s] and parent being %s".format(cl, cl.getClass, inferClasspath(cl), show(cl.getParent))
      case null =>
        "primordial classloader with boot classpath [%s]".format(inferClasspath(cl))
    }
  }

  def staticSingletonInstance(cl: ClassLoader, className: String): AnyRef = {
    val name = if (className endsWith "$") className else className + "$"
    val clazz = java.lang.Class.forName(name, true, cl)
    staticSingletonInstance(clazz)
  }

  def staticSingletonInstance(clazz: Class[_]): AnyRef = clazz getField "MODULE$" get null

  def innerSingletonInstance(outer: AnyRef, className: String): AnyRef = {
    val accessorName = if (className endsWith "$") className.substring(0, className.length - 1) else className
    def singletonAccessor(clazz: Class[_]): Option[Method] =
      if (clazz == null) None
      else {
        val declaredAccessor = clazz.getDeclaredMethods.filter(_.getName == accessorName).headOption
        declaredAccessor orElse singletonAccessor(clazz.getSuperclass)
      }

    val accessor = singletonAccessor(outer.getClass) getOrElse { throw new NoSuchMethodException(s"${outer.getClass.getName}.$accessorName") }
    accessor setAccessible true
    accessor invoke outer
  }

  def isTraitImplementation(fileName: String) = fileName endsWith "$class.class"

  def scalacShouldntLoadClassfile(fileName: String) = isTraitImplementation(fileName)

  def scalacShouldntLoadClass(name: scala.reflect.internal.SymbolTable#Name) = scalacShouldntLoadClassfile(name + ".class")

  object PrimitiveOrArray {
    def unapply(jclazz: jClass[_]) = jclazz.isPrimitive || jclazz.isArray
  }

  class EnclosedIn[T](enclosure: jClass[_] => T) {
    def unapply(jclazz: jClass[_]): Option[T] = if (enclosure(jclazz) != null) Some(enclosure(jclazz)) else None
  }

  object EnclosedInMethod extends EnclosedIn(_.getEnclosingMethod)
  object EnclosedInConstructor extends EnclosedIn(_.getEnclosingConstructor)
  object EnclosedInClass extends EnclosedIn(_.getEnclosingClass)
  object EnclosedInPackage extends EnclosedIn(_.getPackage)

  def associatedFile(clazz: Class[_]): AbstractFile = {
    // TODO: I agree with Jason - this implementation isn't something that we'd like to support
    // therefore I'm having it commented out and this function will now return NoAbstractFile
    // I think we can keep the source code though, because it can be useful to the others
    //
    // def inferAssociatedFile(clazz: Class[_]): AbstractFile = {
    //   // http://stackoverflow.com/questions/227486/find-where-java-class-is-loaded-from
    //   try {
    //     var cl = clazz.getClassLoader()
    //     if (cl == null) {
    //       cl = ClassLoader.getSystemClassLoader()
    //       while (cl != null && cl.getParent != null) cl = cl.getParent
    //     }
    //     var result: AbstractFile = null
    //     if (cl != null) {
    //       val name = clazz.getCanonicalName()
    //       val resource = cl.getResource(name.replace(".", "/") + ".class")
    //       if (resource != null) {
    //         def fromFile(file: String) = AbstractFile.getFile(file)
    //         def fromJarEntry(jarfile: String, entrypath: String) = {
    //           val jar = fromFile(jarfile)
    //           new VirtualFile(clazz.getName, entrypath) {
    //             lazy val impl: AbstractFile = {
    //               def loop(root: AbstractFile, path: List[String]): AbstractFile = {
    //                 def find(name: String) = root.iterator.find(_.name == name).getOrElse(NoAbstractFile)
    //                 path match {
    //                   case step :: Nil => find(step)
    //                   case step :: rest => loop(find(step), rest)
    //                   case Nil => NoAbstractFile
    //                 }
    //               }
    //               loop(ZipArchive.fromFile(new JFile(jarfile)), entrypath.split("/").toList)
    //             }
    //             override def container        = impl.container
    //             override def lastModified     = impl.lastModified
    //             override def input            = impl.input
    //             override def sizeOption       = impl.sizeOption
    //             override def underlyingSource = Some(jar)
    //             override def toString         = jarfile + "(" + entrypath + ")"
    //           }
    //         }
    //         def fallback() = new VirtualFile(clazz.getName, resource.toString)
    //         result = resource.getProtocol match {
    //           case "file" =>
    //             fromFile(resource.getFile)
    //           case "jar" =>
    //             val intrajarUrl = new java.net.URL(resource.getFile)
    //             intrajarUrl.getProtocol match {
    //               case "file" =>
    //                 val file = intrajarUrl.getFile()
    //                 val expectedSuffix = "!/" + name.replace(".", "/") + ".class"
    //                 if (file.endsWith(expectedSuffix)) fromJarEntry(file.stripSuffix(expectedSuffix), expectedSuffix.substring(2))
    //                 else fallback()
    //               case _ => fallback()
    //             }
    //           case _ =>
    //             fallback()
    //         }
    //       }
    //     }
    //     if (result != null) result else NoAbstractFile
    //   } catch {
    //     case _: Exception => NoAbstractFile
    //   }
    // }
    // inferAssociatedFile(clazz)
    NoAbstractFile
  }
}

Other Scala source code examples

Here is a short list of links related to this Scala ReflectionUtils.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.