2017-05-12 21 views
1

我的Spark应用程序无法在AWS EMR群集上运行。我注意到这是因为某些类从EMR设置的路径加载而不是从我的应用程序jar加载。文件:例如为什么AWS上的Spark EMR不会从应用程序的胖jar加载类?

java.lang.NoSuchMethodError: org.apache.avro.Schema$Field.<init>(Ljava/lang/String;Lorg/apache/avro/Schema;Ljava/lang/String;Ljava/lang/Object;)V 
     at com.sksamuel.avro4s.SchemaFor$.fieldBuilder(SchemaFor.scala:424) 
     at com.sksamuel.avro4s.SchemaFor$.fieldBuilder(SchemaFor.scala:406) 

这里org.apache.avro.Schema“罐子装!/usr/lib/spark/jars/avro-1.7.7.jar /组织/apache/avro/Schema.class“

com.sksamuel.avro4s取决于avro 1.8.1。我的应用程序被构建为一个胖罐子,并具有avro 1.8.1。为什么没有加载?而不是从EMR设置类路径中选择1.7.7。

这只是一个例子。我看到与我的应用程序中包含的其他库相同。可能是Spark,取决于1.7.7,当包含其他依赖关系时,我必须加以遮蔽。但为什么包含在我的应用程序jar中的类未被首先加载?

回答

0

经过一番阅读,我意识到这是类加载如何在Spark中工作。有一个钩子来改变这种行为spark.executor.userClassPathFirst。当我尝试并将它标记为实验时,它并不奏效。我想最好的方法是遮蔽依赖关系。鉴于Spark和其组件的数量有所增加,这可能与Spark应用程序的复杂程度相当。

0

我和你有同样的例外。根据recommendation,我能够通过明暗的Avro公司的依赖,以解决这个异常如你所说:

assemblyShadeRules in assembly := Seq( ShadeRule.rename("org.apache.avro.**" -> "[email protected]").inAll )

如果有帮助,这是我的全build.sbt(项目信息除外):

val sparkVersion = "2.1.0" 
val confluentVersion = "3.2.1" 

resolvers += "Confluent" at "http://packages.confluent.io/maven" 

libraryDependencies ++= Seq(
    "org.scala-lang" % "scala-library" % scalaVersion.value % "provided", 
    "org.scala-lang" % "scala-reflect" % scalaVersion.value % "provided", 
    "org.apache.spark" %% "spark-streaming" % sparkVersion % "provided", 
    "org.apache.spark" % "spark-streaming-kafka-0-10_2.11" % sparkVersion, 
    "org.apache.spark" %% "spark-sql" % sparkVersion % "provided" excludeAll ExclusionRule(organization = "org.scala-lang"), 
    "org.apache.avro" % "avro" % "1.8.1" % "provided", 
    "com.databricks" %% "spark-avro" % "3.2.0", 
    "com.sksamuel.avro4s" %% "avro4s-core" % "1.6.4", 
    "io.confluent" % "kafka-avro-serializer" % confluentVersion 
) 

logBuffered in Test := false 

assemblyShadeRules in assembly := Seq(
    ShadeRule.rename("shapeless.**" -> "[email protected]").inAll, 
    ShadeRule.rename("org.apache.avro.**" -> "[email protected]").inAll 
) 

assemblyMergeStrategy in assembly := { 
    case PathList("META-INF", xs @ _*) => MergeStrategy.discard 
    case x => 
    val oldStrategy = (assemblyMergeStrategy in assembly).value 
    oldStrategy(x) 
} 
相关问题