The Situation
I need to support generating XML documents based on schemas that vary only slightly between each other. Specifically, the schemas that I need to support are based on industry standards that change slightly over time and vendors may make their own customized version of them.
The Problem
I was intending to use JAXB 2 (from Metro) with inheritance as a solution. I expected the package structure to end up something like this:
com.company.xml.schema.v1
com.company.xml.schema.v2
com.company.xml.schema.v2.vendorxyz
Where the classes in the v2 package would simply extend the classes in the v1 package and override as necessary. Unfortunately, that plan ended up being impossible since subclasses cannot overwrite the annotations in parent classes (see here). For example, if an attribute in a schema was renamed between versions, then the v2 element class would have to completely re-implement the element without inheriting from the v1.
So that leaves me with only two options as far as I can tell
Option 1
Create a "base" package for each schema type, annotate the element classes in that package with @XmlAccessorType(XmlAccessType.NONE), and remove all other annotations. Then, in each versioned package create classes that subclass the corresponding class in the "base" package and add all the required annotations. This solution does give me a little help in the inheritance realm, but code duplication is huge and it would be a challenge to maintain.
Option 2
Don't use JAXB. I really don't like this solution since I'd also like to work with JAX-RS/JAX-WS.
Questions
- How should I be using JAXB in order to support multiple schemas with minor variations, without a bunch of code duplication?
- Is there a different technology combination I should be looking at?
EDIT
The solution below from Blaise worked perfectly for most of our schemas which were just a minor translation of each other with generally the same data. However, we ran into a problem in cases where it made more sense to use inheritance with package names for versioning. For Example:
com.company.xml.schema.v1.ElementA
com.company.xml.schema.v2.ElementA
(where v2.ElementA extends v1.ElementA)
Using MOXy's OXM in this case stumbles across a bug and the workaround can be found here (with the solution provided by Blaise, no less!)