2

I'm trying to use GSON in my Swing User Interface, when I'm trying to create a GSON object I get an error considering java.applet.Applet class. The weird thing is that I'm not even using Applet elements to save or load using GSON.

Can someone explain to me what is happening?

The code is below.

The error I'm getting

java.lang.IllegalArgumentException: class java.applet.Applet declares multiple JSON fields named accessibleContext

Loading Object to json on button click:

JButton selectProfileSaveLocationButton = new JButton("Select Location");
    selectProfileSaveLocationButton.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            //todo create new empty profile
            JFileChooser jfc = new JFileChooser(FileSystemView.getFileSystemView().getHomeDirectory());
            jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);

            int returnValue = jfc.showSaveDialog(null);
            if (returnValue == JFileChooser.APPROVE_OPTION) {
                if (jfc.getSelectedFile().isDirectory()) {
                    profileSaveLocationTextfield.setText(jfc.getSelectedFile().getAbsolutePath());
                    try {
                        System.out.println("Saving file to: " + jfc.getSelectedFile().getAbsolutePath() + File.separatorChar + profileNameTextfield.getText() + ".json");
                        File dataFile = new File(jfc.getSelectedFile().getAbsolutePath() + File.separatorChar + profileNameTextfield.getText() + ".json");
                        //dataFile.createNewFile();
                        Data.botProfileLocation = dataFile;


                        SlayerProfile profile = newEmptyProfile(profileNameTextfield.getText());
                        String json = FryslanSlayer.gson.toJson(profile);

                        System.out.println(json);

                        FileWriter writer = new FileWriter(Data.botProfileLocation.getAbsolutePath());
                        FryslanSlayer.gson.toJson(profile, writer);

                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        }
    }
});
selectProfileSaveLocationButton.setBackground(new Color(65, 105, 225));
selectProfileSaveLocationButton.setForeground(new Color(0, 0, 139));
selectProfileSaveLocationButton.setBounds(610, 274, 124, 25);
generalPanel.add(selectProfileSaveLocationButton);
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Piet Jetse
  • 388
  • 1
  • 5
  • 16
  • For better help sooner, [edit] to add a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/). Hard code the GSON data. – Andrew Thompson Apr 23 '20 at 04:53

4 Answers4

0

Only explantion I can estimate is that your SlayerProfile.class either extends Applet, or contains a field which does.

GSON can't handle classes which the same field name on multiple levels of the class hierarchy, which is the case for the Applet class. See class A declares multiple JSON fields for more details.

Without sharing your definition of SlayerProfile it is hard to be sure this is the problem.

Another thing I am missing from your question is the definition of how your GSON object is setup. It is possible this issue is related do to misconfiguraiton of your GSON object.

Tom Cools
  • 1,098
  • 8
  • 23
0

You are experience this problem because your class SlayerProfile has a property that is either of type Applet or that references Applet at some point (it can be many levels deep). It's definitely not due to inheritance because Gson calls Object#getClass to get the type displayed in that error so it would have shown the implementation class.

The reason why Gson cannot deserialize Applet is because it uses property names to transform an object to JSON. JSON doesn't have the concept of hierarchy that Java does so you cannot create a JSON with that ambiguity that makes sense and can be serialized back to the same object. More on Gson using fields:

Some Json libraries use the getters of a type to deduce the Json elements. We chose to use all fields (up the inheritance hierarchy) that are not transient, static, or synthetic. We did this because not all classes are written with suitably named getters. Moreover, getXXX or isXXX might be semantic rather than indicating properties.

There is not best solution for this with the data you have provided. Depending on your needs you might want to make the Applet reference transient, create a custom TypeAdapter or something else that is more sensible in your case.

acm
  • 2,086
  • 3
  • 16
  • 34
0

Is your SlayerProfile class defined without the static keyword, and within a subclass of Applet? If so, it implicitly has a reference to the Applet subclass, so Gson tries to serialize that class too, and you need to add the static keyword to SlayerProfile

Angus H
  • 404
  • 3
  • 8
0

GSON looks up at the object's private fields when serializing, meaning all private fields of superclass are included, and when you have fields with same name it throws an error.

If there's any particular field you don't want to include you have to mark it with transient keyword, eg:

protected transient DontSerializeMeClass dontSerializeMeClass;

In this case you might look at trying to hide accessibleContext field by adding it to Slayer. I am not sure about the rest of your code because I can only see a small fragment of it, but I presume somehow it either inherits from Applet or it declares a variable which comes from that family tree.

An article related to this topic can be found here: class A declares multiple JSON fields

private static transient AccesssibleContext accessibleContext = null;

Please refer to this SO article which drives home to the error you're looking at.

Polymorphism with gson