The API we ingest returns some malformed JSON (in particular Double.NaN
is serialized to a String
with "NaN").
To allow this gson always sets lenient
to true and correctly serializes this back to Double.NaN
.
Now, we wanted to use the RuntimeTypeAdapterFactory
class from gson-extras to remove some boilerplate code.
The just described behaviour does not apply here anymore, we get the message
java.lang.NumberFormatException: JSON forbids NaN and infinities: NaN
which
should have been ignored because of the lenient
option normally set from gson.
Consider this small example:
class Base
{
String type;
double malformedField;
}
class A extends Base{}
class B extends Base{}
We use the type
field in order to determine which subclass we want, because of course otherwise we couldn't infer the correct type.
This is the setup we use to create our subclasses and deserialize:
RuntimeTypeAdapterFactory<Base> adapterFactory = RuntimeTypeAdapterFactory.of(Base.class, "type", true)
.registerSubtype(A.class, "A")
.registerSubtype(B.class, "B");
Gson gson = new GsonBuilder()
.registerTypeAdapterFactory(adapterFactory)
//.setLenient() // Has no effect at all
.create();
String json = "{\"type\":\"A\", \"malformedField\": \"NaN\"}";
Base a = gson.fromJson(json, Base.class); // throws said Exception
Implementation in RuntimeTypeAdapterFactory
:
Upon checking the code from the RuntimeTypeAdapterFactory
I noticed that the lenient
option is never set to true, because we invoke the fromJsonTree
method of com.google.gson.TypeAdapter
, in which we create a new JsonTreeReader
without a possiblity to change the lenient
option.
public final T fromJsonTree(JsonElement jsonTree) {
try {
JsonReader jsonReader = new JsonTreeReader(jsonTree);
return read(jsonReader);
} catch (IOException e) {
throw new JsonIOException(e);
}
}
I tried to manually set this through debugging to true
and that seemed to work as expected (no
NumberFormatException
and object gets deserialized correctly with specified type).
Now the question is: Is there something I am missing about why we can't use the lenient
option here? At a first glance this seems to be a bug from gson-extras but I am unsure.