Montag, 14. März 2011

JAXB2 Primitive Fixer Plugin

Shortly we stumbled on creating a data binding with EclipseLink (Moxy). Moxy is the Eclipse JAXB implementation which can be tightly integrated into the eclipse runtime (keyword OSGI). After quite some work we came to the point were the binding was working fine. Suddenly we had to change the xml schema due to an requesst from another department. So we introduced default values for attributes with native xsd types like xs:int, xs:boolean or xs:float. Nothing you would expect to cause trouble.

Well, we were wrong! JAXB 2.x has a major problem with default values and primitive types. Its an major drawback in every implementation. It points out that the the generate Java classes have inconsistent getter for attributes with default values with primitive types.

Short example for a generated class (omited class overhead):
/** The property name for the value property. */
    public final static String PNAME_VALUE = "value";
    @XmlAttribute
    protected Integer value;
    /**
     * Gets the value of the value property.
     * @return possible object is {@link Integer }
     */
    public int getValue() {
        if (value == null) {
            return  75;
        } else {
            return value;
        }
    }
    /**
     * Sets the value of the value property.
     * @param value allowed object is {@link Integer }
     */
    public void setValue(Integer value) {
         this.value = value;
    }
As you can see, the getter returns an int while the setter expect an Integer. This will result in a not working Eclipse data binding (getter and setter do no match).

There is already an JIRA issue filed for this on the JAXB JIRA.
http://java.net/jira/browse/JAXB-733
However it won't be solved because it would destroy the backward compatibility of JAXB.

A suggestions was to create a JAXB XJC plugin that corrects this issue. So i did, you may grab a copy from
https://github.com/sweber/JAXB2-XJC-Primitive-Fixer-Plugin

The plugin searches for getter/setter pairs and if the setter expects a boxified primitive and the getter returns a primitive it will correct the getter to return the boxified primitive. Additional for boolean it will change the getter name from isXY to getXY (in respect to the Java bean notation).

To use it with maven just deploy the binary jar file to you repository and put it into your maven-jaxb2-plugin configuration like this:

    org.jvnet.jaxb2.maven2
    maven-jaxb2-plugin
    0.7.4
    
        
            
        
    
    
        true
        
            -Xfix-primitives
        
        
            
                de.sweber
                jaxb2-primitive-fixer-plugin
                1.0.0-SNAPSHOT
            
        
    

The argument you have to pass to XJC to get the plugin working is (like above used):
-Xfix-primitives

Hope i could solve a little problem with JAXB out there ;-)