ServiceLoader.next导致NoClassDefFoundError [英] ServiceLoader.next causing a NoClassDefFoundError

查看:94
本文介绍了ServiceLoader.next导致NoClassDefFoundError的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我问是因为我完全确定自己​​做对了.我正在将Eclipse用于Web项目.我们将其称为com.web.project包中的WebProject(duh).

I'm asking because I'm totally not sure I've done the right thing. I'm using Eclipse for a web project. Let's call it WebProject (duh) in the package com.web.project.

我希望WebProject在运行时加载JAR插件,所以我认为我可以利用java.util.ServiceLoader的优势.因此,我在WebProject项目中创建了一个接口com.web.project.WebProjectPlugin,其中包含插件必须实现的所有方法.

I want WebProject to load JAR plugins at runtime, so I thought I could take advantage of java.util.ServiceLoader. So I created an interface com.web.project.WebProjectPlugin in the WebProject project with all the methods the plugins must implement.

然后我创建了项目PluginProject,在其Build路径中将WebProbject/build/classes添加为类文件夹:

Then I created the project PluginProject, adding WebProbject/build/classes in its Build path as a class folder:

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".

Then I created a META-INF/services folder in the plugin project, put the text file com.web.project.WebProjectPlugin inside, containing the sole line "com.web.project.plugin.TestPlugin".

我导出了JAR文件,签出添加的build/classes文件夹,并将其放在硬盘驱动器中的某个位置. WebProject启动时,它将执行以下操作:

I exported the JAR file checking out the added build/classes folder and put it somewhere in the hard drive. When WebProject starts up, it does the following:

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文件所在的目录.起初,由于iter不为空,似乎srvl可以完成其工作,但随后它会抛出可怕的NoClassDefFoundError到达iter.next()时.

pluginsDir is a File object pointing to the directory the JAR file is in. At first it seems that srvl does its job, since iter isn't empty, but then it throws the dreaded NoClassDefFoundError when it reaches iter.next().

我已经设法创建一个插件管理器项目来测试ServiceLoader,它运行正常,但是它是一个普通的控制台Java应用程序,而不是Web项目.那么,我在这里做错了什么?

I've already managed to create a plugin manager project to test ServiceLoader, and it runs just fine, but it's a plain console Java application, not a web project. So, what am I doing wrong here?

我有点困惑:它不是怎么找到com.web.project.WebProjectPlugin的类定义,因为它在同一项目中运行?与我正在使用的URLClassLoader对象有关吗?

I'm a little puzzled: how can it not find the class definition for com.web.project.WebProjectPlugin, since it's in the same project that is running? Has that something to do with the URLClassLoader object I'm using?

这是堆栈跟踪.

推荐答案

尝试将父类加载器分配给您的URLClassLoader

Try assigning the parent classloader to your URLClassLoader

URLClassLoader loader = new URLClassLoader(urls, Thread.currentThread().getContextClassLoader());

WebProject期望类加载器具有一定的层次结构,因此,如果父/子层次结构设置不正确,则您的类可能不会彼此可见.

A WebProject expects a certain hierarchy of class loaders, so it might be that your classes are not visible to each other if the parent/child hieararchy is not set properly.

这篇关于ServiceLoader.next导致NoClassDefFoundError的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆