I have a problem with the way JAXB is generating the bound classes for an XML schema (which, for sake of precision, I cannot modify). I want to map a xsd:date type to a Joda-time LocalDate object and, reading here, here and here, I created the following DateAdapter class:
public class DateAdapter extends XmlAdapter<String,LocalDate> {
    private static DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyyMMdd");
    public LocalDate unmarshal(String v) throws Exception {
        return fmt.parseLocalDate(v);
    }
    public String marshal(LocalDate v) throws Exception {
        return v.toString("yyyyMMdd");
    }
}
And I added the following to my global binding file:
  <jaxb:globalBindings>
        <jaxb:javaType name="org.joda.time.LocalDate" xmlType="xs:date"
            parseMethod="my.classes.adapters.DateAdapter.unmarshal"
            printMethod="my.classes.adapters.DateAdapter.marshal" />
    </jaxb:globalBindings>
The problem is that, when I try to maven compile my project, it fails with the following error:
[ERROR] \My\Path\MyProject\target\generated-sources\xjc\my\classes\generated\Adapter1.java:[20,59] non-static method unmarshal(java.lang.String) cannot be referenced from a static context
[ERROR] \My\Path\MyProject\target\generated-sources\xjc\my\classes\generated\Adapter1.java:[24,59] non-static method marshal(org.joda.time.LocalDate) cannot be referenced from a static context
...and this is where things get weird. JAXB generates a class Adapter1 that contains the following:
public class Adapter1
    extends XmlAdapter<String, LocalDate>
{
    public LocalDate unmarshal(String value) {
        return (my.classes.adapters.DateAdapter.unmarshal(value));
    }
    public String marshal(LocalDate value) {
        return (my.classes.adapters.DateAdapter.marshal(value));
    }
}
....which is the source of the compilation error.
Now, my questions are:
Hope I made my situation clear.
Thanks
I was in a WSDL first context: no java at all, just generate a CXF Client from a provided WSDL.
I was stuck with the ugly Adapter1.java for a long time, but I found the solution there.
You will use a custom XMLAdapter like already explained.
The key of this problem was adding the xjc extension to the global binding file:
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" 
 xmlns:xs="http://www.w3.org/2001/XMLSchema" 
 xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
 jaxb:extensionBindingPrefixes="xjc" jaxb:version="2.1">
    <jaxb:globalBindings>
       <xjc:javaType adapter="com.xxx.tools.xjc.DateAdapter" 
        name="java.util.Date" xmlType="xs:dateTime" />
    </jaxb:globalBindings>
</jaxb:bindings>
xjc extension allow the usage of xjc:javaType that accept adapter parameter. No more static method required !
Note this seems to work with jaxb 2.1+ only.
You do not need to extend XmlAdapter.
Just create static methods on a POJO and it will work.
Example:
 public class DateAdapter {
    private static DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyyMMdd");
    public static LocalDate unmarshal(String v) throws Exception {
        return fmt.parseLocalDate(v);
    }
    public static String marshal(LocalDate v) throws Exception {
        return v.toString("yyyyMMdd");
    }
 }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With