如何让 java ClassLoader 知道可用 类?

How do I make the java ClassLoader aware of available classes?

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

我正在尝试将插件加载为 .jar 文件,如下所示:

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

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

pluginLoader.loadClass(pluginName).newInstance();

我遇到的问题是无法找到我想在插件中导入的 classes,尽管它们存在于主应用程序中,但我收到如下错误:

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 文件中包含这个 class(以及许多其他)。相反,我希望 ClassLoader 以某种方式知道本地存在的 classes。这可能吗?如果可以,我该怎么做?

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

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

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