我用Java写了一个Spark作业。作业被打包为一个带阴影的罐子并执行:
spark-submit my-jar.jar
在代码中,有一些文件(Freemarker模板)位于src/main/resources/templates
中。当在本地运行时,我可以访问文件:
File[] files = new File("src/main/resources/templates/").listFiles();
当作业在集群上运行时,执行前一行时会返回空指针异常。
如果我运行jar tf my-jar.jar
,我可以看到文件打包在templates/
文件夹中:
[...]
templates/
templates/my_template.ftl
[...]
我就是看不懂;我怀疑.listFiles()
试图访问集群节点上的本地文件系统,但文件不在那里。
我很想知道我应该如何打包要在自包含的Spark作业中使用的文件。我宁愿不在工作之外将它们复制到HDFS,因为维护起来会很麻烦。
您现有的代码将它们引用为未打包并发送到Spark节点的文件。但是,由于它们在您的jar文件中,您应该能够通过Foo.getClass().getResourceAsStream("/templates/my_template_ftl")
引用它们。有关Java资源流的更多信息,请点击此处:http://www.javaworld.com/article/2077352/java-se/smartly-load-your-properties.html
在Spark上运行Scala(2.11)代码似乎不支持访问着色jar中的资源。
执行此代码:
var path = getClass.getResource(fileName)
println("#### Resource: " + path.getPath())
在Spark之外运行时打印所需的字符串。
在Spark内部运行时,由于路径为null,将引发java.lang.NullPointerException
。
我已经访问了spark-scala中的资源文件,如下所示。我已经分享了我的代码,请检查。
val fs=this.getClass().getClassLoader().getResourceAsStream("smoke_test/loadhadoop.txt")
val dataString=scala.io.Source.fromInputStream(fs).mkString