ServiceLoader.next causing a NoClassDefFoundError
java, noclassdeffounderror, serviceloader
Solution
Try assigning the parent classloader to your `URLClassLoader`
URLClassLoader loader = new URLClassLoader(urls, Thread.currentThread().getContextClassLoader());
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.
Problem
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.