动态类加载 Scala 类型

sme*_*eeb 1 scala classloader

我有以下 Scala 类层次结构:

abstract class BaseModule(val appConf : AppConfig) {
  // ...
}

class SimpleModule(appConf : AppConfig) extends BaseModule(appConf) {
  // ...
}

class FairlyComplexModule(appConf : AppConfig) extends BaseModule(appConf) {
  // ...
}

// dozens of other BaseModule subclasses...
Run Code Online (Sandbox Code Playgroud)

在运行时,我的应用程序将接受BaseModule要实例化的子类的完全限定类名的 String 输入参数,但代码不知道它将是哪个具体子类。所以我有:

val moduleFQCN = loadFromInputArgs()  // ex: "com.example.myapp.SimpleModule"
val moduleClass = Class.forName(moduleFQCN)
println(s"Found ${moduleFQCN} on the runtime classpath.")
val module = Class.forName(moduleFQCN).getConstructor(classOf[AppConfig]).newInstance(appConf).asInstanceOf[BaseModule]
Run Code Online (Sandbox Code Playgroud)

因此,通过这种方式,输入指定BaseModule要在类路径上查找的子类,然后再进行实例化。上面的前三行执行得很好,我看到了println火。但是上面的最后一行抛出了一个异常:

Exception in thread "main" java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    <rest of stacktrace omitted for brevity>
Run Code Online (Sandbox Code Playgroud)

明显,我在尝试创建SimpleModule子类的实例时做错了什么,只是无法弄清楚它是什么。有任何想法吗?

Alo*_*gal 5

您可能会失败,因为您在newInstance()没有任何参数的情况下调用,但未找到默认构造函数,因此实例化失败。

尝试这个:

Class.forName(moduleFQCN).getConstructor(classOf[AppConfig])
.newInstance(appConf).asInstanceOf[BaseModule]
Run Code Online (Sandbox Code Playgroud)

其中appConf是 的实例,AppConfig是要实例化的参数BaseModule