2017-03-19 23 views
0

I以下のScalaのクラス階層があります。動的クラスローディング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... 

実行時に、私のアプリは、インスタンス化するBaseModuleサブクラスの完全修飾クラス名の文字列入力引数を受け入れますが、をコードはどの具体的なサブクラスになるのかわかりません。だから私は持っている:

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] 

にしたがって、この方法は、入力がクラスパス上を探すために、そしてその後、インスタンス化するためにどのBaseModuleサブクラスを指定します。上の最初の3行はうまく実行され、私はprintlnの火を見る。しかし、上記の最後の行は、例外をスロー:SimpleModuleサブクラスのインスタンスを作成しようとすると、明らか私が何か間違ったことをやっている

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> 

ので、ちょうどそれが何であるかを把握することはできません。何か案は?

+2

「InvocationTargetException' [wrapps](https://docs.oracle.com/javase/7/docs/api/java/lang/reflect/InvocationTargetException.html)の原因となる例外として、最初に 'getCause()'を呼び出します。 'appConfig'が呼び出し時に有効かどうかを確認してください。 –

+0

インスタンス化しているクラスのコンストラクタが例外をスローしている可能性があります。 –

+2

「newInstance」の[JavaDoc](https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Constructor.html#newInstance-java.lang.Object...-)から':' @throws InvocationTargetException - 基底のコンストラクタが例外をスローする場合 'あなたが与えたコードは問題ではなく、むしろオブジェクトの作成中に問題があります。さらに進歩を遂げるためには、問題のあるスタックトレースまたは実際のコードのすべてを私たちに与えるべきです。 – rxg

答えて

4

引数なしでnewInstance()を呼び出してもデフォルトのコンストラクタが見つからないため、おそらく失敗します。したがって、インスタンス化に失敗します。

はこれを試してください:

appConfAppConfigのインスタンスであるとして BaseModuleをインスタンス化するためのパラメータである
Class.forName(moduleFQCN).getConstructor(classOf[AppConfig]) 
.newInstance(appConf).asInstanceOf[BaseModule] 

+0

ありがとう@Alon Segal(+1)デフォルトのコンストラクタで何かをしていると思いますが、単純な文字列を使った例は私を助けません。他の複雑な要因は、コードが* BaseModuleのサブクラスを期待していることを知っていることですが、実行時まではそうではありません。あなたが私の 'BaseModule'ユースケースを使用するようにあなたの例を変更することができ、それが私のために働くなら、私はうれしくあなたに緑色のチェックを与えるでしょう!再度、感謝します! – smeeb

+1

編集が正常に機能しているか確認してください –

+0

もう一度お返事ありがとうございます。更新された質問/コードスニペットと新しい例外( 'InvocationTargetException')を見てください。思考?もう一度おねがいします*非常に*! – smeeb