In this short write-up, we will take a close look at the exception JsonMappingException: Can not deserialize instance of java.util.ArrayList from Object value (token JsonToken.START_OBJECT) exception.

We will begin by elucidating what causes Jackson to throw the exception. Then, we will illustrate using a practical example how to fix it.

The Cause

Usually, Jackson throws JsonMappingException during the process of deserializing a JSON string. It denotes a critical mapping error.

Typically, the message “Can not Deserialize Instance of java.util.ArrayList Out of start_object Token” indicates that Jackson cannot map a JSON property to an instance of java.util.ArrayList.

The deserializer expects a JSON array “[]” to perform deserialization into a collection.

So, attempting to use curly braces ”{}” instead of brackets will lead to JsonMappingException.

Let’s understand the problem quickly through an example.

Practical Example

First, let’s assume we have the following JSON document:

    
        {
          "label": "Human Resource Department",
          "employees": {
            "0":{
              "firstName": "Abderrahim",
              "lastName": "Azhrioun"
            },
            "1":{
              "firstName": "John",
              "lastName": "Miller"
            }
          }
        }
    

Basically, our JSON represents a department. It has a label and a list of employees.

As we can see, we used curly braces to define the employee list.

Next, let’s create the Department class as the target type:

    
        public class Department {
            private String label;
            private List<Employee> employees;
            public String getLabel() {
                return label;
            }
            public void setLabel(String label) {
                this.label = label;
            }
            public List getEmployees() {
                return employees;
            }
            public void setEmployees(List<Employee> employees) {
                this.employees = employees;
            }
        }
    

Please notice that we defined a List employees to map the list we specified in JSON.

This is how the class the Employee class looks like:

    
        public class Employee {
            private String firstName;
            private String lastName;
            public String getFirstName() {
                return firstName;
            }
            public void setFirstName(String firstName) {
                this.firstName = firstName;
            }
            public String getLastName() {
                return lastName;
            }
            public void setLastName(String lastName) {
                this.lastName = lastName;
            }
        }
    

Now, let’s deserialize the JSON document into an object of Department type:

    
        public static void main(String[] args) throws JsonMappingException, JsonProcessingException {
            String jsonDep = "{"+
                "\"label\": \"Human Resource Department\","+
                "\"employees\": {"+
                  "\"0\":{"+
                    "\"firstName\": \"Abderrahim\","+
                    "\"lastName\": \"Azhrioun\""+
                  "},"+
                  "\"1\": {"+
                    "\"firstName\": \"John\","+
                    "\"lastName\": \"Miller\""+
                  "}"+
                "}"+
            "}";

            Department dep = new ObjectMapper().reader()
                .forType(Department.class)
                .readValue(jsonDep);
        }
    

Looking at the logs, Jackson throws MismatchedInputException which is a subclass of JsonMappingException:

    
        Exception in thread "main" com.fasterxml.jackson.databind.exc.MismatchedInputException: 
        Cannot deserialize value of type `java.util.ArrayList<com.devwithus.Employee>` from Object value (token `JsonToken.START_OBJECT`)
        at Source: (String)"{"label": "Human Resource Department","employees": {"0":{"firstName": "Abderrahim","lastName": "Azhrioun"},"1":{"firstName": "John","lastName": "Miller"}}}";
    

The stack trace specifically indicates that the property employees starts with an object token ({) instead of an array token.

Please bear in mind that MismatchedInputException denotes a client error since the Department type itself is not the root cause but the mismatching JSON input.

The Solution

The only way to fix the exception is to use brackets instead of curly braces to define a collection of elements.

So, in our case, we need to rewrite the employees property of our JSON document:

    
        "employees": [
            {
              "firstName": "Abderrahim",
              "lastName": "Azhrioun"
            },
            {
              "firstName": "John",
              "lastName": "Miller"
            }
         ]
    

Now, deserializing the JSON input to a Department object will work as expected.

Conclusion

To sum it up, we explored the leading cause behind Jackson’s failure with JsonMappingException: “Can not deserialize instance of java.util.ArrayList from Object value (token JsonToken.START_OBJECT)”.

We also demonstrated how to deliberately reproduce the exception and provided a solution on how to fix it.