I have a Java object. It has numerous fields that have references to other different kinds of Java objects and sometimes, to itself. This object can be best described as a map (or graph) with bi-directional references (or cycles). I am not authorized to analyze its structure, but in order to solve a problem, I have to serialize this graph and store it in a JSON String.
The fact that I can't really have a look at the structure of the object, using library classes is my only option (as far as I think). I have tried json-io, json-lib, google genson, gson and flexjson. But all of these libraries either get stuck and throw an exception due to the presence of a cycle or are able to return a json (only json-io does this) but with a lot of important fields skipped(the ones that are lazy-loaded, and need getters).
Question: Is there something that exists that I might be missing while testing the above listed libraries just to address my problem?
The Java object I have is really convoluted but I don't expect it to be as convoluted as objects that might be used by big websites like facebook. What are some key libraries and their specific configuration that can be used to address my problem?
I think the best option for you is Jackson Streaming API. It allows you to serailaze a POJO into json while teraversing the Object graph, thus maintaining control over the serailization process and you can detect and handle circular references and any other special cases.
EDIT: I tried to implement an example that handles circular references but i could not complete it. Here are my intermediate findings:
ObjectMapper.WriteValue(...)
results in the following Exceptioncom.fasterxml.jackson.databind.JsonMappingException: Direct self-reference leading to cycle
which means Jackson can detect cases of self referencing. The default derializer does not know how to handle this case.mapper.configure(SerializationFeature.FAIL_ON_SELF_REFERENCES, false);
when this is set, The default derializer will cause stack overflow. so we need to implement a custom serializer which detects and handles the self referencing.An example class that can have self reference:
the custom serializer
Calling:
output is
{"name":"n1","child":{"node-ref":"n1"}}