0
votes

I'm trying to make a 2D tile game and I was trying to add items by importing them from a JSON file. I tried importing the JSON file using GSON library, but whenever I run the code I get the following error:

java.lang.IllegalArgumentException: class javax.swing.JFrame declares multiple JSON fields named state
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:172)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:102)
    at com.google.gson.Gson.getAdapter(Gson.java:457)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:117)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:166)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:102)
    at com.google.gson.Gson.getAdapter(Gson.java:457)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:117)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:166)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:102)
    at com.google.gson.Gson.getAdapter(Gson.java:457)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:117)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:166)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:102)
    at com.google.gson.Gson.getAdapter(Gson.java:457)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:117)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:166)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:102)
    at com.google.gson.Gson.getAdapter(Gson.java:457)
    at com.google.gson.internal.bind.ArrayTypeAdapter$1.create(ArrayTypeAdapter.java:48)
    at com.google.gson.Gson.getAdapter(Gson.java:457)
    at com.google.gson.Gson.fromJson(Gson.java:921)
    at com.google.gson.Gson.fromJson(Gson.java:860)
    at dev.bako.tilegame.utils.JSONImporter.ItemJSONReader(JSONImporter.java:13)
    at dev.bako.tilegame.Game.init(Game.java:63)
    at dev.bako.tilegame.Game.run(Game.java:101)
    at java.lang.Thread.run(Thread.java:745)

.

The JSONImporter class is the following:

public class JSONImporter {

    public static void ItemJSONReader() throws Exception {

        Item[] items = new Gson().fromJson(new FileReader("res/JSON/Item.json"), Item[].class);//This is where I get the error
        System.out.println("Loaded file!" + items); 

    }

}

The JSON file I'm trying to import:

{
  "Wood": {
    "id": 0
  },
  "Rock": {
    "id": 2
  }
}
1
What is the structure of Item and why are you deserialising Item[] when your data seems to be Map<String, Item>? Then what does Swing and JFrame have to do with all this, with the process of data deserialisation? And please do not tell that you do not have a DTO to deserialise into which is independent of the view layer. - Oleg Sklyar
I changed the type of items to Map<String, Item> and now it works, I hadn't thought of using Map, so I was focusing on ArrayList and I think that this is where all the problems were. I also modified the implementation of the method, since I had wrongly put in view layer and now I don't have new problems or errors. - Pier Francesco
Because it helped I put my comment as the answer. - Oleg Sklyar

1 Answers

0
votes

The structure of your JSON file suggests that you should be expecting Map<String, Item> instead of Item[]:

  • JSON arrays are surrounded by []
  • arrays (lists) do not have keys and here keys are obviously visible, e.g. "Wood"

So changing that should be leading you to a solution.

Nevertheless, the fact that Swing and JFrame are a part of the trace stack suggest that they are a part of the Item class. Remember how "Clean Code" or SOLID tell that (in this case) a class should have just one responsibility: transporting data is normally performed by dummy DTOs which should have no view-related logic.