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

Spark 3.3.0在EKS运行时抛出ClassCastException异常问题

Spark 3.3.0 日期类型转换ClassCastException问题

环境与问题

  • 运行环境:Spark 3.3.0、Scala 2.13.5
  • 异常表现:Scala代码在本地IntelliJ运行正常,部署到EKS执行时抛出:
    Exception in thread "main" java.lang.ClassCastException: java.time.LocalDate cannot be cast to java.sql.Date
    

代码片段

val listOfDates: List[Date] = 
  cgDatesDf
    .filter(cgDatesDf("cgDatecol") < lit(bs_date.toString).cast("Date"))
    .select(col("bs_date"))
    .collect
    .map(f => f.getDate(0))
    .toList
    .takeRight(1)

数据集信息

cgDatesDf内容:

+----------------+
|convertedDatecol|
+----------------+
|      2016-08-31|
|      2016-09-30|
|      2016-10-31|
|      2021-08-31|
|      2021-09-30|
|      2021-10-31|
|      2021-11-30|
|      2021-12-31|
|      2022-01-31|
|      2022-06-30|
+----------------+

其中bs_date值为2021-09-30

问题原因

Spark 3.x 默认采用Java 8的java.time.LocalDate作为DataFrame中Date类型的底层存储实现,但代码中使用的row.getDate(0)是旧API方法,它期望返回java.sql.Date类型,当底层实际存储的是LocalDate时,就会触发类型转换异常。

本地与EKS环境的差异可能源于Spark配置或依赖包的细微区别,导致日期类型的实际存储实现不一致。

解决方案

方案1:正确转换LocalDate为java.sql.Date

直接获取LocalDate类型后转为java.sql.Date,适配Spark 3.x的默认行为:

import java.sql.Date
import java.time.LocalDate
import org.apache.spark.sql.types.DateType

val listOfDates: List[Date] = 
  cgDatesDf
    .filter(col("cgDatecol") < lit(bs_date).cast(DateType)) // 直接使用DateType,避免字符串转换
    .select(col("bs_date"))
    .collect
    .map(row => Date.valueOf(row.getAs[LocalDate](0))) // 先获取LocalDate再转为sql.Date
    .toList
    .takeRight(1)

方案2:直接使用LocalDate类型

如果业务场景不需要java.sql.Date,可以直接改用LocalDate类型存储结果:

import java.time.LocalDate
import org.apache.spark.sql.types.DateType

val listOfDates: List[LocalDate] = 
  cgDatesDf
    .filter(col("cgDatecol") < lit(bs_date).cast(DateType))
    .select(col("bs_date"))
    .collect
    .map(_.getAs[LocalDate](0))
    .toList
    .takeRight(1)

方案3:调整Spark配置(不推荐)

强制Spark使用旧的日期类型实现,但会失去Java 8日期API的优势,仅作为临时兼容方案:
在SparkSession初始化时添加配置:

val spark = SparkSession.builder()
  .config("spark.sql.datetime.java8API.enabled", "false")
  .getOrCreate()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 12:05:19