我正在开发一个必须从文件夹动态加载.jar
个文件的项目。它从文件夹中获取以.jar
结尾的所有文件,然后打开它们。然后它获取jar文件中以.class
结尾的每个文件并加载它。然后我检查类是否使用以下代码扩展LeafPlugin
:
Class<?> clazz = classloader.loadClass(classname);
Object object = clazz.newInstance();
if(object instanceof LeafPlugin){
// Load LeafPlugin
}else{
System.out.println("Class '" + classname + "' isn't a LeafPlugin");
}
虽然这可以在eclipse中导出的DemoPlugin中正常工作,但是如果项目被导出,则该类不是LeafPlugin的消息会被打印出来。造成这种奇怪行为的原因是什么?
我在插件的构建路径中有这个项目,所以LeafPlugin不应该是不同的。
我尝试过使用LeafPlugin.class.isAssignableFrom(clazz)
,但它没有改变任何内容。如果导出它,可能会有什么不同于在eclipse中运行它来运行它?
可以找到整个代码here(这是非常多的,所以只需看一下LeafPluginLoader)
答案 0 :(得分:1)
问题在于您如何在LeafPluginLoader
中定义ClassLoader。你没有在你的问题中提供它的代码(它在你的GitHub上)。你有它
URLClassLoader cl = URLClassLoader.newInstance(urls);
问题是这个类加载器对你当前的LeafPlugin
类一无所知。您需要传递同时加载ClassLoader
类的LeafPlugin
实例。
URLClassLoader cl = URLClassLoader.newInstance(urls, LeafPlugin.class.getClassLoader());
现在我不知道类加载器的行为足以真正详细解释为什么会出现这种情况,但是简单地说你必须这样做,因为ClassLoaders有一个它知道的类的范围。如果加载它们的类加载器不知道LeafPlugin
类,那么在插件中加载时会出现问题。