1

我正在尝试做并且一直在研究如何做很多天是有一个母罐子,它可以通过一个文件夹查看并动态加载所有罐子(不需要知道它们),这样我才能工作插件内需要一个名为plugin. 我目前有一个可以启动插件的工作类加载器,但我无法读取plugin文件。

这是我当前的代码:

加载类

Load(JMenuBar Bar) {

ClassLoader currentThreadClassLoader = Thread.currentThread().getContextClassLoader();
        ClazzL = new URLClassLoader(new URL[]{new File("/home/grant/plugins/MenuPlugin.jar").toURL()}, currentThreadClassLoader);
        Thread.currentThread().setContextClassLoader(ClazzL);

        in = new BufferedReader(new InputStreamReader(ClazzL.getClass().getClassLoader().getResourceAsStream("/menuplugin/plugin")));

        System.out.println("in: " + in.readLine());


        Class c = ClazzL.loadClass("menuplugin.Main");//this works and loads properly
                                                      //it is just that it needs to
                                                      //load from `plugin` using
                                                      //in.readLine();
        API obj = (API) c.newInstance();
        obj.run(Bar);

}

错误是(第 44 行:in = new Buffered....)

Exception in thread "main" java.lang.NullPointerException
at menuaddon.Load.<init>(Load.java:42)
at menuaddon.Menuaddon.main(Menuaddon.java:39)
Java Result: 1

非常感谢您的帮助

完成的工作代码是:

ClassLoader currentThreadClassLoader = Thread.currentThread().getContextClassLoader();
        ClazzL = new URLClassLoader(new URL[]{new File("/home/grant/plugins/MenuPlugin.jar").toURL()}, currentThreadClassLoader);
        Thread.currentThread().setContextClassLoader(ClazzL);
        in = new BufferedReader(new InputStreamReader(ClazzL.getResourceAsStream("plugin")));
        classpath = in.readLine();
        Class c = ClazzL.loadClass(classpath);
        API obj = (API) c.newInstance();
        obj.run(Bar);
4

3 回答 3

4

如果ClazzL实际上是一个变量,并且引用了类加载器,那么就试试吧

ClazzL.getResourceAsStream("/menuplugin/plugin")

反而。如果你这样做ClazzL.getClass().getClassLoader()了,你试图从你的类的类加载器加载资源ClazzL,而不是你创建的类加载器。

于 2013-05-07T10:22:58.367 回答
2

使用getResource()获取插件文件的 URL ,然后在其上打开输入流。

编辑:您必须使用您使用创建的 URL 类加载器加载的类来执行此操作——而不是原始示例中的类加载器的类加载器——它只看到父类加载器的类路径,而不是你刚刚创建的类路径。

此代码应该可以工作:

Class c = ClazzL.loadClass("menuplugin.Main");
URL pluginFileUrl = c.getResource("/menuplugin/plugin"); // This returns an URL representing resource on the classpath with a given file name.
InputStream inputStream = pluginFileUrl.openStream();

编辑 2: NilsH 的答案当然是一个更优雅的捷径。

于 2013-05-07T10:19:21.227 回答
2
ClazzL.getClass().getClassLoader().getResourceAsStream("/menuplugin/plugin")

那不是从类加载器加载ClazzL,而是从定义 URLClassLoader 的类加载器(即系统类加载器)加载。

尝试

ClazzL.getResourceAsStream("/menuplugin/plugin")
于 2013-05-07T10:22:21.230 回答