Thursday, October 1, 2009

Why we switched from jaxb to jibx

Here is what you will find in this post :
  • xsd to java generation using jaxb2 with an maven project example
  • java to xsd generation using jaxb2
  • jaxb2 cannot generate an xsd with documentation
  • xsd from java generation using jibx with a maven project example
  • jibx customization is easy
  • add jibx xsd generation in maven with customization
  • how to use jibx using spring oxm

XSD authored manually

Continuing on my previous post on how to integrate your own xsd to ease your plugin configuration, I will talk today on something that really bugged me for a while. Some of our xsd are pretty large; we created them using xsd authoring tool, then continued by hand. We used jaxb to produce the java code to map the xsd, but the generated code was not that great. There are some ways to tweak the xjc plugin to bend the produced code the way you like. But this was way too awkward for us.

Jaxb generates XSD from java annotations

Then we thought that it was time to use the java code and annotate it with jaxb annotation so we could produce the xsd for our users to use. You annotate with the same few annotations here and there, and after this very tedious task you can add maven-jaxb-schemagen-plugin plugin to your pom and voilà you have a fresh xsd ready for production generated directly from your classes. But something is missing, looks like the generated xsd is very small compared to the manually authored one: jaxb did not insert any documentation ! Of course I thought that I did a silly mistake, and was ready to add something like @XmlDocumentation annotations. And here starts the story: there is no way to add documentation information to schemagen !

Jaxb cannot generate an XSD with configuration

This really surprised me, because the xsd are also here to help the users when they author an xml by showing documentation while they type etc. I really searched to find a way to use the tool; I even tried to dive into the schemagen source-code to see if there would be an existing annotation not present in the documentation. By the way, let me give a big thumb down to java.net for beeing so slow ! It was hell to navigate through the documentation on a site that is that slow. Wrong path: I was stuck. But there was no way I wanted to continue maintaining both the java and the xsd !

Enter jibx

Then I looked at the alternatives to jaxb, and quickly found out jibx http://jibx.sourceforge.net/ was the tool I was looking for! Bindgen is for jibx what maven-jaxb-schemagen-plugin is for jaxb. But instead of relying on annotation, bindgen rely solely on the class attributes and on the javadocs for producing the xsd and its documentation. Here is an example :
public class XSD {
 
 /** please define your complex object */
 private ComplexObject complexObject;
 /** you are allowed to set many simple objects */
 private List simpleObject = new ArrayList();
}
public class ComplexObject {
 /**
  * only string are allowed
  */
 private String stringAttribute;
 /**
  * This should be a date
  */
 private Date dateAttribute;
 /**
  * boolean are so over
  */
 private boolean thisIsABool = false;
 /**
  * enums are much better than booleans
  */
 private MyEnum myEnum;
}
Would generate the following xsd :

  
  
    
      this is my annotated xsd
    
    
      
        
          please define your complex object
        
        
          
            
              
                only string are allowed
              
            
            
              
                enums are much better than booleans
              
              
                
                  this is a enum, you need to choose between the values
                
                
                  
                  
                  
                  
                
              
            
          
          
            
              This should be a date
            
          
          
            
              boolean are so over
            
          
        
      
      
        
          
            
              
                trivial string
              
            
          
          
            
              trivial numeric
            
          
        
      
    
  

Perfect: all the documentation is present, it is taken directly from the javadoc! But if you follow closely the xsd, the stringAttribute and myEnum are not properties, they are defined as element. An xml would look like

    my string attribute
    B

You could also see that there is no mention on required, default values etc.

Jibx customization is easier than jaxb's

Bindgen is not that magic, we have to give it hints using customization, fortunately it is pretty straightforward thanks to a good documentation along with examples.

    
        
        
    

The only major pain was to make everything work in maven, in particular:
  • The BindGen setup using the ant task maven plugin and the correct dependencies
  • maven-jibx-plugin can use only relative path for its directory configuration point.
You can download and execute a working example here.

Jibx and spring OXM

And now jibx and Spring 3.0 oxm project! Oxm will help you to have a nice hierarchy of exception that wraps your underlying xml provider so you do not have to deal with it.

JibxMarshaller marshaller = new JibxMarshaller();
marshaller.setTargetClass(XSD.class);
marshaller.afterPropertiesSet();

// write
StringWriter writer = new StringWriter();
marshaller.marshal(xsd, new StreamResult(writer));
System.out.println(writer.toString());

// load 
(XSD) marshaller.unmarshal(new StreamSource(new FileInputStream(filename))
You have a unit test ready to be executed in the sample project Have fun with jibx !

2 comments:

Ran Biron said...

Have fun patching jibx-instrumented classes. We have switched from JiBX to JAXB mainly because of that reason. JiBX instrument classes in a special post-compile step. This instrumentation must be done "all at once" and you CAN'T use file from one run with files from another run. This means you can't patch. JiBX is nicer, faster, easier to use - but this instrumentation too high a price to pay for all of this.

cyberoblivion said...

I have been trying to use JIBX because I had a lot of difficulties with JAXB not being very configurable and then still having to hand modify the generated xsd. Problem I am having with JIBX is that it doesn't appear to be able to handle maps.... This is a show stopper for me. Have you found a decent way to handle maps with JIXB?

Post a Comment