[英]When multiple versions of a class are made available by different class loaders, how can I reference a particular one?
[英]How can I use a Scala class as the shared root object across class loaders?
我在Scala中实现了一个自定义类加载器,该加载器用于将插件与主应用程序隔离。 目前,我需要一个Java接口作为共享根对象,以便我的主应用程序可以使用插件代码。
充当共享根的接口(我希望这是Scala):
public interface Handler {
public List<HandlerInfo> getHandlers();
}
示例插件:
class MyPlugin extends Handler {
def getHandlers: java.util.List[HandlerInfo] = // get some handlers
}
用途:
val jarFile = new File(System.getProperty("user.dir") + "/plugins/" + jarName)
val cl = new PluginLoader(jarFile, this.getClass.getClassLoader) // my custom classloader
val classToLoad = Class.forName(className, true, cl)
val handler = classToLoad.newInstance.asInstanceOf[Handler]
val handlers = handler.getHandlers
这很好用,但是我的问题是我必须保留这一Java类(以及生成的构建配置)。 我想改为使用Scala特性或抽象类,如下所示:
trait Handler {
def getHandlers : List[HandlerInfo]
}
然后我的插件可能如下所示:
class MyPlugin extends Handler {
def getHandlers: List[HandlerInfo] = // no more java.util.List
}
但是我不能这样做,因为这条线
val handler = classToLoad.newInstance.asInstanceOf[Handler]
抛出ClassCastException
,大概是因为Scala编译器不会生成一个干净的Java接口。 有什么办法解决这个问题,所以我可以有一个仅限Scala的项目?
问题不在您想像的地方。 它在您的类加载器中。 默认的类加载器可以正常工作,即使是Java也可以。 证据:
// File Handler.scala
trait Handler { def getHandlers: List[String] }
// File MyPlugin.scala
class MyPlugin extends Handler { def getHandlers = List("salmon", "cod") }
// File Interop.java
public class Interop {
public static void main(String[] args) {
try {
Class classToLoad = Class.forName("MyPlugin");
Handler handler = (Handler)classToLoad.newInstance();
System.out.println("Class loader = "+handler.getClass().getClassLoader());
System.out.println(handler.getHandlers());
}
catch (Exception e) { System.out.println("Uh-oh: "+e); }
}
}
在这里,我们运行它:
$ java -cp .:/usr/share/scala/2.10/lib/scala-library.jar Interop
Class loader = sun.misc.Launcher$AppClassLoader@1f3e8d89
List(salmon, cod)
$
Scala List
和所有内容,以及由默认Java类加载器加载的新类。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.