我的应用程序设计有问题。我有基于插件的主应用程序(让我们称之为App)。 Everthing是用Java编写的。在App启动期间动态加载PLugins。在插件中加载App搜索特定的loaction(“/ plugins”目录),然后加载插件,这些插件被安装到jar文件中。
问题如下:当插件(打包到jar中)包含以*类文件编码的功能时 - everthing就可以了。但是当Plugin类使用任何资源(例如文本文件,图像)时 - 存在一个问题,因为在主应用程序(App)中运行此插件期间,我得到了异常:
java.io.FileNotFoundException: sampletxt (Nie można odnaleźć określonego pliku)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.<init>(FileInputStream.java:120)
at java.io.FileInputStream.<init>(FileInputStream.java:79)
at java.io.FileReader.<init>(FileReader.java:41)
我知道为什么会出现这个问题,但我不知道如何应对这个问题。插件类使用的资源始终存在于jar文件中。但问题是在主应用程序(App)中仅加载插件类引起的 - 我不加载资源(sampletxt),因为我对插件类可以使用的资源一无所知。
澄清这种情况:主应用程序有这样的东西:
class App {
public void any method() {
Class<PluginDataGenerator> plugin = jarClassLoader.loadClass("mypackage.plugin."+className, true);
PluginDataGenerator plg = plugin.newInstance();
plg.doAction();
}
}
所以在这段代码中我加载了给定名称(className)的插件。 现在,Plugin类可能有类似这样的代码:
class Plugin {
public void doAction() {
try {
BufferedReader reader = new BufferedReader(new FileReader(
"sampletxt"));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
现在,当调用doAction方法时,我得到了java.io.FileNotFoundException。 我想到的一个解决方案是在App目录结构中创建文件夹“resources”,并放置插件类可以使用的任何资源。但这不是一个好的解决方案,因为在这种情况下,插件(打包到jar)将独立于其资源分发。 我认为另一个想法是将任何条目放入jar中的Manifest文件中。此条目可以通知插件加载器应该加载哪个资源。但是从这个角度看插件代码:
BufferedReader reader = new BufferedReader(new FileReader(
"sampletxt"));
执行App将在App的主目录中搜索“sampletext”,而不是在内存中,所以在这种情况下我应该从jar复制资源并将其粘贴到App中的特定目录中吗?这似乎也是一个糟糕的解决方案。
我不知道如何设计我的App和插件。任何想法将不胜感激。
答案 0 :(得分:1)
请尝试使用Class.getResource或Class.getResourceAsStream。
E.g。
BufferedReader reader = new BufferedReader(
new InputStreamReader(Plugin.class.getResourceAsStream("sampletxt")));
其中Plugin
是插件类的名称。
答案 1 :(得分:0)
我遇到了类似的问题。在你的插件中,我会打电话:
File f = FileLocator.toFileUrl(getClass().getResource("/sampletext.txt")).getFile();