繁体   English   中英

Java从动态外部jar读取文件

[英]Java reading files from dynamic external jar

我正在尝试做并且一直在研究如何做很多天的事情是有一个可以通过文件夹查看并动态加载其中所有罐子的母罐(实际上并不需要了解它们),这样我才能正常工作在插件中需要一个名为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);

如果ClazzL实际上是一个变量,并且引用了类加载器,则尝试

ClazzL.getResourceAsStream("/menuplugin/plugin")

代替。 如果执行ClazzL.getClass().getClassLoader() ,则尝试从ClazzL类的类加载器而不是已创建的类加载器加载资源。

使用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的答案当然是一个更为优雅的捷径。

ClazzL.getClass().getClassLoader().getResourceAsStream("/menuplugin/plugin")

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

尝试

ClazzL.getResourceAsStream("/menuplugin/plugin")

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM