如何访问编译成jar包的资源?

8
首先,我已经阅读了许多关于这个话题的S.O.问题,并尝试了其中建议的方法。
以下是我的情况。我正在使用Processing框架编写Java应用程序,现在进入最后阶段需要开始考虑如何打包该应用程序。我正试图使用Eclipse中的导出功能构建一个可从命令行执行的jar文件。
我的项目结构如下:
src/
   multiple packages/
libs/
   jar files and natives
data/
   fonts and images
config/
   json files

当我导出jar文件并解压缩以检查其内容时,我发现这些目录的内容已经被转储到.jar文件的顶层。
它看起来像这样:
.jar
    packages
    jar files
    fonts
    json files

因此,当我尝试加载配置文件时,例如:

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

当我在Eclipse中运行应用程序时,一切都正常。但jar文件会抛出FileNotFoundException异常。 我看到许多关于这些问题的问答,建议使用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包中,那就太好了。

2个回答

5
要访问根目录中的资源,请在路径前加上/。否则,您将相对于当前包进行操作,这通常仅在资源与类在源代码中相邻时才有用。
因此,请使用class.getResourceAsStream("/config.json");来访问jar根目录中的config.json。
还要注意,不支持嵌套的jar文件。

谢谢您的回复。您是建议我在使用getResource()时同时使用斜杠吗? - JeremyFromEarth
这似乎更接近了。这是返回的路径: jar:file:/C:/path_to_project/myjarfile.jar!/config.json 然而,当我运行jar文件时,虽然路径正确,但仍然会出现文件不存在的异常。我还应该提到它在Eclipse中可以正常工作。 - JeremyFromEarth
1
你不能使用FileReader读取JAR包内的资源。你必须使用从getResourceAsStream返回的InputStream。 - Thorbjørn Ravn Andersen
啊,太好了!我会试一下的。 - JeremyFromEarth
1
谢谢你的帮助。我使用正斜杠和InputStream使它工作了。 - JeremyFromEarth
好问题,好答案。另请参阅有关嵌入式资源的信息页面 - Andrew Thompson

2

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

如果您的包结构如下:

 com.yourco.authentication

你的登录类

然后你的jar文件应该是

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

然后您需要将.jar文件添加到类路径中,以便通过命令行运行环境。

我看到您注意到它在Eclipse中工作,这可能具有环境设置和导入所需的库等,因此很难确定。如果您的packages/文件夹包括编译的Java代码,则不确定在外部引用时是否会起作用,因此建议您从根文件夹开始启动您的packages。


我看到其他建议是编辑您的代码以引用“/”。虽然没有测试,但它似乎可以工作,但您的目录结构看起来像是在尝试打包应用程序而不是库。 - Mike S.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接