The entirely new V2 of my flagship REST With Spring course is out:
This has been my first and most popular course, so it's been cool releasing this all-new material here.
Last updated: May 11, 2024
In this short tutorial, we’ll shed light on how to fix the exception JsonMappingException: Can not deserialize instance of java.util.ArrayList from Object value (token `JsonToken.START_OBJECT`).
First, we’ll highlight the main cause of the exception. Then we’ll demonstrate how to reproduce it in practice, and finally, how to solve it.
Typically, Jackson throws JsonMappingException to signal a fatal mapping error when deserializing a JSON string. Therefore, the stack trace “Can not deserialize instance of java.util.ArrayList” indicates that Jackson failed to map a JSON property into an instance of ArrayList.
In short, the most common cause of this exception is using curly braces “{…}” to denote a collection instead of brackets “[…]”.
Now that we know what causes Jackson to throw JsonMappingException, let’s see how to reproduce it using a practical example.
Let’s consider the Country class:
public class Country {
private String name;
private List<String> cities;
// standard getters and setters
}
As we can see, a country is defined by a name and a list of cities.
Next, let’s pretend to use curly braces to define cities in a JSON string:
{
"name": "Netherlands",
"cities": {"Amsterdam", "Tamassint"}
}
Now trying to deserialize the JSON string into an object of Country type will result in the following:
Cannot deserialize value of type `java.util.ArrayList<java.lang.String>` from Object value (token `JsonToken.START_OBJECT`)
at [Source: (String)"{"name":"Netherlands","cities":{"Amsterdam", "Tamassint"}}"; line: 1, column: 32]
(through reference chain: com.baeldung.mappingexception.Country["cities"])
...
Finally, we’ll create a test case to confirm this:
@Test
public final void givenJsonWithInvalidList_whenDeserializing_thenThrowException() throws JsonParseException, IOException {
String json = "{\"name\":\"Netherlands\",\"cities\":{\"Amsterdam\", \"Tamassint\"}}";
ObjectMapper mapper = new ObjectMapper();
Exception exception = assertThrows(JsonMappingException.class, () -> mapper.reader()
.forType(Country.class)
.readValue(json));
assertTrue(exception.getMessage()
.contains("Cannot deserialize value of type `java.util.ArrayList<java.lang.String>`"));
}
As shown above, Jackson fails with “Cannot deserialize value of type `java.util.ArrayList<java.lang.String>`”.
The main reason here is that we used curly braces to represent a list of cities. For Jackson, {“Amsterdam”, “Tamassint”} isn’t a JSON array.
The easiest way to avoid the exception is to use brackets instead of curly braces to define a collection of elements. So to solve the exception, we need to fix our JSON string first:
{
"name": "Netherlands",
"cities": ["Amsterdam", "Tamassint"]
}
Now let’s verify that everything works as excepted using a test case:
@Test
public final void givenJsonWithValidList_whenDeserializing_thenCorrect() throws JsonParseException, IOException {
String json = "{\"name\":\"Netherlands\",\"cities\":[\"Amsterdam\", \"Tamassint\"]}";
ObjectMapper mapper = new ObjectMapper();
Country country = mapper.reader()
.forType(Country.class)
.readValue(json);
assertEquals("Netherlands", country.getName());
assertEquals(Arrays.asList("Amsterdam", "Tamassint"), country.getCities());
}
As we can see, the new JSON string is successfully deserialized into a Country object.
In this brief article, we discussed the main cause of the JsonMappingException: Can not deserialize instance of java.util.ArrayList from Object value (token `JsonToken.START_OBJECT`). Then we showcased how to produce the exception, and how to solve it.
As always, the full source code of the examples is available over on GitHub.