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

使用Scala Spark Encoders.product[X]遇“No TypeTag available for X”错误求助

解决Scala 3中Spark Encoders.product报错"No TypeTag available for classa"的问题

我在IntelliJ IDEA的Scala工作表中,尝试为Scala样例类classa创建编码器,参考资料使用Encoders.product[classa],但始终报错“No TypeTag available for classa”。以下是相关代码、报错信息及build.sbt配置:

代码示例

import org.apache.spark.sql.*

val spark: SparkSession =
    SparkSession
      .builder()
      .appName("test")
      .master("local")
      .getOrCreate()

import scala3encoders.given

case class classa(i: Int, j: Int, s: String)

val enc = Encoders.product[classa]

报错信息

-- Error: ----------------------------------------------------------------------
1 |val enc = Encoders.product[classa]
  |                                  ^
  |                                  No TypeTag available for classa
1 error found

build.sbt配置

scalaVersion := "3.1.3"
scalacOptions ++= Seq("-language:implicitConversions", "-deprecation")
libraryDependencies ++= Seq(
  excludes(("org.apache.spark" %% "spark-core" % "3.2.0").cross(CrossVersion.for3Use2_13)),
  excludes(("org.apache.spark" %% "spark-sql" % "3.2.0").cross(CrossVersion.for3Use2_13)),
  excludes("io.github.vincenzobaz" %% "spark-scala3" % "0.1.3"),
  "org.scalameta" %% "munit" % "0.7.26" % Test
)

//netty-all replaces all these excludes
def excludes(m: ModuleID): ModuleID =
  m.exclude("io.netty", "netty-common").
    exclude("io.netty", "netty-handler").
    exclude("io.netty", "netty-transport").
    exclude("io.netty", "netty-buffer").
    exclude("io.netty", "netty-codec").
    exclude("io.netty", "netty-resolver").
    exclude("io.netty", "netty-transport-native-epoll").
    exclude("io.netty", "netty-transport-native-unix-common").
    exclude("javax.xml.bind", "jaxb-api").
    exclude("jakarta.xml.bind", "jaxb-api").
    exclude("javax.activation", "activation").
    exclude("jakarta.annotation", "jakarta.annotation-api").
    exclude("javax.annotation", "javax.annotation-api")

// Without forking, ctrl-c doesn't actually fully stop Spark
run / fork := true
Test / fork := true

解决方案

核心原因

Scala 3的元编程机制和Scala 2差异较大,Encoders.product是为Scala 2设计的API,依赖Scala 2的TypeTag机制,而Scala 3中需要使用spark-scala3库提供的适配方案,不能直接沿用Scala 2的调用方式。

具体修改步骤

  1. 替换编码器创建方式
    不需要手动调用Encoders.product,可以通过两种方式获取编码器:

    • 利用spark-scala3提供的隐式编码器,直接使用summon获取:
      val enc = summon[Encoder[classa]]
      
    • 或者使用Spark会话的隐式工具类:
      import spark.implicits.*
      val enc = implicitly[Encoder[classa]]
      

    实际开发中,大多数场景不需要显式创建编码器,直接调用toDF()等方法时,隐式编码器会自动生效:

    val data = Seq(classa(1, 2, "test1"), classa(3, 4, "test2"))
    val df = data.toDF() // 隐式编码器自动生效
    
  2. 调整代码结构
    将样例类classa的定义移到工作表的最顶部,或者单独的源文件中,避免IntelliJ工作表的类加载顺序问题导致隐式无法解析:

    import org.apache.spark.sql.*
    
    case class classa(i: Int, j: Int, s: String)
    
    val spark: SparkSession =
        SparkSession
          .builder()
          .appName("test")
          .master("local")
          .getOrCreate()
    
    import scala3encoders.given
    import spark.implicits.*
    
    val enc = summon[Encoder[classa]]
    
  3. 验证依赖配置
    你的build.sbt中已经正确引入了spark-scala3依赖,版本0.1.3和Spark 3.2.0、Scala 3.1.3兼容,无需修改。如果后续升级版本,注意保持三者的兼容性。

  4. 工作表运行注意事项
    IntelliJ的Scala工作表有时会存在隐式解析延迟,建议先执行Build Project编译整个项目,再运行工作表;如果问题仍存在,可以尝试重启IDE或者切换到普通Scala对象运行测试代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 18:40:49