Open w296488320 opened 3 months ago
Can you please provide a minimal, reproducible example so that we can reproduce this issue?
For example maybe some other part of your code is concurrently modifying the HashMap
at the same time your are serializing it with Gson.
I'm having exactly the same problem in the piece of code below:
fun trackValue(trigger: Map<String, Array
>?) { val json = Gson().toJson(ConcurrentHashMap<String, Any>().apply { put("key1","X") put("key2","Y") put("key3","Z") put("trigger", trigger.toString()) }) print(json.toString()) }
Notes:
The only case that its happening this crash is within Gson().toJson().
It's difficult to reproduce this error but at my company we have millions of active users and a low percentage of them are getting this exception.
The trigger value passed as parameter is Map so it cannot be modified.
But only within this function the type is Map
, the caller might have it as MutableMap
and might be modifying it concurrently? Or are you calling Java code with trigger
? Because Java only has the interface java.util.Map
, which is mutable, so even if you pass a Kotlin (non-mutable) Map
, the Java code can still modify it (unless you used java.util.Collections#unmodifiableMap
or similar).
I assume whether you use ConcurrentHashMap
in your code example does not matter, since that is only a temporarily map created in the trackValue
function and is only visible to Gson.
Does your code snippet really match your production code? The trigger.toString()
looks a bit dubious because it does not create JSON data, so you can most likely not parse it afterwards again; and also that call would be executed before toJson
is called, so I don't understand how that could result in the ConcurrentModificationException
for toJson
in the end.
Gson version
2.11.0
Java / Android version
java.util.ConcurrentModificationException at java.util.HashMap$HashIterator.nextNode(HashMap.java:1574) at java.util.HashMap$EntryIterator.next(HashMap.java:1607) at java.util.HashMap$EntryIterator.next(HashMap.java:1605) at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.write(MapTypeAdapterFactory.java:220) at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.write(MapTypeAdapterFactory.java:154) at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:73) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$2.write(ReflectiveTypeAdapterFactory.java:247) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:490) at com.google.gson.Gson.toJson(Gson.java:944) at com.google.gson.Gson.toJson(Gson.java:899) at com.google.gson.Gson.toJson(Gson.java:848) at com.google.gson.Gson.toJson(Gson.java:825)
Used tools
Description
Expected behavior
Actual behavior
Reproduction steps
Exception stack trace