i have a class Delete which i want to convert it into json using Gson library but when i convert it it throws exception of java.lang.StackOverflowError: null
he
The issue is that the bytecode of a Scala Enumeration contains a collection of the possible values - each of which is an instance of the enumeration.
For example, if we run javap CoinFaces
on:
object CoinFaces extends Enumeration {
type CoinFaces = Value
val Heads, Tails = Value
}
we can see that the Java disassembly contains static field values
of type Enumeration$Value
:
public final class CoinFaces {
public static scala.Enumeration$Value Tails();
public static scala.Enumeration$Value Heads();
public static scala.Enumeration$ValueSet$ ValueSet();
public static scala.Enumeration$ValueOrdering$ ValueOrdering();
public static scala.Enumeration$Value withName(java.lang.String);
public static scala.Enumeration$Value apply(int);
public static int maxId();
public static scala.Enumeration$ValueSet values();
public static java.lang.String toString();
}
This means that from Java, all Scala enumerations contains cyclical references. The easiest solution to this is to annotate such fields as @transient
(https://stackoverflow.com/a/14489534/323177). Unfortunately, since we cannot annotate the generated bytecode for your custom Scala Enumeration
, the solution is to create a custom GSON serializer that manually serializes the enumeration value as a String.
import com.google.gson.JsonElement;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import scala.Enumeration;
import java.lang.reflect.Type;
// Scala enumerations are static Java classes with values of type `Enumeration.Value`
public class GsonScalaEnumerationSerializer implements JsonSerializer<Enumeration.Value> {
@Override
public JsonElement serialize(final Enumeration.Value enumValue,
final Type typeOfEnum,
final JsonSerializationContext context) {
return new JsonPrimitive(enumValue.toString());
}
}
Then register this as a type adapter during construction of your Gson
object and this will then serialise the Enumeration value.
Gson gson = new GsonBuilder()
.registerTypeAdapter(Enumeration.Value.class, new GsonScalaEnumerationSerializer())
.create();