我有一个maven项目,我正在使用一些用文件编写的资源。为了将它们添加到类路径中,在POM文件中我将其定义如下:
<build>
<!-- custom resource folders -->
<resources>
<resource>
<directory>${basedir}/src/main/resources</directory>
</resource>
</resources>
</build>
我正在使用的资源文件夹是:
src/main/resources/A-resources
src/main/resources/B-resources
因此,在A-resources
和B-resources
文件夹中,我有一些文件,我想从中读取内容。我有以下代码从这些文件中读取一些选项:
try {
// Error appears on the next line ("InputStream in = ... ")
InputStream in = getClass().getResource("/A-resources/some_file.conf").openStream();
setOptions(in); // -> some function for reading options from files
in.close();
} catch (IOException e) {
// should not happen
throw new RuntimeException(e);
}
在本地,这很好用。但是,当我构建一个胖jar来在集群上运行Spark上的整个代码时,它会抛出一个NullPointerException。
我怀疑,虽然它们是在类路径中构建的,但资源可能不会在胖罐中导出。我该如何解决这个问题?也许在POM文件中有一些额外的选项?
修改
当我检查胖罐时,我可以看到文件在那里:
...
714 Wed Jun 07 11:14:58 CEST 2017 resources/A-resources/some_file.conf
...
如果我改变:
InputStream in = getClass().getResource("/A-resources/some_file.conf").openStream();
到
InputStream in = getClass().getResource("/resources/A-resources/some_file.conf").openStream();
它可以在Spark上运行(因此,通过更改代码中的所有内容来添加此/resources
作为前缀)。但是,随着这种变化 - 本地部分不起作用。我如何使这两者都有效,也就是说,而不是在脂肪瓶中:
resources/A-resources/some_file.conf
直接拥有它:
A-resources/some_file.conf
答案 0 :(得分:1)
我评论道:
最可能的解释是资源路径不正确。检查JAR文件以查看其中包含的内容以及实际路径。
除此之外:运行jar -tvf
将为您提供JAR文件中所有资源的列表。
事实证明是问题的根源。 (有时受过教育的猜测结果是正确的......)
你回答说:谢谢,这几乎解决了问题(见编辑)。虽然它适用于火花,但现在本地部分已经破裂。知道如何使它适用于两者吗?
看看你发现了什么,以及你所说的话,我认为你找错了解决问题的方法。在我看来,你最初在你的代码中使用的路径是正确的:它是有道理的,它在本地案例中起作用。
我的诊断可能是您构建JAR文件的方式存在问题。看看POM文件。
根据我在"Specifying Resource Directories"中的内容,我认为您的POM文件应该为每个资源目录单独<resource>dir</resource>
。
如果这没有帮助,请查看与构建JAR文件的Maven相关的任何POM配置。