I am working in an application where we need to save objects in XML format, and load them later once required. For this I have used JAXB to marshall and unmarshall XMLs back to Java classes.
My problem is that the I have to change Java models sometime (by adding, renaming or deleting attributes), as a result, I will have incompatible saved XMLs which can’t be bound back to the new class form.
To solve this, every time I have to do a change I take a copy of all the classes under a new package (named after its version) and apply the requested changes. And when saving an XML I save its version so that I can decide which package should be scanned by JAXB to unmarshall this XML.
My question is, Is there any other way to implement backward and forward compatibility using JAXB? If not is there any other technology that can support this?
If you only add new attributes it can still work: it's called "duck typing". Your object is free it ignore extra stuff that it doesn't.
You only have to worry about versioning if you modify or remove attributes that are required. Unfortunately, this is the case with database schemas, Java serialization, and any other persistence technology. XML isn't magic; it's not immune.
Note: I am a member of the JAXB 2 (JSR-222) expert group and lead EclipseLink JAXB (MOXy).
For this use case I prefer to use a single model when possible. This will require that you have multiple mappings for your object model. The JAXB spec does not provide a means to do this, but it can be done using MOXy's externalized metadata extension:
The metadata can be used to supplement the annotations, or used to replace them. So I would recommend mapping your base schema with annotations and using the XML format to modify the metadata per version of the schema.
Deleting a Java attribute (field/property) makes things difficult since there will be nothing for the old XML to map to. Instead you can leave them in your model, and mark them "@XmlTransient" in the XML metadata files.