• Home
  • RSS Feed
  • Log in

Maarten Winkels

Tweaking JAXB to generate better code
Posted by Maarten Winkels in the late evening: September 2nd, 2009

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:

<Document>
...
  <Replies>
    <Reply>
      ...
    </Reply>
    <Reply>
      ...
    </Reply>
    ...
  </Replies>
  ...
</Document>

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:

<plugin>
  <groupId>com.sun.tools.xjc.maven2</groupId>
  <artifactId>maven-jaxb-plugin</artifactId>
  <executions>
    <execution>
      <id>jaxb-generate</id>
      <goals>
        <goal>generate</goal>
      </goals>
    </execution>
  </executions>
  <configuration>
    <includeSchemas>
      <includeSchema>xsd/Document.xsd</includeSchema>
    </includeSchemas>
    <strict>true</strict>
    <verbose>true</verbose>
    <args>-Xxew</args>
  </configuration>
  <dependencies>
    <dependency>
      <groupId>xew</groupId>
      <artifactId>xew</artifactId>
      <version>1.0.0</version>
      <scope>runtime</scope>
    </dependency>
  </dependencies>
</plugin>

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.

Share

Tags: jaxb, Maven, xjb plugin, XmlElementWrapper
Filed under General | 3 Comments »



3 Responses to “Tweaking JAXB to generate better code”



    Tzach Says:
    Posted at: September 6, 2009 at 12:30 pm

    Nice, but is there a way to annotate the XSD to create the deride code?

    Reply


    Bjarne Hansen Says:
    Posted at: September 14, 2009 at 12:36 pm

    Use the -delete option to have modified candidates removed from the final code.

    Reply


    AM Says:
    Posted at: October 5, 2009 at 10:48 pm

    Nice, but is there a way to annotate the XSD to create the deride code?

    Reply


Leave a Reply

Click here to cancel reply.


Xebia Sites

  • Xebia Corporate
  • Xebia France
  • Xebia India
  • Xebia Sweden

Categories

  • Java (311)
  • Agile (181)
  • General (136)
  • Scrum (67)
  • Architecture (64)
  • Testing (59)
  • Performance (46)
  • Middleware (56)
    • Deployment (38)
  • Xebia Labs (39)
  • SOA (31)
  • Podcast (31)
  • Project Management (28)
  • Tools (26)
  • Uncategorized (20)
  • lean architecture (20)
  • Quality Assurance (17)
  • Articles (13)
  • Requirements Management (13)
  • Virtualization (19)

Tag Cloud

    Maven TDD Oracle Moving to India Eclipse ACT lean architectuur Agile Flex Hibernate Spring Frameworks Lean Scrum Grails Concurrency Control Xebia XML Groovy Java Architecture product owner Scala lean architecture agile architectuur SOA JPA implementation patterns Ajax JPA Javascript

Archives

  • February 2012
  • January 2012
  • December 2011
  • November 2011
  • October 2011
  • September 2011
  • August 2011
  • July 2011
  • June 2011
  • May 2011
  • April 2011
  • March 2011
Avatars by Sterling Adventures