mdm mdm - 6 months ago 68
Java Question

JAXB, Custom bindings, Adapter1.class and Joda-time

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:


  • being that my adapter is overriding XmlAdapter, I cannot make the methods static....how do I avoid this?

  • Can I avoid the generation of Adapter1.class altogether?? Maybe using package-level annotation XmlJavaTypeAdapters, and if so, how do I do it exactly?? (JAXB generates already a package-info.java of its own....)



Hope I made my situation clear.

Thanks

Answer

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");
    }
 }