jeudi 9 mars 2017

Scala: Extracting annotation from singleton object via reflection

How can one access the annotation of a singleton object given a string?

I am using Scala version 2.11.6 and plan to upgrade to 2.12 after sorting this issue out.

Example

Given an (java) annotation

public @interface Marked {
  String name();
}

and a simplified factory interface

trait Instance { def doSomething(): Unit }
trait Factory { def create(): Instance }

I would like to check whether a dynamically loaded singleton object is annotated and with what value. The singleton object will be put in the classpath and may be defined as such:

class A extends Instance { override def doSomething() { println("A is done.") } }

@Marked(name = "My A Factory")
object AFactory extends Factory {
  override def create(): Instance = new A()
}

What I tried

I can only access the module (singleton object) dynamically and in this way fail to access the annotation. Mostly due to lack of comprehensive documentation I have tried the following expressions which all somehow return an empty list.

import scala.reflect.runtime.{universe => ru}
val name = "AFactory$" // This is automatically provided.
val rm = ru.runtimeMirror(getClass.getClassLoader)

val classSym = rm.staticClass(name)
println(classSym.annotations)
println(classSym.companion.annotations)
println(classSym.baseClasses(0).annotations)
println(classSym.baseClasses(0).companion.annotations)

val moduleSym = rm.staticModule(name)
println(moduleSym.companion.annotations)
println(moduleSym.asModule.annotations)
println(moduleSym.asModule.moduleClass.annotations)
println(moduleSym.asModule.moduleClass.companion.annotations)





Aucun commentaire:

Enregistrer un commentaire