javagsondeserializationobservablelist

Gson fails to deserialize because of Usage of Observable List


I want to use Gson to im- and export the Characters created in my software and while export works just fine, the Import fails with an

java.lang.IllegalArgumentException: Can not set javafx.collections.ObservableList field items.GameCharacter.weapons to java.util.ArrayList

I read the gson documentation and it said to solve this issue via a token type, but I don't know how I should do this exactly because the attributes Gson fails to deserialize are of different types: The complete object is of type GameCharacter with a few Integer and Strings, but I also use:

    private ObservableList<Weapon> weapons;
    private BattleRound battleRound;
    private ObservableList<Spell> spells;
    private Armor armor;

How exactly can I tell gson all these different types when it only accepts one TypeToken? Any help would be appreciated :) Btw my code used for Import:

public class Import {

    private Gson gson = new GsonBuilder().setPrettyPrinting().create();

    public GameCharacter importCharacter(String url) {
        try (Reader reader = Files.newBufferedReader(Paths.get(url), Charset.defaultCharset())) {
            return gson.fromJson(reader, new TypeToken<GameCharacter>(){}.getType());
        } catch (IOException e) {

        }
        throw new NullPointerException("No character was able to load");
    }
}

Solution

  • Type tokens help deal with the issue of Type erasure where generic information is lost at runtime(List<String> becomes List at runtime so it doesn't know what is in the List).

    Your issue looks like you are attempting to deserialize to ObservableList which is probably not a type that is compatible with gson by default. You can implement your own Custom deserializer following the docs or you can serialize/deserialize to a simpler object that uses core better supported types such as List and copy to your internal object.

    Usually objects like Observable List are not good targets for serialization usage as they need additional work to reinitialize on reload.