JAXB - Java Architecture for XML Binding

JAXB

Published: Saturday, 20 January 2007

What is JAXB used for

JAXB is an XML to Java serializer / deserializer for web services. Alternatives to this include XMLBeans

Creating Java from XML

Use xjc from the bin directory. It will call com.sun.tools.xjc.XJCFacade.main via an ant task or maven plugin.

xjb - binding file

You may need to use a xjb binding file if the auto generated classes aren’t suitable.

See customizing jaxb bindings for further info. It is better to map all elements manually using the mapping file, as the autogenerate option may give different class names on different build environments.

xjb - mapping examples

Rename the default class name to avoid clashes.

  <jaxb:bindings schemaLocation="security.xsd">
    <jaxb:bindings node="//xs:complexType[@name='Security']">
      <jaxb:class name="Security2"/>
    </jaxb:bindings>
  </jaxb:bindings>

Enums have to be mapped differently using typesafeEnumClass.

If you have clashes in the ObjectFactory you can use factoryMethod.

  <jaxb:bindings schemaLocation="model.xsd">
    <jaxb:bindings node="//xs:element[@name='Phone']">
      <jaxb:factoryMethod name="Phone2"/>
    </jaxb:bindings>
    <jaxb:bindings node="//xs:simpleType[@name='Enum_WeightUnit']">
      <jaxb:typesafeEnumClass name="EnumWeightUnit2"/>
    </jaxb:bindings>
  </jaxb:bindings>

Troubleshooting

xjc created duplicate classes and won’t compile

This happens if the xsd has nested elements of the same name.

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns="http://magicmonster.com/test/duplicates" xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="qualified">
  <xs:element name="ErrorTest">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="ErrorTest">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="Hello"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

produces

..
@XmlRootElement(name = "ErrorTest")
public class ErrorTest {
..
..
    public static class ErrorTest {
..

The above does not compile due to ‘Duplicate Class: ErrorTest’. Static inner classes can’t have the same name as the parent class. One solution is to create an xjb mapping to tell xjc how to transform the elements. You can control many things, including the Java class names.

<jxb:bindings version="1.0" xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
              xmlns:xs="http://www.w3.org/2001/XMLSchema"
              xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_1_0.xsd">
  <jxb:bindings schemaLocation="example.xsd"
                node="//xs:element[@name='ErrorTest']//xs:element[@name='ErrorTest']/xs:complexType">
    <jxb:class name="ErrorTestXXX"/>
  </jxb:bindings>
</jxb:bindings>