动态添加 Jar 插件,但发出 NoClassDefFoundError

Adding Jar Plugins Dynamically, but issuing NoClassDefFoundError

我最近正在制作 PluginClassLoader 以动态加载 java 插件到我的程序。这样插件就可以和我的程序交互了。

然而,事情不会很顺利。于是查了一下bukkit加载插件的实现。 [Bukkit's source code]我跟着它,Java仍然给我一个NoClassDefFoundError

这是我的实现:

所有要添加的插件都扩展到com.mob41.sakura.plugin.Plugin。这个抽象class包含onCallPlugin()onEndPlugin()等主程序交互的函数。 [Abstract class source code]

所有插件都将放在工作目录 (System.getProperty("user.dir") + "\plugins") 的 /plugins 文件夹中。我的程序将在工作目录中找到文件夹 (/plugins)。如果它不存在,它会创建一个新文件夹。如果存在,它将找到所有 jar 个文件。并创建一个 PluginClassLoader [Source Code] 来添加插件。

我预计插件将被添加到我的程序中并且 classloader 将创建它们的实例。通过这个测试代码:

public static void main(String[] args) {
    System.out.println("Loading...");
    try {
        PluginManager.getPluginManager().loadAllPlugins();
    } catch (Exception e){
        e.printStackTrace();
        return;
    }
    System.out.println("Loaded.");
    JSONObject json = new JSONObject();
    json.put("ext", false);
    System.out.println((JSONObject) PluginManager.getPluginManager().runPluginLifeCycle("Sakura-Plugin-HKOWeather", json));
    }

如果插件invalid/causes加载时出错,这个exception会被抛出。 不知道为什么我的程序找不到自己扩展的插件...

com.mob41.sakura.plugin.exception.InvalidPluginException: java.lang.NoClassDefFoundError: com/mob41/sakura/plugin/Plugin
    at com.mob41.sakura.plugin.PluginManager.loadPlugin(PluginManager.java:180)
    at com.mob41.sakura.plugin.PluginManager.loadAllPlugins(PluginManager.java:145)
    at com.mob41.sakura.Main.main(Main.java:12)
Caused by: java.lang.NoClassDefFoundError: com/mob41/sakura/plugin/Plugin
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(Unknown Source)
    at java.security.SecureClassLoader.defineClass(Unknown Source)
    at java.net.URLClassLoader.defineClass(Unknown Source)
    at java.net.URLClassLoader.access0(Unknown Source)
    at java.net.URLClassLoader.run(Unknown Source)
    at java.net.URLClassLoader.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Unknown Source)
    at com.mob41.sakura.plugin.PluginClassLoader.<init>(PluginClassLoader.java:25)
    at com.mob41.sakura.plugin.PluginManager.loadPlugin(PluginManager.java:176)
    ... 2 more
Caused by: java.lang.ClassNotFoundException: com.mob41.sakura.plugin.Plugin
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    ... 17 more

经过几个小时的调试,我终于找到了答案。

我为 PluginClassLoader 的实现指定了错误的 ClassLoader