我想做的事情并且一直在研究如何做多天是有一个母罐,透过一个文件夹并动态加载所有的罐子(不是真的需要知道它们)为此为了工作我需要一个名为plugin
的插件内的文件。我目前有一个工作类加载器,可以启动插件,但我无法读取plugin
文件。
这是我目前的代码:
Load.class
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);
答案 0 :(得分:4)
如果ClazzL
实际上是一个变量,并且引用了类加载器,那么只需尝试
ClazzL.getResourceAsStream("/menuplugin/plugin")
代替。如果您执行ClazzL.getClass().getClassLoader()
,则尝试从ClazzL
类的类加载器加载资源,而不是您创建的类加载器。
答案 1 :(得分: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的答案当然是一个更优雅的捷径。
答案 2 :(得分:2)
ClazzL.getClass().getClassLoader().getResourceAsStream("/menuplugin/plugin")
这不是从类加载器ClazzL
加载,而是从定义URLClassLoader的类加载器(即系统类加载器)加载。
尝试
ClazzL.getResourceAsStream("/menuplugin/plugin")