将java插件加载到jar中包含的问题,包含资源

时间:2011-07-18 16:21:30

标签: java plugins resources jar

我的应用程序设计有问题。我有基于插件的主应用程序(让我们称之为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和插件。任何想法将不胜感激。

2 个答案:

答案 0 :(得分:1)

请尝试使用Class.getResourceClass.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();