【问题标题】:Apache Spark: Classloader cannot find classDef in the jarApache Spark:类加载器在 jar 中找不到 classDef
【发布时间】:2015-08-06 05:17:37
【问题描述】:

我正在 Apache Spark 中以本地模式运行一项作业,它将其结果保存到 s3a 文件系统。由于 Hadoop 2.6 没有 s3a:// 实现(或 s3://、s3n://)。我打包了一个包含 hadoop-aws 2.6.0 的所有传递依赖的 uber jar,并与我的主要工作的 jar 一起提交。

但是,当我使用以下简约代码对其进行测试时:

sc.parallelize(1 to 100).saveAsTextFile("s3a://***/test10/")

编译器在我第一次运行时给了我这个错误:

java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
    at com.amazonaws.auth.AWSCredentialsProviderChain.<clinit>(AWSCredentialsProviderChain.java:41)
    at org.apache.hadoop.fs.s3a.S3AFileSystem.initialize(S3AFileSystem.java:112)
    at org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:2596)
    at org.apache.hadoop.fs.FileSystem.access$200(FileSystem.java:91)
    at org.apache.hadoop.fs.FileSystem$Cache.getInternal(FileSystem.java:2630)
    at org.apache.hadoop.fs.FileSystem$Cache.get(FileSystem.java:2612)
    at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:370)
    at org.apache.hadoop.fs.Path.getFileSystem(Path.java:296)
    at org.apache.spark.SparkHadoopWriter$.createPathFromString(SparkHadoopWriter.scala:170)
    at org.apache.spark.rdd.PairRDDFunctions.saveAsHadoopFile(PairRDDFunctions.scala:953)
    at org.apache.spark.rdd.PairRDDFunctions.saveAsHadoopFile(PairRDDFunctions.scala:863)
    at org.apache.spark.rdd.RDD.saveAsTextFile(RDD.scala:1290)

如果我再次尝试运行,它会给我这个错误:

java.lang.NoClassDefFoundError: Could not initialize class com.amazonaws.auth.AWSCredentialsProviderChain
    at org.apache.hadoop.fs.s3a.S3AFileSystem.initialize(S3AFileSystem.java:112)
    at org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:2596)
    at org.apache.hadoop.fs.FileSystem.access$200(FileSystem.java:91)
    at org.apache.hadoop.fs.FileSystem$Cache.getInternal(FileSystem.java:2630)
    at org.apache.hadoop.fs.FileSystem$Cache.get(FileSystem.java:2612)
    at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:370)
    at org.apache.hadoop.fs.Path.getFileSystem(Path.java:296)
    at org.apache.spark.SparkHadoopWriter$.createPathFromString(SparkHadoopWriter.scala:170)
    at org.apache.spark.rdd.PairRDDFunctions.saveAsHadoopFile(PairRDDFunctions.scala:953)
    at org.apache.spark.rdd.PairRDDFunctions.saveAsHadoopFile(PairRDDFunctions.scala:863)
    at org.apache.spark.rdd.RDD.saveAsTextFile(RDD.scala:1290)

奇怪的是:LogFactory 和 AWSCredentialsProviderChain 都在我提到的 uber jar 中。我还检查了其他 jar,包括 worker 上的 spark 库和我的主要工作的 jar(已经部署到 spark/worker 目录),并且可以确认它们都没有具有相同名称的类。所以它不可能是一个 jar 地狱问题(此外,在这种情况下,抛出的错误应该是 Property/MethodNotFoundError)。您是否知道可能发生了什么以及如何解决?

【问题讨论】:

  • 您是否使用过jar分析器来验证depa?你能发布你的 build.sbt
  • 我手动打开所有 jar 以验证它们是否存在。构建文件见github.com/tribbloid/spookystuff/blob/improved-lookup/lib/…
  • @tribbloid 你解决了这个问题吗?我正在努力使用带有 Hadoop 2.6.0 的 Spark 1.5.0 尝试修改类路径、shadowjars 等,但它无济于事。

标签: java scala apache-spark classloader


【解决方案1】:

我之前遇到过类似的问题,我的解决方案是在运行 spark-submit 时将 uber jar 本身添加到 --driver-class-path。您的 uber-jar 不是由 JVM 直接执行的。相反,它由 Spark 的某种驱动程序包装器运行。将 uber jar 添加到驱动程序的类路径中似乎没有必要,但有时可以解决一些奇怪的 NoClassDefFoundError。我不确定它是否能解决您的问题,但值得一试。

【讨论】:

  • 非常感谢!我马上试试这个
  • 否,但稍微好一点:s3 和 s3n 适用于本地集群模式(或模拟模式),但在真实集群模式下会引发相同的 ClassNotFound 错误。
  • 在提交应用程序时尝试设置 spark.executor.userClassPathFirst=true,方法是在 spark-submit 命令中指定“--conf spark.executor.userClassPathFirst=true”
  • 非常感谢您的建议,在 spark 1.4.0 发布并且 S3 访问的错误仍然标记为“未解决”后,我有点放弃并恢复到 hadoop 2.4 .解决依赖管理中的版本冲突既不高效也不安全。更改覆盖顺序可能会引发其他一些问题,甚至更糟的是,会引发一个隐藏问题,该问题只有在部署到生产环境后才会迫在眉睫
  • 在 [SPARK-7442] 的修复发布后,让我们回到解决方案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-01
  • 2016-05-27
  • 2021-06-06
  • 1970-01-01
  • 2015-04-11
  • 1970-01-01
  • 2013-03-23
相关资源
最近更新 更多