【问题标题】:Problem with loading java plugins packaged into jar, contained resources加载打包到 jar 中的 java 插件时出现问题,包含资源
【发布时间】:2011-10-07 20:07:54
【问题描述】:

我的应用程序设计有问题。我有基于插件的主应用程序(我们称之为应用程序)。一切都是用Java编写的。插件在 App 启动期间动态加载。在插件加载过程中 App 搜索特定位置(“/plugins”目录),然后加载插件,这些插件被打包成 jar 文件。

问题如下:当插件(打包到 jar 中)包含编码在 *class 文件中的功能时 - 一切正常。但是当 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 目录结构中创建文件夹“资源”,并在其中放置插件类可以使用的任何资源。但这不是一个好的解决方案,因为在这种情况下,插件(打包到 jar 中)将独立于其资源进行分发。 我认为的另一个想法是将任何条目放入 jar 中的 Manifest 文件。该条目可以通知插件加载器应该加载哪个资源。但是从这个时候插件代码来看:

 BufferedReader reader = new BufferedReader(new FileReader(
                "sampletxt"));

被执行的应用程序将在应用程序的主目录中搜索“sampletext”,而不是在内存中,所以在这种情况下,我应该从 jar 中复制资源并将其粘贴到应用程序的特定目录中吗?这似乎也是不好的解决方案。

我不知道如何设计我的应用程序和插件。任何想法将不胜感激。

【问题讨论】:

    标签: java plugins resources jar


    【解决方案1】:

    尝试改用Class.getResourceClass.getResourceAsStream

    例如

    BufferedReader reader = new BufferedReader(
            new InputStreamReader(Plugin.class.getResourceAsStream("sampletxt")));
    

    Plugin 是您的插件类的名称。

    【讨论】:

    • 不幸的是,这个解决方案不起作用:/ 执行插件代码时,我得到:java.lang.NullPointerException at java.io.Reader.&lt;init&gt;(Reader.java:61) at java.io.InputStreamReader.&lt;init&gt;(InputStreamReader.java:55) at net.sf.genedator.plugin.PluginWithResource.getName(PluginWithResource.java:35)
    • 看起来还是找不到文件。我唯一能想到的就是尝试"/sampletxt"(带有前导斜杠)。您能否更具体地了解该文件在插件的 .jar 中的位置?
    【解决方案2】:

    我刚刚遇到了类似的问题。在您的插件中,我会调用:

    File f = FileLocator.toFileUrl(getClass().getResource("/sampletext.txt")).getFile();
    

    【讨论】:

      猜你喜欢
      • 2010-10-09
      • 2022-10-01
      • 1970-01-01
      • 2013-07-07
      • 1970-01-01
      • 1970-01-01
      • 2013-09-23
      • 2014-08-26
      相关资源
      最近更新 更多