Adapters in JAXB
Java XML Binding (aka JAXB) is part of many applications since it provides a convenient API to marshall/unmarshall Java to/from XML.
Like so many area, the devil is in the detail, like when one has to unmarshall a JAXB-incompatible class. Such classes come across one’s code for a variety of reasons: design, legacy, third-party… Suffice to say that such a sand grain can be a blocker for any project.
Luckily, JAXB designers must have had this use-case in mind when they crafted their API, because an adapter is provided to bypass such problems. In this case, a JAXB-compatible class is made available and JAXB bridges between it and the incompatible one. This is easily done through the use of the XmlJavaTypeAdapter annotation: it accepts a class parameter which bridges between the JAXB-friendly and -unfriendly worlds. In other words, it must implement the XmlAdapter<OriginalType, CompatibleType> contract. The annotation can then be put on the field which is of incompatible type.
This is all well, and many resources on the web tells how to do it. Alas, most examples stay on the safe side and completely forget to address the following:
- My class to be marshalled (and back) has a field of type A
- Type A has an associations of type B, which in turn has an association of type C, etc
- All of these types are third-party
- Type A through Y are JAXB-compatible, type Z is not
Now things get interesting… Creating the adapter for type A is out of the question, since I would have to create the structure for the whole tree, which would be a huge time sink.
The solution I’ve found so far is to create a package-info.java in the third-party package and annotate it with my adapter. It’s not clean in that it may come in conflict with the real package-info (i.e. the one coming from the third-party library), but it was not the case for me (none was provided). Btw, I’m amazed how few providers are creating this object in their library.
Anyone having faced this problem and found a more elegant solution?