Serializing Java Objects

There are various ways to serialize Java Objects. This be came an issue for me in the context of the save game feature for OpenPatrician. So it was clear from the start that the output format should be XML. As The project already uses JAXB to generate some classes from XSD this seemed to be an obvious choice. Another option turned out to be XStream.

Let’s start with JAXB: For Objects to be serializeable to XML they must be properly annotated. This basically means that you have to define the mapping of any class which contains non primitive fields. With this I have run into further problems, as now the fields were annotated with the JAXB binding annotations as well as the Lombok annotations for the getter. This resulted in the generated classes to have the JAXB annotation both on the field and the getter method, which caused problems. Therefore I hat do define that the annotations are define on the fields by this class level annotation:

XmlAccessorType(XmlAccessType.FIELD)

As with any application of any complexity I also employed data types that could not be serialized only using the JAXB type bindings: e.g. Map, Multimap, DateTime. For these types a XMLAdapter had to be implemented to map the unknown type to a known type. In many cases (e.g. Map) such a known type basically is an alternative implementation of the original, so you can bang the proper annotations on it.

And finally there were the cases of the inner and anonymous classes (e.g. Runnable). Their purpose is not defined through the data but through it’s methods.  For such classes we would also require a XMLAdapter which basically converts the class to a byte array, that can then be serialized.

Another issue that cannot be solved with JAXB are references: Some objects already serialized may be referenced by other objects. It must be avoided that these objects are serialized multiple times. To achieve that, the object is serialized separatly and any reference to it is annotated with XMLTransient. This approach over means that when loading the object from XML, the references must be placed manually.

On the whole there is quite a bit of boilerplate in the form of adapters and annotations that is needed. Therefore I was looking for a more streamlined alternative: XStream

XStream can serialize all objects without an Adapter (you can provide a Converter though). Another plus is the fact that XStream can handle the references properly by serializing an object the first time and then use references to that location in the XML.

On each object however there are probably some fields that must not be serialized, e.g. Loggers, MessageBundle, … So these fields must be annotated with

@XStreamOmitField

For XStream to work with annotations the must be activated:

XStream xstream = new XStream();
xstream.setMode(XStream.XPATH_ABSOLUTE_REFERENCES);
xstream.autodetectAnnotations(true);

You can even define how the reference path should be represented in the XML.

An excellent example for XStream can be found here.

Schreibe einen Kommentar