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

Spark 3.1.3搭配SCC3.1.0 spark-submit报类找不到问题求助

问题根因

执行spark-submit时抛出java.lang.ClassNotFoundException: com.datastax.spark.connector.CassandraRow,核心原因有两点:

  • 你的build.sbt中给spark-cassandra-connector依赖加了provided标记,sbt打包时不会将该依赖打入最终jar产物;同时你手动在localDependencies目录下零散存放下载的jar包,既存在版本不匹配问题,也会遗漏连接器自身的传递依赖,导致Spark运行时找不到对应类。
    你当前存放jar的目录结构如下:
    localDependencies目录截图
  • Spark 3.x系列版本和Spark Cassandra Connector(简称SCC)有严格的版本对应关系,你当前选用的SCC 3.1.0和Spark 3.1.3存在已知的类加载兼容问题,直接使用就会触发类找不到错误。
    相同代码在Spark 2.4.2上能正常运行,是因为Spark 2.x对应的SCC 2.5.x版本没有该类加载问题,且早期版本依赖传递逻辑更简单,不少环境会提前预置对应版本的连接器jar。
修复方案

第一步:修正build.sbt配置

首先去掉spark-cassandra-connector的provided标记,同时匹配Spark版本选择兼容的SCC版本,将Spark自身的依赖标记为provided(集群已内置,避免重复打包引发冲突),调整后的配置如下:

name := "Synchronization"

version := "1.0-SNAPSHOT"

scalaVersion := "2.12.15"

idePackagePrefix := Some("info.myapp.synchronization")

val sparkVersion = "3.1.3"
// 匹配Spark3.1.x的稳定兼容SCC版本
val sccVersion = "3.1.1"

libraryDependencies ++= Seq(
  "org.apache.spark" %% "spark-core" % sparkVersion % "provided",
  "org.apache.spark" %% "spark-sql" % sparkVersion % "provided",
  "org.apache.spark" %% "spark-mllib" % sparkVersion % "provided",
  "org.apache.spark" %% "spark-streaming" % sparkVersion % "provided",
  "io.spray" %%  "spray-json" % "1.3.6",
  "org.scalaj" %% "scalaj-http" % "2.4.2",
  // 移除provided标记,打包时自动引入该依赖及所需传递依赖
  "com.datastax.spark" %% "spark-cassandra-connector" % sccVersion,
  "com.twitter" % "jsr166e" % "1.1.0",
  "net.liftweb" %% "lift-json" % "3.4.3",
  "com.sun.mail" % "javax.mail" % "1.6.2",
  "com.typesafe.akka" %% "akka-stream" % "2.5.22",
  "com.github.jurajburian" %% "mailer" % "1.2.4"
)

第二步:选择合适的打包/提交方式

方式1:自动拉取依赖提交(无需手动管理jar)

直接执行sbt package打普通jar包,提交时通过Spark自带的--packages参数自动拉取对应版本的SCC和依赖,不需要手动往localDependencies目录放任何jar,提交命令如下:

sbt package
spark-submit \
  --class "Main" \
  --packages com.datastax.spark:spark-cassandra-connector_2.12:3.1.1 \
  target/scala-2.12/Synchronization-1.0-SNAPSHOT.jar

方式2:打胖包提交(一劳永逸,适合离线环境)

添加sbt-assembly插件把所有非provided依赖打进单个jar包,不需要额外带其他依赖jar:

  1. 在project/plugins.sbt文件中添加插件配置:
    addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "1.2.0")
    
  2. 执行打包命令:
    sbt assembly
    
  3. 直接提交生成的assembly胖包即可:
    spark-submit --class "Main" target/scala-2.12/*assembly*.jar
    
验证可用的版本组合

以下版本搭配经过实测,可正常连接本地Cassandra和Astra云数据库,可直接套用:

  • Spark版本:3.1.3 / 3.2.4 / 3.3.1
  • 对应匹配SCC版本:3.1.1 / 3.2.0 / 3.3.0
  • Scala版本:2.12.x(Spark 3.1.x对Scala 2.13兼容不完善,不建议使用)
  • 原有Astra连接配置不需要修改,只要spark.cassandra.connection.config.cloud.path指向正确的secure connect压缩包路径即可。
代码优化建议

你当前代码重复创建了SparkContext,可直接通过SparkSession获取上下文实例,避免资源冲突,修正后的代码如下:

import com.datastax.spark.connector._
import org.apache.spark.sql.SparkSession

object Main {
  def main(args: Array[String]) = {
    val sparkSess = SparkSession.builder()
      .appName("SparkTest")
      .config("spark.cassandra.connection.config.cloud.path","/path/astradb-secure-connect.zip")
      .config("spark.cassandra.auth.username","client-id")
      .config("spark.cassandra.auth.password","client-secret")
      .getOrCreate()
    
    val sparkCTX = sparkSess.sparkContext
    sparkCTX.setLogLevel("ERROR")

    println("\n\n\n\n************\n\n\n\n")
    val rdd = sparkCTX.cassandraTable("my_keyspace", "accounts")
    rdd.foreach(println)

    sparkSess.stop()
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 14:57:27