google / gson

A Java serialization/deserialization library to convert Java Objects into JSON and back
Apache License 2.0
23.23k stars 4.27k forks source link

Why can't Gson serialize the value of the scala.collection.immutable.Map type member variable of the case class into a JSON string,while java.util.HashMap is ok? #2601

Closed Ivankings closed 3 months ago

Ivankings commented 7 months ago

Gson version

gson version 2.85

Java / Android version

Java version 1.8.0_392 Scala version 2.12.15

Used tools

Description

Expected behavior

Actual behavior

Reproduction steps

case class Config(info: scala.collection.immutable.Map[String, String]) case class ConfigHashMap(info: java.util.HashMap[String, String])

val map = scala.collection.immutable.Map("k" -> "v") val hashMap = new java.util.HashMap[String, String]() hashMap.put("k", "v")

val config = Config(map) val configHashMap = ConfigHashMap(hashMap)

import com.google.gson.Gson; val g = new Gson() g.toJson(config) g.toJson(configHashMap) image

Exception stack trace

Marcono1234 commented 7 months ago

Gson has no explicit support for Scala, it might work for some cases but not for all. I am not familiar with Scala, but I assume scala.collection.immutable.Map does not implement java.util.Map, so Gson falls back to using reflection and apparently that does not work well here. And even if it worked you would rely on the implementation details of Scala's Map because Gson just accesses all fields, even if they are private.

You might be able to solve this by writing a custom TypeAdapterFactory for Scala's Map type. However, a better solution is probably to switch to a JSON library with explicit Scala support.

Does that answer your question?

Marcono1234 commented 3 months ago

I am going to close this because no answer has been provided. As mentioned in the comment above (and now also in the README), Gson's main focus is Java; for other JVM languages such as Scala it is probably better to use a library with explicit support for that language.