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

json4s中extract/decompose返回空JObject(Nil)的原因及修复方案

json4s框架decompose()/extract()返回空对象问题排查

问题现象

执行测试代码时,预期得到包含a、b字段的JSON对象,实际输出为空对象JObject(Nil),排除依赖冲突后问题仍然存在。
问题复现代码:

implicit val formats: Formats = DefaultFormats

case class StrInt(
    a: String = "A",
    b: Int = 2
)


val d1 = StrInt("a", 12)
val json = decompose(d1)

println(json)

运行时类路径依赖信息如下,无明显版本不匹配问题:

org.json4s:json4s-jackson_2.12:3.6.12

     org.scala-lang:scala-library:2.12.15 ➡ 2.12.16
     org.json4s:json4s-core_2.12:3.6.12
         org.scala-lang:scala-library:2.12.15 ➡ 2.12.16
         org.json4s:json4s-ast_2.12:3.6.12
             org.scala-lang:scala-library:2.12.15 ➡ 2.12.16
         org.json4s:json4s-scalap_2.12:3.6.12
             org.scala-lang:scala-library:2.12.15 ➡ 2.12.16
         com.thoughtworks.paranamer:paranamer:2.8
     com.fasterxml.jackson.core:jackson-databind:2.9.10.8
         com.fasterxml.jackson.core:jackson-annotations:2.9.10
         com.fasterxml.jackson.core:jackson-core:2.9.10

根本原因

该问题和依赖冲突、Scala小版本差异无关,核心诱因是用于序列化的case class被定义在了方法/函数的局部作用域中。
json4s的序列化、反序列化逻辑依赖类构造器的参数名做字段映射,底层通过paranamer库+Scala反射读取字节码中存储的构造参数元数据。如果case class定义在方法内部(即局部类),Scala编译生成的字节码会擦除对应的构造参数名信息,json4s读取不到任何可序列化的字段,调用decompose()时就会直接返回无字段的JObject(Nil),调用extract()反序列化时也会因为找不到字段映射,生成全默认值的空对象。
依赖树中显示的Scala 2.12.15到2.12.16的小版本漂移属于二进制兼容范围,不会触发该问题。

修复方案

  • 将需要参与json4s序列化/反序列化的case class移动到顶层作用域,或者单例object的成员位置,禁止定义在方法、函数、匿名代码块的局部作用域内。
  • 修复后可正常运行的代码示例:
import org.json4s._
import org.json4s.jackson.JsonMethods._

// case class定义在顶层作用域,不要放在main等方法内部
case class StrInt(
    a: String = "A",
    b: Int = 2
)

object JsonDemo {
  implicit val formats: Formats = DefaultFormats

  def main(args: Array[String]): Unit = {
    val d1 = StrInt("a", 12)
    val json = decompose(d1)
    println(json)
    // 正常输出:JObject(List((a,JString(a)), (b,JInt(12))))
  }
}
  • 如果是在REPL、脚本环境中临时测试,直接将case class写在执行代码的最外层即可,不要嵌套在其他代码块中。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 18:31:01