yasson
yasson copied to clipboard
Json silently returns an empty list instead of failing
Describe the bug When providing a json object instead of a json array and asking Jsonb to produce a list, the library returns an empty list; whereas it should throw an exception to indicate to the caller that something is wrong.
To Reproduce
String json = "{\"name\": \"John Doe\"}";
try (Jsonb jsonb = JsonbBuilder.create()) {
List<Person> list = jsonb.fromJson(json, new ArrayList<Person>() {
private static final long serialVersionUID = -7485196487128234751L;
}.getClass().getGenericSuperclass());
/** The deserialization process returns an empty list instead of failing fast: */
assertEquals(List.of(), list);
}
See Person and PersonTests for full details.
Expected behavior
I expect that the call jsonb.fromJson in the above example throws an exception indicating that the input string is not in a format that allows to extract a list of persons (as a json array is expected and not a json object).
System information:
- Yasson Version: 1.0.7
Additional context
This bug was found by students in my course, whose GitHub usernames are Sarah-Elhelw and Semida-Buzdugan. Credits go to them.
hi @oliviercailloux, thanks for raising this issue. My first thought here is that this falls under the "must-ignore" policy defined in section 3.18 of the JSON-B spec:
When JSON Binding implementation during deserialization encounters key in key/value pair that it does not recognize, it should treat the rest of the JSON document as if the element simply did not appear, and in particular, the implementation MUST NOT treat this as an error condition.
I know this is is not always preferred behavior for users though, so I have raised an issue to have a way to globally opt-out of this policy here: https://github.com/eclipse-ee4j/jsonb-api/issues/56
I disagree this falls under must-ignore. Here, Json is given a JsonObject whereas a JsonArray is expected. The lack of failure is not a consequence of ignoring some keys: it is rather as if 1) the whole object was ignored (including thus the opening and closing curly brackets), and 2) the lack of opening and closing square brackets was ignored as well.
Have you had some chance to investigate this bug? To reiterate, the lack of failure is not a consequence of ignoring some keys, thus the quoted paragraph does not apply and Yasson should fail, it seems to me.
The given code now correctly throws an exception:
Exception in thread "main" jakarta.json.bind.JsonbException: Incorrect position for processing type: class java.util.ArrayList. Received event: START_OBJECT Allowed: [START_ARRAY]
at org.eclipse.yasson/org.eclipse.yasson.internal.deserializer.PositionChecker.deserialize(PositionChecker.java:80)
at org.eclipse.yasson/org.eclipse.yasson.internal.deserializer.PositionChecker.deserialize(PositionChecker.java:1)
at org.eclipse.yasson/org.eclipse.yasson.internal.deserializer.NullCheckDeserializer.deserialize(NullCheckDeserializer.java:46)
at org.eclipse.yasson/org.eclipse.yasson.internal.deserializer.NullCheckDeserializer.deserialize(NullCheckDeserializer.java:1)
at org.eclipse.yasson/org.eclipse.yasson.internal.DeserializationContextImpl.deserializeItem(DeserializationContextImpl.java:138)
at org.eclipse.yasson/org.eclipse.yasson.internal.DeserializationContextImpl.deserialize(DeserializationContextImpl.java:127)
at org.eclipse.yasson/org.eclipse.yasson.internal.JsonBinding.deserialize(JsonBinding.java:55)
at org.eclipse.yasson/org.eclipse.yasson.internal.JsonBinding.fromJson(JsonBinding.java:70)
at org.eclipse.yasson/asd.Main.main(Main.java:14)