【问题标题】:How should resources in a compiled jar be accessed?应该如何访问已编译 jar 中的资源?
【发布时间】:2012-07-14 19:30:12
【问题描述】:

首先,我已经阅读了很多 S.O.关于这个主题的问题,我已经尝试了其中建议的内容。

这是我的情况。我正在使用 Processing 框架编写一个 Java 应用程序,我正处于需要开始考虑打包应用程序的最后阶段。可以从命令行执行的 jar 文件是我尝试使用 Eclipse 中的导出功能构建的。

我的项目结构如下:

src/
   multiple packages/
libs/
   jar files and natives
data/
   fonts and images
config/
   json files

当我导出 jar 文件并解压缩 jar 以检查其内容时,我发现这些目录的内容已转储到 .jar 的顶层。

看起来像这样:

.jar
    packages
    jar files
    fonts
    json files

所以,当我尝试使用以下内容加载配置文件时:

BufferedReader reader = new BufferedReader( new FileReader( path ) );

当我在 Eclipse 中运行应用程序时,一切都只是文件。但是 jar 文件会抛出一个FileNotFoundException

我在 S.O. 上看到的许多问题。对于此类问题,建议使用class.getClass().getResource()class.getResourceAsStream()。我已经使用相对路径和文件名尝试了这两种方法:

class.getResource( 'config.json' );
class.getResources( 'cfg/config.json' );
class.getResourceAsStream( '../../config.json' );

当从 Eclipse 或 jar 使用以下方法运行时,所有这些方法都返回 null:

java -jar myjarfile.jar

我也愿意使用 Ant 文件。事实上,我现在正在使用导出功能生成的 Ant 文件来构建 jar。如果我可以添加一些东西来将目录添加到 jar 中,那也很棒。

【问题讨论】:

    标签: java eclipse jar processing embedded-resource


    【解决方案1】:

    要访问根目录中的资源,请在路径前添加 /。如果不是,则相对于当前包执行此操作,这通常仅在资源物理上也位于源中的类旁边时才有用。

    所以使用class.getResourceAsStream("/config.json"); 到达 jar 根目录中的 config.json。

    另请注意,不直接支持 jars-inside-jars。

    【讨论】:

    • 感谢您的回复。您是否建议我在 getResource() 之外使用正斜杠?
    • 这似乎更接近了。这是它返回的路径:jar:file:/C:/path_to_project/myjarfile.jar!/config.json 但是,当我运行 jar 时,即使路径正确,我仍然得到一个文件而不是异常。我还应该提到它确实可以在 Eclipse 中工作。
    • 您不能将 FileReaders 与 jar 内的资源一起使用。您必须使用从 getResourceAsSTream 返回的 InputStream。
    • 啊,太好了!我试试看。
    • 感谢您的帮助。我使用正斜杠和 InputStream 让它工作。
    【解决方案2】:

    您的 .jar 文件应该只包含与已编译代码的“包”相关的目录。您可能正在使用 /lib /WEB-INF 等引用 .war 结构,但这是不同的。

    如果你的包结构是:

     com.yourco.authentication
    

    还有你在登录中的班级

    那么你的罐子应该是

    /com/
      /yourco/
        /authentication/
            Login.class
    

    然后,您需要类路径中的 .jar 来让 env 通过命令行运行。

    我看到你注意到它在 Eclipse 中工作,它可能具有环境设置和导入所需的库等,因此很难准确判断。如果您的 packages/ 文件夹包含已编译的 java 代码,我不确定这在外部引用时是否有效,因此建议您在根文件夹中启动您的包。

    【讨论】:

    • 我看到了编辑代码以引用 / 的其他建议。未经测试,它可以工作,但看起来你正在尝试用你的目录结构打包一个应用程序而不是一个库。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-28
    • 2012-02-28
    • 2011-07-11
    • 2011-02-08
    • 2011-01-24
    • 2018-01-06
    相关资源
    最近更新 更多