Marshalling Immutable Types in Jaxb

Unfortunately Jaxb requires any classes it creates during unmarshalling to have a default no-arguments constructor, and some way of mutating the fields. This prevents the use of types which enforce immutability using final fields.

A way to get around this is to use the @XmlJavaTypeAdapter annotation and implement custom marshalling and unmarshalling.

For example, create a class like this:

@XmlJavaTypeAdapter(value = MyValueXmlAdapter.class)
public class MyValue
{
   private final String value;
 
   private MyValue(final String value)
   {
      this.value = value;
   }
 
   @Override
   public String toString()
   {
      return value;
   }
 
   public static MyValue valueOf(final String value)
   {
      return new MyValue(value);
   }
}

and another like this:

public class MyValueXmlAdapter extends XmlAdapter<String, MyValue>
{
   @Override
   public String marshal(final MyValue value) throws Exception
   {
      return value.toString();
   }
 
   @Override
   public MyValue unmarshal(final String value) throws Exception
   {
      return MyValue.valueOf(value);
   }
}