NoClassDefFoundError:org/apache/hadoop/fs/StreamCapabilities,同时用火花读取s3数据

Posted

技术标签:

【中文标题】NoClassDefFoundError:org/apache/hadoop/fs/StreamCapabilities,同时用火花读取s3数据【英文标题】:NoClassDefFoundError: org/apache/hadoop/fs/StreamCapabilities while reading s3 Data with spark 【发布时间】:2019-02-17 23:52:09 【问题描述】:

我想在本地开发机器(通过 Intellij)上运行一个简单的 spark 作业,从 Amazon s3 读取数据。

我的 build.sbt 文件:

scalaVersion := "2.11.12"

libraryDependencies ++= Seq(
  "org.apache.spark" %% "spark-core" % "2.3.1",
  "org.apache.spark" %% "spark-sql" % "2.3.1",
  "com.amazonaws" % "aws-java-sdk" % "1.11.407",
  "org.apache.hadoop" % "hadoop-aws" % "3.1.1"
)

我的代码 sn-p:

val spark = SparkSession
    .builder
    .appName("test")
    .master("local[2]")
    .getOrCreate()

  spark
    .sparkContext
    .hadoopConfiguration
    .set("fs.s3n.impl","org.apache.hadoop.fs.s3native.NativeS3FileSystem")

  val schema_p = ...

  val df = spark
    .read
    .schema(schema_p)
    .parquet("s3a:///...")

我得到以下异常:

Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/hadoop/fs/StreamCapabilities
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:348)
    at org.apache.hadoop.conf.Configuration.getClassByNameOrNull(Configuration.java:2093)
    at org.apache.hadoop.conf.Configuration.getClassByName(Configuration.java:2058)
    at org.apache.hadoop.conf.Configuration.getClass(Configuration.java:2152)
    at org.apache.hadoop.fs.FileSystem.getFileSystemClass(FileSystem.java:2580)
    at org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:2593)
    at org.apache.hadoop.fs.FileSystem.access$200(FileSystem.java:91)
    at org.apache.hadoop.fs.FileSystem$Cache.getInternal(FileSystem.java:2632)
    at org.apache.hadoop.fs.FileSystem$Cache.get(FileSystem.java:2614)
    at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:370)
    at org.apache.hadoop.fs.Path.getFileSystem(Path.java:296)
    at org.apache.spark.sql.execution.streaming.FileStreamSink$.hasMetadata(FileStreamSink.scala:45)
    at org.apache.spark.sql.execution.datasources.DataSource.resolveRelation(DataSource.scala:354)
    at org.apache.spark.sql.DataFrameReader.loadV1Source(DataFrameReader.scala:239)
    at org.apache.spark.sql.DataFrameReader.load(DataFrameReader.scala:227)
    at org.apache.spark.sql.DataFrameReader.parquet(DataFrameReader.scala:622)
    at org.apache.spark.sql.DataFrameReader.parquet(DataFrameReader.scala:606)
    at Test$.delayedEndpoint$Test$1(Test.scala:27)
    at Test$delayedInit$body.apply(Test.scala:4)
    at scala.Function0$class.apply$mcV$sp(Function0.scala:34)
    at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
    at scala.App$$anonfun$main$1.apply(App.scala:76)
    at scala.App$$anonfun$main$1.apply(App.scala:76)
    at scala.collection.immutable.List.foreach(List.scala:392)
    at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:35)
    at scala.App$class.main(App.scala:76)
    at Test$.main(Test.scala:4)
    at Test.main(Test.scala)
Caused by: java.lang.ClassNotFoundException: org.apache.hadoop.fs.StreamCapabilities
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 41 more

s3a:/// 替换为s3:/// 时出现另一个错误:No FileSystem for scheme: s3

由于我是 AWS 新手,我不知道我应该使用 s3:///s3a:/// 还是 s3n:///。我已经使用 aws-cli 设置了我的 AWS 凭证。

我的机器上没有安装任何 Spark。

提前感谢您的帮助

【问题讨论】:

【参考方案1】:

我会先看看the S3A troubleshooting docs

不要尝试“插入”比构建 Hadoop 版本的新版本的 AWS 开发工具包无论您遇到什么问题,更改 AWS 开发工具包版本都不会解决问题,只会更改您看到的堆栈跟踪。

无论您在本地 spark 安装中使用的是什么版本的 hadoop-JAR,您都需要完全使用相同版本的 hadoop-aws,以及完全相同版本的 aws SDK,其中 hadoop- aws 是用构建的。详情请尝试mvnrepository。

【讨论】:

@ogen 最后对你有用的正确设置是什么?我搜索了 Maven 存储库并正在使用 com.amazonaws:aws-java-sdk:1.11.217, org.apache.hadoop:hadoop-aws:3.1.1, org.apache.hadoop:hadoop-common:3.1.1,但是它不工作。 根据 Maven 的存储库,org.apache.hadoop:hadoop-aws:3.1.1 依赖于 com.amazonaws:aws-java-sdk:1.11.271 而不是 com.amazonaws:aws-java -sdk:1.11.217,我想你打错了。希望这能解决您的问题! 注意hadoop中的spark版本在依赖树的org.apache.hadoop依赖下,将hadoop-aws依赖设置为这个值。 这正是解决方案。如果您在本地系统中使用(通过 pip install 安装 pyspark),则在本地 pyspark 安装的 'jar' 文件夹下复制正确的 'hadoop-aws' 和 'aws-java-sdk-bundle' .jar 文件应该可以解决此问题.【参考方案2】:

对我来说,除了上述之外,它还通过在 pom.xml 中添加以下依赖项来解决:

<dependency>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-common</artifactId>
    <version>3.1.1</version>
</dependency>

【讨论】:

不确定,因为 Spark 不使用 Hadoop 3.1.1 jars【参考方案3】:

在我的情况下,我修复了它选择正确的依赖版本:

  "org.apache.spark" % "spark-core_2.11" % "2.4.0",
  "org.apache.spark" % "spark-sql_2.11" % "2.4.0",
  "org.apache.hadoop" % "hadoop-common" % "3.2.1",
  "org.apache.hadoop" % "hadoop-aws" % "3.2.1"

【讨论】:

以上是关于NoClassDefFoundError:org/apache/hadoop/fs/StreamCapabilities,同时用火花读取s3数据的主要内容,如果未能解决你的问题,请参考以下文章

java.lang.NoClassDefFoundError: org/hibernate/QueryTimeoutException

出现错误 java.lang.NoClassDefFoundError: org/mockito/MockitoAnnotations$Mock

错误 500 - NoClassDefFoundError: org/hsqldb/lib/LongValueHashMap

java.lang.NoClassDefFoundError:org/json/JSONObject [重复]

java.lang.NoClassDefFoundError: org/springframework/util/MultiValueMap

异常java.lang.NoClassDefFoundError: org/apache/curator/framework/CuratorFrameworkFactory