2

I have a LinkedHashMap that contains two objects which both reside inside a normal HashMap. All 3 objects inside these maps have hashCode, equals, and toString methods. The "Chunk" object contains 3 variables a string and 2 integers all are final. The Location object only contains a string and 3 integers which are also final. Lastly, the ChestObject contains an enum and a list of other enums.

public static Map<Chunk, LinkedHashMap<Location, ChestObject>> CHEST_MAP = new HashMap<>();

public class Location {
private final String worldName;
private final int x;
private final int y;
private final int z;

public class Chunk {
private final String worldName;
private final int x;
private final int z;

public class ChestObject {
public List<Material> filteredMaterials = new ArrayList<>();
private ChestType chestType;

Saving the map works perfectly but retrieving the info throws the following error.

[17:17:53 WARN]: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 2 column 4 [17:17:53 WARN]:
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:176) [17:17:53 WARN]:
        at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:40) [17:17:53 WARN]:
        at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:186) [17:17:53 WARN]:
        at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:145) [17:17:53 WARN]:
        at com.google.gson.Gson.fromJson(Gson.java:803) [17:17:53 WARN]:
        at com.google.gson.Gson.fromJson(Gson.java:768) [17:17:53 WARN]:  
Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 2 column 4 [17:17:53 WARN]:
        at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:374) [17:17:53 WARN]:
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:165) [17:17:53 WARN]:
        ... 18 more

The file it attempts to read is the following...

{
  "WorldName:world X:-3 Z:-64": {
    "WorldName:world X:-39 Y:63 Z:-1016": {
      "filteredMaterials": [
        "ROTTEN_FLESH"
      ],
      "chestType": "DOUBLE"
    },
    "WorldName:world X:-40 Y:63 Z:-1016": {
      "filteredMaterials": [
        "ROTTEN_FLESH"
      ],
      "chestType": "DOUBLE"
    }
  }
}

The last bit of useful info is my recovery method which at this moment just attempts to print the map instead of assigning it to CHEST_MAP.

private void recoverChests() {
    final File file = new File(getDataFolder(), "chests.json");

    if(file.exists() && file.length() > 2) {
        try {
            final Gson gson = new GsonBuilder().setPrettyPrinting().create();
            final Type type = new TypeToken<Map<Chunk, LinkedHashMap<Location, ChestObject>>>() {}.getType();
            final Map<Chunk, LinkedHashMap<Location, ChestObject>> map = gson.fromJson(new FileReader(file), type);
            System.out.println("Map: " + map);
        } catch (IllegalStateException | JsonSyntaxException | IOException e) {
            e.printStackTrace();
        }
    }
}

So based on the above error it appears that Json is having a hard time serializing object keys while it has no trouble doing the same for values. This is shown above since we can see Json saving the data as a String instead of an object like it did with our ChestObject. So how can I correctly save the above data so that Json correctly serializes key objects?

 private void saveChests() {
        try {
            if(!CHEST_MAP.isEmpty()) {
                final File file = new File(this.getDataFolder(), "chests.json");
                final Gson gson = new GsonBuilder().setPrettyPrinting().create();
                final Writer writer = new FileWriter(file);

                gson.toJson(CHEST_MAP, writer);
                writer.flush();
                writer.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
  • Why doesn't your code show up in the stack trace? Did you edit it out (please don't do that)? – Jim Garrison Dec 23 '22 at 00:51
  • @JimGarrison I don't think the error message really matters too much since the issue is that I am not serializing it correctly. Json cannot take Objects as a HashMaps key which is the whole problem. However, if you are curious the error occurred when calling the recovery method when trying to make the map. Do you know how I can serialize Objects that are keys in hashmaps? – HowDoISolveThis Dec 23 '22 at 01:39
  • Assuming your json as seen by the code _really_ looks like what you posted, I don't think the dup flag is valid. Can you verify that the input stream really contains the json you showed? – Jim Garrison Dec 23 '22 at 22:15

0 Answers0