System for saving objects

I want to create a system for saving objects. I have three classes, that I want to save, to json format, but I don’t want to write by hand every variables. Is there any way that I can move the entire object to json format right away?

Hi,

Java provides already a system for serializing objects :

You can look at this thread if you really want to save them in JSON format :

They talk about the GSON library which can serialize objects to JSON without writing annotations in the class (something you want to avoid).

And this tutorial can get you started with the library : https://www.studytrails.com/java/json/java-google-json-parse-json-to-java/

1 Like

This is interesting, but I wrote this code:

void Save()
{  
  switch(mode) {
  case 1:
    for (int i = 0; i<cir.size(); i++)
    {
      save.saves(cir.get(i));
    }
    break;
  case 2:
    if (pendul)
    {
      for (int i = 0; i< pend.size(); i++)
      {
        save.saves(pend.get(i));
      }
    } else 
    {
      for (int i = 0; i< doublePend.size(); i++)
      {
        save.saves(doublePend.get(i));
      }
    }
    break;
  }
}
class SaveGame
{
  Gson gson; 
  String json;
  JSONObject js;

  SaveGame()
  {
    gson = new Gson();
  }

  void saves(Object obj)
  {
    json = gson.toJson(obj);
    js = parseJSONObject(json);
    boolean exist;
    if (js != null)
    {
      File f;
      int i = -1;
      do
      {
        i++;
        f = dataFile("saves/save" + i + ".txt");     
        exist = f.isFile();
      }
      while (exist);
      println(i, " ",f , " ",exist);//, " ",js, " ",json);
      saveJSONObject(js, "saves/save" + i + ".txt");
    }  
  }
}

But this isn’t working, and I have this errors: SEVERE: An error occured while forwarding a Controller event, please check your code at Save java.lang.reflect.InvocationTargetException Caused by: java.lang.IllegalArgumentException: class java.awt.Frame declares multiple JSON fields named state
That I don’t know how to resolve. Can you help me with that?

So you are using the GSON library?

Also what is the full stack trace of the error? (paste everything from the console)

It seems that you have multiple errors, are you using the ControlP5 library? Because it looks similar as this :


I’m using GSON, and ControlP5 library, and those are errors:
gru 03, 2020 10:14:43 PM controlP5.ControlBroadcaster printMethodError
SEVERE: An error occured while forwarding a Controller event, please check your code at Save
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at controlP5.ControlBroadcaster.invokeMethod(Unknown Source)
at controlP5.ControlBroadcaster.callTarget(Unknown Source)
at controlP5.ControlBroadcaster.broadcast(Unknown Source)
at controlP5.Controller.broadcast(Unknown Source)
at controlP5.Button.setValue(Unknown Source)
at controlP5.Button.activate(Unknown Source)
at controlP5.Button.mouseReleased(Unknown Source)
at controlP5.Controller.setMousePressed(Unknown Source)
at controlP5.ControllerGroup.setMousePressed(Unknown Source)
at controlP5.ControlWindow.mouseReleasedEvent(Unknown Source)
at controlP5.ControlWindow.mouseEvent(Unknown Source)
at sun.reflect.GeneratedMethodAccessor5.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at processing.core.PApplet$RegisteredMethods.handle(PApplet.java:1436)
at processing.core.PApplet.handleMethods(PApplet.java:1638)
at processing.core.PApplet.handleMouseEvent(PApplet.java:2749)
at processing.core.PApplet.dequeueEvents(PApplet.java:2652)
at processing.core.PApplet.handleDraw(PApplet.java:2493)
at processing.opengl.PSurfaceJOGL$DrawListener.display(PSurfaceJOGL.java:866)
at jogamp.opengl.GLDrawableHelper.displayImpl(GLDrawableHelper.java:692)
at jogamp.opengl.GLDrawableHelper.display(GLDrawableHelper.java:674)
at jogamp.opengl.GLAutoDrawableBase$2.run(GLAutoDrawableBase.java:443)
at jogamp.opengl.GLDrawableHelper.invokeGLImpl(GLDrawableHelper.java:1293)
at jogamp.opengl.GLDrawableHelper.invokeGL(GLDrawableHelper.java:1147)
at com.jogamp.newt.opengl.GLWindow.display(GLWindow.java:759)
at com.jogamp.opengl.util.AWTAnimatorImpl.display(AWTAnimatorImpl.java:81)
at com.jogamp.opengl.util.AnimatorBase.display(AnimatorBase.java:452)
at com.jogamp.opengl.util.FPSAnimator$MainTask.run(FPSAnimator.java:178)
at java.util.TimerThread.mainLoop(Timer.java:555)
at java.util.TimerThread.run(Timer.java:505)
Caused by: java.lang.IllegalArgumentException: class java.awt.Frame 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:458)
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:458)
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:458)
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:458)
at com.google.gson.internal.bind.ArrayTypeAdapter$1.create(ArrayTypeAdapter.java:48)
at com.google.gson.Gson.getAdapter(Gson.java:458)
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:458)
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:458)
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:458)
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:458)
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:458)
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:458)
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:458)
at com.google.gson.Gson.toJson(Gson.java:696)
at com.google.gson.Gson.toJson(Gson.java:683)
at com.google.gson.Gson.toJson(Gson.java:638)
at com.google.gson.Gson.toJson(Gson.java:618)
at Everything2D_3$SaveGame.saves(Everything2D_3.java:2346)
at Everything2D_3.Save(Everything2D_3.java:580)
… 35 more

Ok thanks,

This is probably this problem explained by Sojamo :

this is probably a concurrency issue. there are 2 threads running, the sketch itself and the ControlFrame.

Without having access to the code of a running example that demonstrates the behaviour you are encountering it is hard for me to tell if this is a controlp5 issue or a sketch issue. However if you modify an array in your main sketch from the controlFrame, a concurrency issue is very likely.

Using a CopyOnWriteArrayList instead of ArrayList might solve that issue.

(ControlFrame issues · Issue #138 · sojamo/controlp5 · GitHub)

And this related issue might help, this is not related to Gson :

Naw my code look like this:

void Save()
{  
  Gson gson = new Gson();
  String json = "0";
  JSONObject js;
  JSONArray values = new JSONArray();

  switch(mode) {
  case 1:
    for (int i = 0; i<cir.size(); i++)
    {
      json = gson.toJson(cir.get(i));
      js = parseJSONObject(json);
      values.setJSONObject(i, js);
    }
    break;
  case 2:
    if (pendul)
    {
      for (int i = 0; i< pend.size(); i++)
      {
        json = gson.toJson(pend.get(i));
        js = parseJSONObject(json);
        values.setJSONObject(i, js);
      }
    } else 
    {
      for (int i = 0; i< doublePend.size(); i++)
      {
        json = gson.toJson(doublePend.get(i));
        js = parseJSONObject(json);
        values.setJSONObject(i, js);
      }
    }
    break;
  }
  
  save.saves(values);
}

class SaveGame
{
  Gson gson; 
  String json;
  JSONObject js;

  SaveGame()
  {
    gson = new Gson();
  }

  void saves(JSONArray obj)
  {
 
    boolean exist = true;
    if (obj != null)
    {
      File f;
      int i = -1;
      do
      {
        i++;
        f = dataFile("saves/save" + i + ".txt");     
        exist = f.isFile();
      }
      while (exist);
      println(f, " ",obj);
      saveJSONArray(obj, "saves/save" + i + ".txt");
    }  
  }
}```

I don’t really know because I don’t have your full code (you don’t have to post it here).

Which objects are you saving with the saves function? It might be that controlP5 is accessing that object at the same time…

You might want to investigate yourself by commenting parts of your code and identifying where the error comes from (from the stack trace, this is made for that :wink: )

I’m using button from controlP5 to access this function, and to use stack trace, I would need to know how. This is my full project: https://github.com/Rafhub69/Everythig

Now my code look like this: pastebin.com/ZSLX1yRb, but I still have a problem. At this point, I don’t know why, but in the resulting file, after everything is done, the last js call is repeated in place of all previous JSONs.