Search code examples
scalareflectionscala-2.10scala-2.11scala-reflect

How to instantiate a Scala object using reflection


I have some code that uses reflection to instantiate a Java or Scala class, allowing a user to specify the name: Assume that loadIt below is a hypothetical method defined using this approach.

def getInstance(name:String, jar:String) = {
   val c:Class[_] = loadIt(name, jar) // load class from the jar
   c.newInstance.asInstanceOf[AnyRef] // return new instance of the class
}

This works fine if name is a Scala class, but not if it is an object. Say I define an object:

object Foo

and call it as:

getInstance("Foo", "someJar.jar")

I get the error:

java.lang.InstantiationException: Foo
    at java.lang.Class.newInstance(Class.java:364)

Is there any way I can properly instantiate the object?


Solution

  • Found the answer:

    Refer to this link. Added the following code:

    import scala.reflect.runtime.universe._
    def getObjectInstance(clsName: String):AnyRef = {
      val mirror = runtimeMirror(getClass.getClassLoader)
      val module = mirror.staticModule(clsName)
      mirror.reflectModule(module).instance.asInstanceOf[AnyRef]
    }
    val c:Class[_] = loadIt("Foo", "someJar.jar") // ok 
    val o = try c.newInstance.asInstanceOf[AnyRef] catch {
        case i:java.lang.InstantiationException => getObjectInstance("Foo")
    }
    // works