、私はこの方法で(.jarファイルに)外部のクラスをロード:スカラ - 動的オブジェクト/クラスローディングJavaでは
ClassLoader classLoader = new URLClassLoader(new URL[] {
new File("module.jar").toURI().toURL()});
Class clazz = classLoader.loadClass("my.class.name");
Object instance = clazz.newInstance();
//check and cast to an interface, then use it
if (instance instanceof MyInterface)
...
、それが正常に動作します。
====================
今私はScalaで同じことをしたいです。私はModule
という名前trait
(Module.scala
)を持っている:
trait Module {
def name: String
}
object Module {
lazy val ModuleClassName = "my.module.ExModule"
}
私はその後、module.jar
にそれをコンパイルし、Module
を拡張するモジュールを記述します。
package my.module
import Module
object ExModule extends Module {}
その後、私はこのコードでそれを読み込む:
var classLoader = new URLClassLoader(Array[URL](
new File("module.jar").toURI.toURL))
var clazz = classLoader.loadClass(Module.ModuleClassName)
正常に動作します。私は、新しいインスタンスを作成した場合でも、私はこの例外を取得:
java.lang.InstantiationException: my.module.ExModule
私はそれをテストする場合:
- >は常にfalse
を返します。
この問題で私を助けてくれますか?
編集
私はExModule
がobject
(ないclass
)であるので、それはあると思います。しかし、それをclass
に変更すると、classLoader.loadClass(...)
はjava.lang.NoClassDefFoundError
になります。 ExModule
がtrait
から拡張されているからだと思います。
私は混乱しています。誰でも私を助けてくれますか?
編集
clazz.isInstanceOf[Class[Module]]//or Class[Byte], or Class[_]...
true
戻ります。
私はあなたがClassNotFoundExceptionを取得していたときにそれをクラスにすることに近づいたと思います。 module.jarを参照したときにパスが正しく取得されていることを確認できますか?それが特性から拡張されているという事実は、何の違いもありません.ExModuleはクラスです(その場合)。 –
はい私は 'module.jar'へのパスが正しいと確信しています。メソッド 'classLoader.loadClass(...)'はうまく動作します( 'ExModule'が' object'の場合)。 –
(javapなどを介して)コンパイルされたバイトコードを見ることができますか? Scalacには$ sや他の奇妙な名前を追加するという面白い習慣があり、ExModuleはコンパイルされたバージョンでちょっと別の名前を持っているかもしれません。また、scalacにjavaコードを印字するようにscalacに依頼することもできます(私は今オプションを覚えていません)。 – Rogach