我问是因为我完全不确定我做对了。我正在将 Eclipse 用于 Web 项目。我们称它为包中的 WebProject (duh) com.web.project
。
我希望 WebProject 在运行时加载 JAR 插件,所以我想我可以利用java.util.ServiceLoader
. 所以我com.web.project.WebProjectPlugin
在 WebProject 项目中创建了一个接口,其中包含插件必须实现的所有方法。
然后我创建了项目 PluginProject,在其构建路径中添加 WebProbject/build/classes 作为类文件夹:
package com.web.project.plugin;
import com.web.project.WebProjectPlugin;
public class TestPlugin implements WebProjectPlugin {
// Implementation of the interface methods...
}
然后我在插件项目中创建了一个 META-INF/services 文件夹,将文本文件com.web.project.WebProjectPlugin
放入其中,包含唯一的一行“com.web.project.plugin.TestPlugin”。
我导出了 JAR 文件,检查了添加的 build/classes 文件夹并将其放在硬盘驱动器的某个位置。当 WebProject 启动时,它会执行以下操作:
File[] jlist = pluginsDir.listFiles(new FileFilter() {
public boolean accept(File file) {
return file.getPath().toLowerCase().endsWith(".jar");
}
});
URL[] urls = new URL[jlist.length];
for (int i = 0; i < jlist.length; i++)
urls[i] = jlist[i].toURI().toURL();
URLClassLoader ucl = new URLClassLoader(urls);
ServiceLoader<WebProjectPlugin> srvl =
ServiceLoader.load(WebProjectPlugin.class, ucl);
Iterator<WebProjectPlugin> iter = srvl.iterator();
while (iter.hasNext()) {
WebProjectPlugin plugin = iter.next();
plugins.add(plugin);
}
pluginsDir
是一个File
指向 JAR 文件所在目录的对象。起初它似乎srvl
完成了它的工作,因为iter
它不是空的,但是NoClassDefFoundError
当它到达iter.next()
.
我已经设法创建了一个插件管理器项目来测试ServiceLoader
,它运行得很好,但它是一个普通的控制台 Java 应用程序,而不是一个 Web 项目。那么,我在这里做错了什么?
我有点困惑:它怎么找不到的类定义com.web.project.WebProjectPlugin
,因为它在同一个正在运行的项目中?这与URLClassLoader
我正在使用的对象有关吗?
这是堆栈跟踪。