首页
/ Apache Fury Scala 对象反序列化问题解析

Apache Fury Scala 对象反序列化问题解析

2025-06-25 16:45:40作者:董灵辛Dennis

问题背景

在使用 Apache Fury 进行 Scala 对象序列化/反序列化时,开发人员发现了一个特殊现象:当尝试反序列化一个 Scala 的 case object 或单例对象时,首次反序列化会返回 null 值,而只有在执行过一次序列化操作后,后续的反序列化才能正常工作。

问题复现

这个问题在以下两种场景中表现明显:

  1. 简单 case class 场景:定义一个简单的 case class 并尝试反序列化其序列化后的字节数组,首次反序列化返回 null,执行一次序列化操作后,再次反序列化才能得到正确结果。

  2. Scala 枚举模式场景:使用 sealed trait 和 case object 实现的枚举模式,当修改枚举值后重新运行程序,反序列化会返回 null 而不是预期的枚举值。

技术分析

经过深入分析,发现问题的根源在于 Scala 对单例对象(object)的懒加载机制。Scala 中的单例对象是延迟初始化的,只有在首次被访问时才会真正创建实例。这种设计导致了以下行为:

  1. 当 Fury 的 SingletonObjectSerializer 尝试读取单例对象时,如果该对象尚未被初始化,其 MODULE$ 字段可能为 null 或者根本不存在。

  2. 只有在程序显式引用了该单例对象(如执行序列化操作时),Scala 运行时才会初始化该对象,设置 MODULE$ 字段。

  3. 这就是为什么首次反序列化失败,而执行序列化后反序列化却能成功的原因——序列化操作隐式触发了单例对象的初始化。

解决方案

针对这个问题,社区提出了一个优雅的解决方案:在 SingletonObjectSerializer 的构造函数中,主动检查并确保目标类已完成初始化。具体实现是通过 Java 的 Unsafe API 来强制初始化目标类:

public SingletonObjectSerializer(Fury fury, Class type) {
  super(fury, type);
  if (Platform.UNSAFE.shouldBeInitialized(type)) {
    Platform.UNSAFE.ensureClassInitialized(type);
  }
  try {
    field = type.getDeclaredField("MODULE$");
  } catch (NoSuchFieldException e) {
    throw new RuntimeException(type + " doesn't have `MODULE$` field", e);
  }
}

这个修改确保了在访问 MODULE$ 字段之前,目标类已经完全初始化,从而解决了首次反序列化返回 null 的问题。

技术启示

这个问题给我们几个重要的技术启示:

  1. 理解语言特性:在使用序列化框架时,必须深入理解目标语言的特性,如 Scala 的单例对象懒加载机制。

  2. 框架适配:通用序列化框架需要针对不同语言的特性进行特殊处理,不能假设所有语言的对象初始化行为都一致。

  3. 防御性编程:在访问可能延迟初始化的资源时,应该采用防御性编程策略,确保资源可用后再进行操作。

这个问题的解决不仅修复了 Apache Fury 在 Scala 环境下的一个关键问题,也为处理类似的语言特性与序列化框架的交互提供了有价值的参考。

登录后查看全文
热门项目推荐

热门内容推荐

最新内容推荐

项目优选

收起
docsdocs
OpenHarmony documentation | OpenHarmony开发者文档
Dockerfile
143
1.91 K
kernelkernel
deepin linux kernel
C
22
6
nop-entropynop-entropy
Nop Platform 2.0是基于可逆计算理论实现的采用面向语言编程范式的新一代低代码开发平台,包含基于全新原理从零开始研发的GraphQL引擎、ORM引擎、工作流引擎、报表引擎、规则引擎、批处理引引擎等完整设计。nop-entropy是它的后端部分,采用java语言实现,可选择集成Spring框架或者Quarkus框架。中小企业可以免费商用
Java
8
0
ohos_react_nativeohos_react_native
React Native鸿蒙化仓库
C++
192
273
RuoYi-Vue3RuoYi-Vue3
🎉 (RuoYi)官方仓库 基于SpringBoot,Spring Security,JWT,Vue3 & Vite、Element Plus 的前后端分离权限管理系统
Vue
927
551
openHiTLSopenHiTLS
旨在打造算法先进、性能卓越、高效敏捷、安全可靠的密码套件,通过轻量级、可剪裁的软件技术架构满足各行业不同场景的多样化要求,让密码技术应用更简单,同时探索后量子等先进算法创新实践,构建密码前沿技术底座!
C
421
392
openGauss-serveropenGauss-server
openGauss kernel ~ openGauss is an open source relational database management system
C++
145
189
金融AI编程实战金融AI编程实战
为非计算机科班出身 (例如财经类高校金融学院) 同学量身定制,新手友好,让学生以亲身实践开源开发的方式,学会使用计算机自动化自己的科研/创新工作。案例以量化投资为主线,涉及 Bash、Python、SQL、BI、AI 等全技术栈,培养面向未来的数智化人才 (如数据工程师、数据分析师、数据科学家、数据决策者、量化投资人)。
Jupyter Notebook
75
64
Cangjie-ExamplesCangjie-Examples
本仓将收集和展示高质量的仓颉示例代码,欢迎大家投稿,让全世界看到您的妙趣设计,也让更多人通过您的编码理解和喜爱仓颉语言。
Cangjie
344
1.3 K
easy-eseasy-es
Elasticsearch 国内Top1 elasticsearch搜索引擎框架es ORM框架,索引全自动智能托管,如丝般顺滑,与Mybatis-plus一致的API,屏蔽语言差异,开发者只需要会MySQL语法即可完成对Es的相关操作,零额外学习成本.底层采用RestHighLevelClient,兼具低码,易用,易拓展等特性,支持es独有的高亮,权重,分词,Geo,嵌套,父子类型等功能...
Java
36
8