I have been trying to do a kind of plugin-system using the ServiceLoader. There are 2 modules, the first provides the abstract class LoadedRealmPlugin. The second one extends this class. I have added the file corresponding to the full name of the ServiceProvider and added the service-class to it. IntelliJ does not find any errors (but when changing the filename or classname it does). Here is the structure:
MainModule
src
main
java
com.interestingcompany.mainmodule
LoadedRealmPlugin
MainModule.iml
Plugin
META-INF
services
com.interestingcompany.mainmodule (-> Content: "PluginExtension")
src
PluginExtension
Plugin.iml
(This is simplified, I left out classes that (I think) are not important to the ServiceLoader. I can post a screenshot of the actual structure if anyone needs it)
Here is the code I use to load the Service:
File file = new File("Plugins/Plugin.jar");
URLClassLoader c = new URLClassLoader(new URL[]{file.getAbsoluteFile().toURI().toURL()});
ServiceLoader<LoadedRealmPlugin> loader = ServiceLoader.load(LoadedRealmPlugin.class, c);
LoadedRealmPlugin p = loader.iterator().next(); // Throws a java.util.NoSuchElementException
p.Initialize(RealmPath); // Abstract method implemented in the service
return p;
When trying to run it, I always get an empty ServiceLoader. I looked at this post, but I was not quite sure about how to apply that answer since I am trying to load my plugin from a file. In addition, I found this post. Yet, there was no answer, just some comments that did not seem to have answered the question.
As you might have been able to tell, this is my first time working with classloaders. If there is any additional information needed, just ask me. Thank you for reading through my beginner troubles.
package-less classes are in the unnamed package, which is inaccessible to rather a lot of code, notably including here.
Put PluginExtension.java
in a package, make sure the content of your META-INF/services/com.ic.mainmodule
file reflects this (content should be pkg.PluginExtension
), and it'll work fine.