sbt运行但是./spark-submit没有

时间:2016-11-23 10:29:43

标签: apache-spark sbt

我想使用sbt构建的lift-json解析器。我的built.sbt文件包含以下内容:

name := "MyProject"

version := "1.0"

scalaVersion := "2.10.0"
// https://mvnrepository.com/artifact/net.liftweb/lift-json_2.10
libraryDependencies += "net.liftweb" % "lift-json_2.10" % "3.0-M1"
val lift_json = "net.liftweb" %% "lift-json_2.10" % "3.0-M1"
//val json4sNative = "org.json4s" %% "json4s-native" % "3.3.0"
//libraryDependencies += "org.scala-lang" % "scala-library" % "2.9.1"
lazy val gitclonefile = "/root/githubdependencies/lift"
lazy val g = RootProject(file(gitclonefile))
lazy val root = project in file(".") dependsOn g

我的代码是:

package org.inno.parsertest
import net.liftweb.json._
//import org.json4s._
//import org.json4s.native.JsonMethods._
object parser {
   def main (args: Array[String]){
     val x = parse(""" { "numbers" : [1, 2, 3, 4] } """)
     println(x)
     val x1 = "jaimin is awesome"
     println(x1)
 }
}

sbt包然后sbt运行。但是当我想使用spark-submit运行它时,我收到以下错误:

Error: application failed with exception
java.lang.NoClassDefFoundError: net/liftweb/json/package$
    at org.inno.parsertest.parser$.main(jsonparser.scala:7)
    at org.inno.parsertest.parser.main(jsonparser.scala)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.apache.spark.deploy.SparkSubmit$.launch(SparkSubmit.scala:367)
    at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:77)
    at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)
Caused by: java.lang.ClassNotFoundException: net.liftweb.json.package$
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
    ... 9 more

如何让./spark-submit工作?

1 个答案:

答案 0 :(得分:3)

一旦火花驱动程序开始处理您的应用程序(当您提交它时),它就必须处理import net.liftweb.json._行,这意味着它将在其类路径中查找此类。

但是Spark没有搭载liftweb的jar,所以这是一个小姐,最后你得到ClassNotFoundException

因此,您需要为您的应用程序提供所需的罐子。有很多方法,详细讨论,这样做。

您可以从spark documentation开始。

  

捆绑应用程序的依赖性
  如果您的代码依赖于其他项目,则需要将它们与应用程序一起打包,以便将代码分发到Spark集群。为此,请创建包含代码及其依赖项的程序集jar(或“uber”jar)。 sbt和Maven都有汇编插件。在创建程序集jar时,将Spark和Hadoop列为提供的依赖项;这些不需要捆绑,因为它们是由集群管理器在运行时提供的。一旦你有了一个装配好的jar,你可以在传递jar时调用bin / spark-submit脚本,如图所示。

有人可能会建议:

  1. 将您的应用程序打包为通常称为“超级jar”或“胖罐”的应用程序,例如sbt's "assembly"插件或maven shade,具体取决于您的偏好。此策略将所有依赖项的所有类和资源合并到一个JAR中,即您提交的JAR。

  2. 为spark-submit调用添加参数。有几种方法,一种简单的方法是使用--jars参数,然后是您需要的(逗号分隔的)jar文件列表。在启动作业之前,这些罐子将通过spark添加到实际的驱动程序/工作者类路径

  3. 告诉spark-submit将“绑定”到maven存储库

      

    用户还可以通过使用--packages提供以逗号分隔的maven坐标列表来包含任何其他依赖项。使用此命令时将处理所有传递依赖项。可以使用标志--repositories以逗号分隔的方式添加其他存储库(或SBT中的解析程序)。

  4. 但是对所有选项的完整讨论是一个相当漫长的讨论,我建议你谷歌“包火花应用程序”或搜索StackOverflow与这些主题,以获得更好的概述。

    旁注:向Spark提交一个不使用SparkContext的应用程序似乎毫无意义,但我想你现在只是在试验。