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

时间:2017-06-07 12:26:37

标签: java maven apache-spark classpath

我有一个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
  3. 因此,在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);
    } 
    

    在本地,这很好用。但是,当我构建一个胖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
    

1 个答案:

答案 0 :(得分:1)

我评论道:

  

最可能的解释是资源路径不正确。检查JAR文件以查看其中包含的内容以及实际路径。

除此之外:运行jar -tvf将为您提供JAR文件中所有资源的列表。

事实证明问题的根源。 (有时受过教育的猜测结果是正确的......)

你回答说:

  

谢谢,这几乎解决了问题(见编辑)。虽然它适用于火花,但现在本地部分已经破裂。知道如何使它适用于两者吗?

看看你发现了什么,以及你所说的话,我认为你找错了解决问题的方法。在我看来,你最初在你的代码中使用的路径是正确的:它是有道理的,它在本地案例中起作用。

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

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

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