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

Akka EventSourced Actor序列化报错:无法实例化内部类State

问题:Jackson序列化Typed EventSourced Actor状态时出错

在尝试持久化事件并更新Actor状态时,抛出如下异常:

Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `module.MyActor$State`: non-static inner classes like this can only by instantiated using default, no-argument constructor

相关Actor代码如下:

object MyActor {

  final case class Settings(
      name: String = "",
      accessToken: AccessToken = AccessToken()      

     ) extends CborSerializable
     .
     .
     .
}

class MyActor()(implicit system: ActorSystem[_]) {
  import MyActor._

  private implicit val executionContext: ExecutionContextExecutor = system.executionContext
  private val sharding = ClusterSharding(system)

  // State
  final case class State(
      settings: Settings = Settings(),
      pollTime: Long = 0L
  ) extends CborSerializable
  . 
  .
  private def onEvent(state: State, event: Event): State = {
event match {
  case _ => {            
       state.copy(pollTime = state.pollTime.updated(timestampToStringDate(System.currentTimeMillis())))
   }
  }
 .
 .     
}

这是一个Typed EventSourced Actor,事件/命令处理程序因与序列化问题无关已省略。

使用Jackson序列化器,application.conf配置如下:

akka.actor.serialization-bindings {
  "module.CborSerializable" = jackson-cbor
}

模块中已定义trait CborSerializable,需排查操作错误点。


解决方案

问题核心:State是MyActor类的非静态内部类,Jackson反序列化时无法正确构造这类实例——非静态内部类必须依赖外部MyActor实例才能创建,但反序列化场景下没有可用的外部实例,即便提供默认无参构造器也无法解决。

修复方法二选一:

  • 将State移到MyActor的伴生对象object MyActor内部,此时它会成为静态嵌套类(Scala中伴生对象内的类不依赖外部类实例)
  • 直接把State定义为顶层类(放在当前文件最外层或单独文件中)

调整后的代码示例(将State移至伴生对象):

object MyActor {

  final case class Settings(
      name: String = "",
      accessToken: AccessToken = AccessToken()      

     ) extends CborSerializable

  // 把State移到伴生对象内,转为静态嵌套类
  final case class State(
      settings: Settings = Settings(),
      pollTime: Long = 0L
  ) extends CborSerializable
     .
     .
     .
}

class MyActor()(implicit system: ActorSystem[_]) {
  import MyActor._

  private implicit val executionContext: ExecutionContextExecutor = system.executionContext
  private val sharding = ClusterSharding(system)

  . 
  .
  private def onEvent(state: State, event: Event): State = {
event match {
  case _ => {            
       state.copy(pollTime = state.pollTime.updated(timestampToStringDate(System.currentTimeMillis())))
   }
  }
 .
 .     
}

调整后State成为独立的静态类,Jackson可通过无参构造器正常完成序列化与反序列化操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 18:01:25