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
.
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.
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...
}
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".
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
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()
.
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?
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?
This is the stack trace.
Thread.currentThread().getContextClassLoader()
, but you know what? It runs just fine! Thanks! – Herringbone