Tweaking JAXB to generate better code

02 Sep, 2009
Xebia Background Header Wave

JAXB can be a real time saver when working on a project that uses XSD to describe interfaces implemented in Java. Sometimes, however, the generated code is not up to standard. I ran into a problem that seems very common and found a very elegant solution to it on the web.

Yesterday, while working on the XML Schema for Document, I had to decide whether I would wrap collections in a surrounding element, like this:





or I would just have a sequence of <Reply>-elements directly under Document. I think the general consensus is to use wrapping elements, but I decided to base the design on another measure: What would the (Java) code look like that would be generated from the Schema by JAXB.
After configuring the maven-jaxb-plugin into the project (which was really easy and it integrated out of the box with Eclipse through M2Eclipse), the Java code was a little disappointing: For every collection I would get the following structure:
class Document {
@XmlElement(name = "Replies")
private Replies replies;
public Replies getReplies() {
return replies;
public class Replies() {
@XmlElement(name = "Reply")
private List<Reply> reply;
public List<Reply> getReply() {
return reply;
This would lead to the following usage pattern:
Document doc;

doc.getReplies().getReply().add(new Reply(…));
which is in my opinion quite awful. I would expect there to be a simple collection structure:
Document doc;

doc.getReplies().add(new Reply(…));
But whether I would use the wrapping element or not, I would still get the additional class.
There is a JAXB annotation that will help in this situation:
@XmlElementWrapper(name = "replies")
@XmlElement(name = "reply")
protected List<Reply> replies;
And this is exactly what we want, but how to tell the JAXB code generator to use that annotation?
After some googling around, I found this blog posting, that provides a solution by using a custom plugin for XJB (the JAXB code generator). Configuring this in maven was quite easy:

  1. Add the plugin jar (which was unfortunately not available from a Maven repo) to the maven-jaxb-plugin dependencies.
  2. Add an <args>-element to the plugin configuration with the -Xxew option to activate the plugin.

The final Maven configuration looks like this:
The generated code now uses a simple collection, so it looks much more usable.
One last problem is that the generated Replies class, that is now no longer used, is not removed from the code: A little clean up task that must have slipped the plugin developers mind.


Get in touch with us to learn more about the subject and related solutions

Explore related posts