【问题标题】:Spark unable to find "spark-version-info.properties" when run from ammonite script从 ammonite 脚本运行时,Spark 无法找到“spark-version-info.properties”
【发布时间】:2017-03-04 19:18:49
【问题描述】:

我有一个创建火花上下文的菊石脚本:

#!/usr/local/bin/amm

import ammonite.ops._

import $ivy.`org.apache.spark:spark-core_2.11:2.0.1`

import org.apache.spark.{SparkConf, SparkContext}

@main
def main(): Unit = {
  val sc =  new SparkContext(new SparkConf().setMaster("local[2]").setAppName("Demo"))
}

当我运行这个脚本时,它会抛出一个错误:

Exception in thread "main" java.lang.ExceptionInInitializerError
Caused by: org.apache.spark.SparkException: Error while locating file spark-version-info.properties
...
Caused by: java.lang.NullPointerException
    at java.util.Properties$LineReader.readLine(Properties.java:434)
    at java.util.Properties.load0(Properties.java:353)

脚本不是从 spark 安装目录运行的,也不知道它或打包此版本信息的资源 - 它只知道 ivy 依赖项。所以也许问题是这个资源信息不在常春藤依赖项的类路径上。我看过其他 spark“独立脚本”,所以我希望我能在这里做同样的事情。


我探查了一下,试图了解发生了什么。我希望我可以在运行时以编程方式将一些构建信息破解到系统属性中。

异常的来源来自spark库中的package.scala。相关的代码位是

val resourceStream = Thread.currentThread().getContextClassLoader.
  getResourceAsStream("spark-version-info.properties")

try {
  val unknownProp = "<unknown>"
  val props = new Properties()
  props.load(resourceStream) <--- causing a NPE?
  (
    props.getProperty("version", unknownProp),
    // Load some other properties
  )
} catch {
  case npe: NullPointerException =>
    throw new SparkException("Error while locating file spark-version-info.properties", npe)

似乎隐含的假设是,如果在资源中找不到版本信息,props.load 将失败并出现 NPE。 (这对读者来说不是很清楚!)

NPE 本身看起来像是来自java.util.Properties.java 中的这段代码:

class LineReader {
    public LineReader(InputStream inStream) {
        this.inStream = inStream;
        inByteBuf = new byte[8192];
    }

    ...
    InputStream inStream;
    Reader reader;

    int readLine() throws IOException {
      ...
      inLimit = (inStream==null)?reader.read(inCharBuf)
                                :inStream.read(inByteBuf);

LineReader 是用 null InputStream 构造的,该类在内部将其解释为意味着 reader 不为 null,应该使用它来代替 - 但它也是 null。 (这种东西真的在标准库里吗?看起来很不安全……)


从spark自带的bin/spark-shell看,它在启动时添加了-Dscala.usejavacp=truespark-submit。这是正确的方向吗?

感谢您的帮助!

【问题讨论】:

    标签: scala apache-spark ammonite


    【解决方案1】:

    以下似乎适用于 2.11 和 1.0.1 版本,但不是实验性的。

    可以在 Spark 2.2 上更好地实现

    #!/usr/local/bin/amm
    
    import ammonite.ops._
    import $ivy.`org.apache.spark:spark-core_2.11:2.2.0` 
    import $ivy.`org.apache.spark:spark-sql_2.11:2.2.0`
    import org.apache.spark.{SparkConf, SparkContext}
    import org.apache.spark.sql._ 
    import org.apache.spark.sql.SparkSession
    
    @main
    def main(): Unit = {
        val sc =  new SparkContext(new SparkConf().setMaster("local[2]").setAppName("Demo"))
    }
    

    或更多扩展答案:

    @main
    def main(): Unit = {
        val spark = SparkSession.builder()
          .appName("testings")
          .master("local")
          .config("configuration key", "configuration value")
          .getOrCreate 
      val sqlContext = spark.sqlContext
      val tdf2 = spark.read.option("delimiter", "|").option("header", true).csv("./tst.dat")
      tdf2.show()
    }
    

    【讨论】:

    • 感谢您的帮助。我运行了您的脚本,但遇到了可怕的问题:“NoSuchMethodError ...ArrayOps”,这通常是二进制兼容性问题。那是同时使用 scala 2.12.3 和 scala 2.11.8 以及 java 1.8.0_25 和 ammonite 1.0.1 (git.io/v7cx7)。你能列出你正在使用的工具的版本吗?我也尝试删除~/.ammonite/cache,但仍然出现同样的错误。
    • ~$ scala 欢迎使用 Scala 2.11.8(Java HotSpot(TM) 64 位服务器 VM,Java 1.8.0_144)。 ~$ amm Loading... 欢迎使用 Ammonite Repl 1.0.1 (Scala 2.11.11 Java 1.8.0_144) uname -r 4.4.0-91-generic Lubuntu 16.04 LTS 64 位。我会说核弹: $ rm -rf ~/.coursier/cache/v1/https/oss.sonatype.org/content/repositories/snapshots 如果这不起作用 $mv ~/.ivy2 ~/.ivy2.bak
    • 谢谢@quantt。我意识到由 SCALA_HOME 定义的 scala 版本并没有被 ammonite 使用,它实际上使用了自己的 scala 版本。我还意识到,即使是较旧的 ammonite 安装程序似乎也使用最新版本的 ammonite,但使用的是旧版本的 scala。当我使用 amm 版本 git.io/v5Tcm 时,脚本有效。我的输出是:“Welcome to the Ammonite Repl 1.0.2 (Scala 2.11.11 Java 1.8.0_25)”这实际上是我第一次尝试的更新的菊石,但使用的是旧的 scala。所以目前这是 scala 2.11 但不是 2.12 的解决方案。
    • :) 我的第一行:以下似乎适用于 2.11 和 1.0.1 版本,但不是实验性的。我应该说 scala 2.11
    猜你喜欢
    • 2017-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-15
    • 1970-01-01
    • 1970-01-01
    • 2016-10-26
    • 2021-01-04
    相关资源
    最近更新 更多