Scala - 动态对象/类加载
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8867766/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Scala - Dynamic object/class loading
提问by
In Java, I load external class (in .jar file) by this way:
在 Java 中,我通过这种方式加载外部类(在 .jar 文件中):
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)
...
And it works fine.
它工作正常。
====================
====================
Now I want to do the same thing in Scala. I have a traitnamed Module(Module.scala):
现在我想在 Scala 中做同样的事情。我有一个trait名为Module( Module.scala):
trait Module {
def name: String
}
object Module {
lazy val ModuleClassName = "my.module.ExModule"
}
I write a module extending Module, then compile it to module.jar:
我编写了一个扩展模块Module,然后将其编译为module.jar:
package my.module
import Module
object ExModule extends Module {}
Then I load it by this code:
然后我通过这个代码加载它:
var classLoader = new URLClassLoader(Array[URL](
new File("module.jar").toURI.toURL))
var clazz = classLoader.loadClass(Module.ModuleClassName)
It works fine. But if I create new instance, I get this exception:
它工作正常。但是,如果我创建新实例,则会出现此异常:
java.lang.InstantiationException: my.module.ExModule
If I test it:
如果我测试它:
clazz.isInstanceOf[Module]
-> always return false.
-> 总是返回false。
So could you help me on this problem?
那么你能帮我解决这个问题吗?
Edited
已编辑
I guess it is because ExModuleis an object(not class). But when I change it to class, and classLoader.loadClass(...)raises a java.lang.NoClassDefFoundError. I guess it is because ExModuleis extended from a trait.
我想这是因为ExModule是object(不是class)。但是当我将其更改为class, 并classLoader.loadClass(...)引发java.lang.NoClassDefFoundError. 我想这是因为它是ExModule从trait.
I'm confused. Could anyone please help me?
我糊涂了。有人可以帮我吗?
Edited
已编辑
clazz.isInstanceOf[Class[Module]]//or Class[Byte], or Class[_]...
returns true.
返回true。
采纳答案by
Oops... I got the answer.
哎呀...我得到了答案。
Learn from:
借鉴:
https://stackoverflow.com/a/8868537/942821(thanks Neil again).
====================
====================
I guess this way is temporary before Scala team provides right way to load an object/class/trait... from external jar file. Or because I can't find out the right way. But currently this helps me out of the problem.
我想这种方式在 Scala 团队提供object/class/trait从外部 jar 文件加载... 的正确方法之前是暂时的。或者因为我找不到正确的方法。但目前这可以帮助我解决问题。
var classLoader = new java.net.URLClassLoader(
Array(new File("module.jar").toURI.toURL),
/*
* need to specify parent, so we have all class instances
* in current context
*/
this.getClass.getClassLoader)
/*
* please note that the suffix "$" is for Scala "object",
* it's a trick
*/
var clazzExModule = classLoader.loadClass(Module.ModuleClassName + "$")
/*
* currently, I don't know how to check if clazzExModule is instance of
* Class[Module], because clazzExModule.isInstanceOf[Class[_]] always
* returns true,
* so I use try/catch
*/
try {
//"MODULE$" is a trick, and I'm not sure about "get(null)"
var module = clazzExModule.getField("MODULE$").get(null).asInstanceOf[Module]
} catch {
case e: java.lang.ClassCastException =>
printf(" - %s is not Module\n", clazzExModule)
}
That's all :-)
就这样 :-)
Edited
已编辑
I'd better design ExModuleas a class. After loading it from jar file, I can check it as like as:
我最好把设计ExModule当成一个班级。从 jar 文件加载后,我可以像这样检查它:
var clazz = classLoader.loadClass(Module.ModuleClassName)
if (classOf[Module].isAssignableFrom(clazz))
...
Note:
笔记:
You can not do it the opposite way:
你不能以相反的方式做到这一点:
if (clazz.isAssignableFrom(classOf[Module]))
because Moduleis a trait/object, isAssignableFrom()will not work in this case.
因为Module是trait/ object,isAssignableFrom()在这种情况下不起作用。
回答by Chris Shain
Have you seen this article? http://kneissl.eu/Members/martin/blog/reflection-from-scala-heaven-and-hell
你看过这篇文章吗? http://kneissl.eu/Members/martin/blog/reflection-from-scala-heaven-and-hell
Got it from Need to load a scala class at runtime from a jar and initialize it
Also (and maybe more relevant): http://coffeetimecode.wordpress.com/2010/07/24/remote-and-dynamic-class-loading-in-scala/
另外(也许更相关):http: //coffeetimecode.wordpress.com/2010/07/24/remote-and-dynamic-class-loading-in-scala/

