我正在研究一个必须从文件夹动态加载.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

最佳答案

问题在于您如何在LeafPluginLoader中定义ClassLoader。您没有在问题中提供代码(在GitHub上)。你有

URLClassLoader cl = URLClassLoader.newInstance(urls);


问题是此类加载器对您当前的LeafPlugin类一无所知。您需要传递同时加载ClassLoader类的LeafPlugin实例。

URLClassLoader cl = URLClassLoader.newInstance(urls, LeafPlugin.class.getClassLoader());



现在,我对类加载器的行为还不够了解,无法真正详细地解释为什么是这种情况,但是简单地说,您必须这样做,因为类加载器具有它所知道的类范围。在加载插件时,如果加载它们的类加载器不了解LeafPlugin类,那么您将遇到问题。

关于java - 如果项目是从Eclipse运行的,那么Instanceof可以工作,但是导出时不能运行,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38540853/

10-09 07:29