Skip to content

JSONObject.accumulate() with Map produces invalid JSON in toString() #1057

@vrubal

Description

@vrubal

Bug: JSONObject.accumulate() with Map produces invalid JSON in toString()

Version

  • Broken: 20250517, 20251224
  • Works correctly: 20240303

Description

When using JSONObject.accumulate(String key, Map value) followed by toString(), the nested Map is serialized using Java's Map.toString() format ({key=value, key=value}) instead of valid JSON ({"key":"value","key":"value"}).

This is a regression from version 20240303 where accumulate() would properly wrap the Map into a JSONObject internally before storing it.

Steps for Reproduction

import org.json.JSONObject;
import java.util.HashMap;
import java.util.Map;

public class OrgJsonAccumulateBug {
    public static void main(String[] args) {
        Map<String, String> responseMap = new HashMap<>();
        responseMap.put("responseCode", "00");

        Map<String, String> data= new HashMap<>();
        data.put("firstName", "John");
        data.put("lastName", "Doe");

        JSONObject jsonOut = new JSONObject(responseMap);
        jsonOut.accumulate("data", data);

        System.out.println(jsonOut.toString());
    }
}

Expected Output (valid JSON)

{"responseCode":"00","data":{"firstName":"John","lastName":"Doe"}}

Actual Output (invalid — Java Map.toString())

{"responseCode":"00","data":"{firstName=John, lastName=Doe}"}

Impact

Any code that uses accumulate() to add a Map to a JSONObject and then uses toString() to produce JSON for downstream parsing (e.g., Jackson ObjectMapper deserialization) will fail because the output is not valid JSON.

Jackson throws:

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `MyClass`:
no String-argument constructor/factory method to deserialize from String value ('{key=value, ...}')

Workaround

Use put() with explicit new JSONObject(map) wrapping:

jsonOut.put("data", new JSONObject(tokenData));

Suggested Fix

accumulate() should wrap Map values in new JSONObject(map) (and List values in new JSONArray(list)) before storing, as it did in 20240303.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions