NoClassDefFoundError:在spark独立群集上部署后无法初始化XXX类

时间:2017-04-26 03:17:54

标签: scala apache-spark deployment spark-streaming spark-submit

我写了一个用sbt构建的火花流应用程序。它在本地工作得非常好,但是在集群上部署后,它会抱怨我在胖罐中写的一个类(使用jar tvf检查)。以下是我的项目结构。 XXX对象是引发抱怨的对象

src
`-- main
    `-- scala
        |-- packageName
        |   `-- XXX object
        `-- mainMethodEntryObject

我的提交命令:

$SPARK_HOME/bin/spark-submit \
  --class mainMethodEntryObject \
  --master REST_URL\
  --deploy-mode cluster \
  hdfs:///FAT_JAR_PRODUCED_BY_SBT_ASSEMBLY

特定错误消息:

java.lang.NoClassDefFoundError: Could not initialize class XXX

2 个答案:

答案 0 :(得分:1)

由于与此用户类似的原因,我遇到了此问题: http://apache-spark-developers-list.1001551.n3.nabble.com/java-lang-NoClassDefFoundError-is-this-a-bug-td18972.html

我在一个对象上调用了一个方法,该对象在对象本身上定义了一些变量,包括spark和logger,就像这样

val spark = SparkSession
  .builder()
  .getOrCreate()

val logger = LoggerFactory.getLogger(this.getClass.getName)

我正在调用的函数调用另一个函数,该函数调用另一个函数,该函数在rdd上的flatMap调用内调用另一个函数。

我在堆栈跟踪中得到NoClassDefFoundError错误,其中堆栈跟踪中的前两个函数调用是类Spark上的函数告诉我不存在。

基于上面链接的对话,我的假设是全局spark引用在被调用的函数被调用时被初始化(导致{{1例外)。

经过不少实验,我发现这种模式可以解决问题。

NoClassDefFoundError

它有点难看,但Spark似乎喜欢它。

答案 1 :(得分:0)

没有代码很难说,但它看起来像是XXX对象的序列化问题。我不能说我完全理解为什么,但重点是该对象不会被发送给执行者。

对我有用的解决方案是将对象转换为扩展Serializable的类,并在需要的地方实例化它。所以基本上,如果我没有错,你有

object test {
   def foo = ...
}

将在您的主页中用作test.foo,但您至少需要

class Test extends Serializable {
   def foo = ...
}

然后在你的主要开头有val test = new Test,那就是它。