Description
Problem solved by the feature
Gson uses its internal LinkedTreeMap
as Map
implementation when a Map<String, ...>
(or a raw Map
) should be created. The reasons for this LinkedTreeMap
seem to be that old JDK versions were vulnerable to denial-of-service attacks due to hash code collision. See previous discussions in #1992 (comment) (that also covers another Gson Map implementation which we had removed in the meantime) and #2152 (comment).
The problem is that Gson's LinkedTreeMap
:
- Does not permit
null
keys - Requires that keys must be
Comparable
This can cause issues such as #1247, but also for less contrived cases where the user tries to add null
or non-Comparable
to the deserialized map, such as:
@SuppressWarnings("unchecked")
Map<Object, Object> map = new Gson().fromJson("{}", Map.class);
map.put(null, 1);
var map2 = new Gson().fromJson("{}", new TypeToken<Map<String, Integer>>() {});
map2.put(null, 1);
Note: I have added the
java8
LinkedTreeMap
is not needed as denial-of-service protection, see JDK-8046170.
But we could also already make this change while Gson is still targeting Java 7 as minimum.
Feature description
We should consider not creating Gson's LinkedTreeMap
in ConstructorConstructor
anymore, but only JDK LinkedHashMap
.
(And adjust unit tests which assert isInstanceof(LinkedTreeMap.class)
and isNotInstanceof(LinkedTreeMap.class)
.)
Note: We can probably not completely remove LinkedTreeMap
because:
- External users rely on it (even though they shouldn't because the class is internal); we could mark it as
@Deprecated
though JsonObject
uses it, and especially itsasMap
method relies onLinkedTreeMap
not permittingnull
keys and values
Otherwise we would have to write a custom wrapper class which disallowsnull
keys and values (similar to what we have forJsonArray#asList
)
This would then:
- Resolve Confusing Exceptions #1247
- Obsolete Fix LinkedTreeMap being used for non-Comparable keys #2152
Alternatives / workarounds
- Try to fix at least some cases of
ClassCastException
due toLinkedTreeMap
usage, see Fix LinkedTreeMap being used for non-Comparable keys #2152