Suresh Atta
Suresh Atta

Reputation: 122026

Gson : StackOverflowError

The below codes causing StackOverflowError. purpose of the code is to create a json string from java class.

for (ControlTransaction crt : ctrList) {
                crt= new ControlTransaction();// for test, Still issue
                final Gson gson = new GsonBuilder().registerTypeAdapter(
                ControlTransaction.class,
                  new ControlTransactionSerializer()).create();
                String jsonControlTransactionString = gson.toJson(crt);
                strList.add(jsonControlTransactionString);

            }

My class looks like

public class ControlTransaction implements IsSerializable, Serializable ,IsBean{
    private long id;
    private String value; // H
    private String lastValue; // H
    private FormTransaction formTransaction;
    private List<FormTransaction> gridRows;
    private ControlTransaction referenceGridTransaction;
    private RowTransaction fkRowTransaction;
    private ReportTransaction reportTransaction;
    //getters ... setters
}

Stack trace followed like this, Let me know

Caused by: java.lang.StackOverflowError
at com.google.gson.stream.JsonWriter.<init>(JsonWriter.java:190)
at com.google.gson.internal.bind.JsonTreeWriter.<init>(JsonTreeWriter.java:58)
at com.google.gson.Gson.toJsonTree(Gson.java:478)
at com.google.gson.Gson$3.serialize(Gson.java:140)
at com.nextenders.common.ControlTransactionSerializer.serialize(ControlTransactionJsonUtil.java:129)
at com.nextenders.common.ControlTransactionSerializer.serialize(ControlTransactionJsonUtil.java:1)
at com.google.gson.TreeTypeAdapter.write(TreeTypeAdapter.java:70)
at com.google.gson.Gson.toJson(Gson.java:586)
at com.google.gson.Gson.toJsonTree(Gson.java:479)
at com.google.gson.Gson$3.serialize(Gson.java:140)
at com.nextenders.common.ControlTransactionSerializer.serialize(ControlTransactionJsonUtil.java:129)
at com.nextenders.common.ControlTransactionSerializer.serialize(ControlTransactionJsonUtil.java:1)
at com.google.gson.TreeTypeAdapter.write(TreeTypeAdapter.java:70)
at com.google.gson.Gson.toJson(Gson.java:586)
at com.google.gson.Gson.toJsonTree(Gson.java:479)
at com.google.gson.Gson$3.serialize(Gson.java:140)
at com.nextenders.common.ControlTransactionSerializer.serialize(ControlTransactionJsonUtil.java:129)
at com.nextenders.common.ControlTransactionSerializer.serialize(ControlTransactionJsonUtil.java:1)
at com.google.gson.TreeTypeAdapter.write(TreeTypeAdapter.java:70)
at com.google.gson.Gson.toJson(Gson.java:586)
at com.google.gson.Gson.toJsonTree(Gson.java:479)
at com.google.gson.Gson$3.serialize(Gson.java:140)

Here is my serializer and deserializer

class ControlTransactionDeserializer implements
        JsonDeserializer<ControlTransaction> {
    @Override
    public ControlTransaction deserialize(JsonElement json, Type type,
            JsonDeserializationContext context) throws JsonParseException {
        return context.deserialize(json, type);
    }
}

class ControlTransactionSerializer implements
        JsonSerializer<ControlTransaction> {

    @Override
    public JsonElement serialize(ControlTransaction ctr, Type type,
            JsonSerializationContext context) {
        return context.serialize(ctr, type);
    }
}

Whats going on in backend. I just passed a empty Object, that means new ControlTransaction(), Still unable to parse.

Upvotes: 2

Views: 6711

Answers (1)

Sotirios Delimanolis
Sotirios Delimanolis

Reputation: 280175

The point of a JsonSerializer is to serialize the fields of an Object, not the object itself. However, you are passing the object you've already told Gson to serialize. The following

@Override
public JsonElement serialize(ControlTransaction ctr, Type type,
        JsonSerializationContext context) {
    return context.serialize(ctr, type);
}

is equivalent to

@Override
public JsonElement serialize(ControlTransaction ctr, Type type,
        JsonSerializationContext context) {
    return new GsonBuilder().registerTypeAdapter(
            ControlTransaction.class,
              new ControlTransactionSerializer()).create().toJsonTree(ctr);
}

which I hope you can see is going into recursive loop.

The JsonSerializationContext is basically the underlying structure that the Gson object uses to serialize your object. When it sees your type ControlTransaction, it will delegate to your custom JsonSerializer. But your JsonSerializer will send it back to the JsonSerializationContext and the loop goes on.

Upvotes: 5

Related Questions