Context
I use scala 2.11.6 currently, possibly 2.11.7 in the future. Given compiled class files in the classpath, I want to do 2 things:
Find the name of any objects that implements a certain interface:
trait Service trait ServiceFactory { def create(): Service } ... package my.package object MyServiceFactory extends ServiceFactory { def create(): Service = new Service() }
Here the name would be something like
my.package.MyServiceFactory
as it implements theServiceFactory
trait.Given the fully qualified name of the object I want to get the reference to the object's instance.
val factory = getInstance[ServiceFactory]("my.package.MyServiceFactory") val service = factory.create()
Problem
The problem to both scenarios is verifying the type inheritance and making sure it is a singleton object.
Checking the class seems straight-forward but given all the documentation
I could understand, none helped me implementing something like isSingletonObject(name: String): Boolean
as used in:
import scala.reflect.runtime.{universe => ru}
val rm = ru.runtimeMirror(classLoader)
def getInstance[T](name: String)(implicit tt: ru.TypeTag[T]): T = {
if (!isSingletonObject(name)) throw new RuntimeException(
s"$name does not specify a singleton object")
val moduleSym = try rm.staticModule(name).asModule
if (!(moduleSym.moduleClass.asClass.selfType <:< tt.tpe))
throw new RuntimeException("Type of loaded module " + moduleSym.fullName
+ " does not satisfy subtype relationship with "
+ tt.tpe.typeSymbol.fullName)
val mm = rm.reflectModule(moduleSym.asModule)
mm.instance.asInstanceOf[T]
}
How can one find objects and verify that a given name is really an object? Alternative approaches to the given scenarios are also welcome.