I am trying to create Java plugins for an existing application. The plugins would like to re-use a lot of the already existing code-base in the main application (e.g. logging, error handling, etc).
I am trying to load plugins as .jar files like this:
String localPath = "...";
String pluginName = "...";
File jarFile = new File(localPath);
ClassLoader pluginLoader = URLClassLoader.newInstance(new URL[]{jarFile.toURL()});
pluginLoader.loadClass(pluginName).newInstance();
The problem I am having is that the classes I would like to import inside the plugin can not be found, even though they exist in the main app, I am getting errors like this:
NoClassDefFoundError: com/foo/exception/FooException
at com.foo.plugins.PluginManager.loadPlugin(PluginManager.java:187)
at com.foo.plugins.PluginManager.loadPlugins(PluginManager.java:86)
...
com/foo/exception/FooException is used everywhere in the code, but I didn't want to have to include this class (and many many others) in the plugin jar file. Instead I would like the ClassLoader to somehow be aware of the locally existing classes. Is this possible? If so, how can I do it?
You need to use your main application's classloader as a parent:
ClassLoader mainLoader = ThisClass.class.getClassLoader(); // some class in the main application
ClassLoader pluginLoader = URLClassLoader.newInstance(new URL[]{jarFile.toURL()}, mainLoader);
Then classes loaded by the plugin classloader will have access to classes loaded by the main classloader (as well as that classloader's parent, if it has one, and so on).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With