You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Apache Spark 3.1.2使用spark-hadoop-cloud无法读取S3问题咨询

问题根因

该报错是Guava版本冲突导致的:Apache Spark 3.1.x内置依赖的Guava版本为14.0/16.0,而Cloudera发行版的spark-hadoop-cloud、hadoop-aws组件依赖高版本Guava,高版本新增的com.google.common.base.Preconditions.checkArgument多参数重载方法在Spark内置的低版本Guava中不存在,类加载时优先加载了Spark自带的低版本Guava,就会抛出该方法不存在异常。

解决方案

不要使用Cloudera定制版本的spark-hadoop-cloud组件,原生Apache Spark 3.1.2可以通过官方标准依赖组合实现S3读写,无需额外引入第三方发行版组件,操作步骤如下:

  • 第一步:移除现有依赖中所有Cloudera来源的包,以及不必要的spark-hadoop-cloud依赖,调整sbt配置如下:
version := "0.0.1"

scalaVersion := "2.12.12"

lazy val app = (project in file("app")).settings(
    assemblyPackageScala / assembleArtifact := false,
    assembly / assemblyJarName := "uber.jar",
    assembly / mainClass := Some("com.example.Main"),
    // 核心:打包时排除Spark自带的低版本Guava,强制使用兼容版本的Guava
    assembly / assemblyExcludedJars := {
      val cp = (assembly / fullClasspath).value
      cp filter {_.data.getName.startsWith("guava-")}
    },
    // 解决冲突时优先使用高版本类
    assembly / assemblyMergeStrategy := {
      case PathList("META-INF", xs @ _*) => MergeStrategy.discard
      case x => MergeStrategy.first
    }
  )

libraryDependencies += "org.apache.spark" %% "spark-core" % "3.1.2" % "provided"
libraryDependencies += "org.apache.spark" %% "spark-sql" % "3.1.2" % "provided"
// 匹配Spark 3.1.2内置的Hadoop 3.2.0版本引入对应hadoop-aws
libraryDependencies += "org.apache.hadoop" % "hadoop-aws" % "3.2.0"
// 引入hadoop-aws 3.2.0匹配的aws-java-sdk-bundle版本
libraryDependencies += "com.amazonaws" % "aws-java-sdk-bundle" % "1.11.375"
// 引入和高版本Hadoop兼容的Guava,避免方法不存在
libraryDependencies += "com.google.guava" % "guava" % "27.0-jre"

libraryDependencies += "com.github.mrpowers" %% "spark-daria" % "0.38.2"
libraryDependencies += "com.github.mrpowers" %% "spark-fast-tests" % "0.21.3" % "test"
libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.1" % "test"
  • 第二步:调整Spark会话配置,添加S3A相关参数:
import org.apache.spark.sql.SparkSession

object SparkApp {
  def main(args: Array[String]){
    val spark = SparkSession.builder().master("local")
      .appName("spark session")
      // S3访问密钥配置,生产环境建议通过环境变量/IAM角色传递,避免硬编码
      .config("spark.hadoop.fs.s3a.access.key", "你的访问密钥AK")
      .config("spark.hadoop.fs.s3a.secret.key", "你的访问密钥SK")
      // S3A实现类配置
      .config("spark.hadoop.fs.s3a.impl", "org.apache.hadoop.fs.s3a.S3AFileSystem")
      // 路径风格访问开关,可根据你使用的S3服务配置调整
      .config("spark.hadoop.fs.s3a.path.style.access", "true")
      .getOrCreate

    val jsonDF = spark.read.json("s3a://path-to-bucket/compact.json")
    val csvDF = spark.read.format("csv").load("s3a://path-to-bucket/some.csv")
    jsonDF.show()
    csvDF.show()
  }
}
  • 第三步:如果是提交到Spark集群运行,作业提交时添加参数强制优先加载用户包中的类:
spark-submit \
  --conf spark.driver.userClassPathFirst=true \
  --conf spark.executor.userClassPathFirst=true \
  --class com.example.Main \
  uber.jar
验证

调整后重新打包运行,即可正常读写S3存储,不会再出现Guava方法不存在的异常。

内容的提问来源于stack exchange,提问作者discord

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 09:09:04