getClass().getResource 上的 NullPointerException 不适用于 Apache Spark

NullPointerException on getClass().getResource not working for Apache Spark

我有一个maven项目,我正在使用一些写在文件中的资源。为了将它们添加到类路径中,在POM文件中我定义如下:

<build>
    <!-- custom resource folders -->
    <resources>
        <resource>
            <directory>${basedir}/src/main/resources</directory>
        </resource>
    </resources>
</build>

我使用的资源文件夹是:

  1. src/main/resources/A-resources
  2. src/main/resources/B-resources

因此,在 A-resourcesB-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);
} 

在本地,这工作正常。但是,当我为 运行 群集上 Spark 上的整个代码构建一个 fat jar 时,它会抛出 NullPointerException。

我怀疑,虽然它们是在类路径中构建的,但资源可能没有在 fat jar 中导出。我该如何解决这个问题?也许在 POM 文件中有一些额外的选项?

编辑:

当我检查 fat jar 时,我可以看到文件在那里:

...
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

我评论了:

The most likely explanation is that the resource path is incorrect. Check the JAR file to see what has been included in it, and what the actual path is.

旁白:运行 jar -tvf 将为您提供 JAR 文件中所有资源的列表。

事实证明,问题的根源。 (有时有根据的猜测结果是正确的......)

您回复了:

Thanks, this almost solved the problem (see edit). Although it works for spark, now the local part is broken. Any idea how to make it work for both?

看看您的发现,以及您所说的和您所做的,我认为您解决问题的方法是错误的。在我看来,您最初在代码中使用的路径是正确的:它有意义,并且在本地情况下有效。

我的诊断是您构建 JAR 文件的方式存在问题。看一下 POM 文件。

根据我在 "Specifying Resource Directories" 中阅读的内容,我认为您的 POM 文件应该有一个单独的 <resource>dir</resource> 用于每个资源目录。

如果这没有帮助,请查看与构建 JAR 文件的 Maven 相关的任何 POM 配置。