Search code examples
javajsonclasscastexceptiondowncast

ClassCastException for downcast JSONObject to JSONArray


i'm using the simple JSON library to write a match log analyzer for tf2. The code successfully gets all log IDs but cannot get to the actual log itself. The error is that

Exception in thread "main" java.lang.ClassCastException: org.json.simple.JSONObject cannot be cast to org.json.simple.JSONArray

However, in the code, I've already casted an object to an array. Here is a snippet of the code, where parseJSON returns a JSONObject and logIDList contains a list of all the log ids:

JSONArray playerData = (JSONArray)parseJSON("http://logs.tf/json_search?player=" + steamID64).get("logs");
    //....
        JSONArray tempJSONArray = (JSONArray)parseJSON("http://logs.tf/json/" + logIDList.get(j)).get("players");

The second attempt at casting the JSONObject always throws a casting error. Using IntelliJ's debugger, parseJSON successfully parses the JSON and returns multiple keys.

The first JSON file is structured as so:

{
 "logs": [
{
  "date": 1512093930, 
  "id": 1893064, 
  "title": "UGC 6v6 Match: RED vs -rep"
},
],
} 

The second JSON file is structured as so:

{  
"players" : {
"[U:1:61383870]":{(Player Stats)}
},
}

My assumption is that it is due to there being a key within a key or something like that? Not sure why this tells me I can't cast this to an array, when I did it with another JSONObject.


Solution

  • You are downcasting from Object to Array. This works if the instance really is an array, and fails if it not (like a map). You should always protect downcasts with instanceof checks in general, like:

    JSONArray playerData;
    JSONObject playerJson = parseJSON("http://logs.tf/json_search?player=" + steamID64).get("logs");
    if (playerJson instanceof JSONArray) {
        playerData = (JSONArray) playerJson;
    } else {
        throw new IllegalStateException("wrong Json type " + playerJson)
    }
    

    As you can see from the json you posted:

    "logs": [ ...]
    

    log is an array, while

    "players" : { ... }
    

    players is a map.