I have a trait, named Init:
package test
trait Init {
def init(): Any
}
There are some classes and an object, extends this trait:
package test
object Config extends Init {
def init() = { loadFromFile(...) }
}
class InitDb extends Init {
def init() = { initdb() }
}
When app has started, I will find all classes and objects which extends Init, and invoke their init method.
package test
object App {
def main(args: Array[String]) {
val classNames: List[String] = findAllNamesOfSubclassOf[Init]
println(classNames) // -> List(test.Config$, test.InitDb)
classNames foreach { name =>
Class.forName(name).newInstance().asInstanceOf[Init].init() // ***
}
}
}
Please note the “*” line. For test.InitDb, it’s OK. But for test.Config$, when newInstance(), it throws an exception said we can’t access its private method.
My problem is, how to get that object, and run its init method?
There’s usually little point to doing this in Scala. Just put some code in the body of any
objectand it’ll be executed when that object is first initialised, saving you the nasty performance hit of pre-initialising everything.In general though, finding all subclasses of a particular type requires a full classpath scan. There are a few libraries to do this, but one of the more common is Apache’s commons-discover
However… This is dynamic code, it uses reflection, and it’s really NOT idiomatic. Scala has sharper tools than that, so please don’t try and swing the blunt ones with such violence!