如何让java ClassLoader知道可用的类?

时间:2017-05-03 04:05:21

标签: java plugins dependencies classloader dependency-management

我正在尝试为现有应用程序创建Java插件。插件希望在主应用程序中重用大量已有的代码库(例如日志记录,错误处理等)。

我正在尝试将插件加载为.jar这样的文件:

String localPath = "...";
String pluginName = "...";

File jarFile = new File(localPath);
ClassLoader pluginLoader = URLClassLoader.newInstance(new URL[]{jarFile.toURL()});

pluginLoader.loadClass(pluginName).newInstance();

我遇到的问题是我想在插件中导入的类无法找到,即使它们存在于主应用程序中,我也会遇到这样的错误:

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在代码中的任何地方都使用,但我不想在插件jar文件中包含此类(以及许多其他类)。相反,我希望ClassLoader以某种方式了解本地存在的类。这可能吗?如果是这样,我该怎么做?

1 个答案:

答案 0 :(得分:3)

您需要将主应用程序的类加载器用作父级:

ClassLoader mainLoader = ThisClass.class.getClassLoader(); // some class in the main application
ClassLoader pluginLoader = URLClassLoader.newInstance(new URL[]{jarFile.toURL()}, mainLoader);

然后插件类加载器加载的类将可以访问主类加载器加载的类(以及 类加载器的父类,如果它有一个,依此类推)。