Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JAXB Marshalling and Generics

I am trying to use JAXB's introspection to marshall and unmashall some existing domain objects marked up with JAXB annotations. Most things work as expected, but I am having quite a bit of trouble getting a fairly simple class to serialize. This class is used as an @XmlElement on a number of beans and looks something like:

public class Range<E extends Comparable<E>> implements Serializable {
    protected boolean startInclusive, endInclusive;
    protected E       start, end;

    public Range(){
            startInclusive = endInclusive = true;
    }

    public boolean contains(E value){...}

    public E getEnd() {
            return end;
    }

    public void setEnd(E end) {
            this.end = end;
    }

    public boolean isEndInclusive() {
            return endInclusive;
    }

    public void setEndInclusive(boolean endInclusive) {
            this.endInclusive = endInclusive;
    }

    public E getStart() {
            return start;
    }

    public void setStart(E start) {
            this.start = start;
    }

    public boolean isStartInclusive() {
            return startInclusive;
    }

    public void setStartInclusive(boolean startInclusive) {
            this.startInclusive = startInclusive;
    }
}

I have tried to do the following, with no success, JAXB is still angry with the interface Comparable.

public class DoubleRange extends Range<Double> {}

Using both Range and DoubleRange as return types for the bean getter's yields an exception like:

java.lang.Comparable is an interface, and JAXB can't handle interfaces.
    this problem is related to the following location:
        at java.lang.Comparable
        at protected java.lang.Comparable com.controlpath.util.Range.start
        at example.util.Range
        at example.util.DoubleRange
        at public example.util.DoubleRange example.domain.SomeBean.getRange()
        at example.domain.SomeBean

I realize that in most cases List<T> and Map<T, U> only work because the JAXB specification has special provisions for those types when they are encountered on beans, but is there any way to convey what I want to the JAXB introspection engine without having to reimplement range with non-generic fields?

like image 695
Steve Skrla Avatar asked May 05 '09 20:05

Steve Skrla


1 Answers

How about

public class Range<**E extends Number**> implements Serializable { ...
  • Number is a class

  • I bet JAXB knows default marshalling/unmarshalling rules for Number

For unmarshalling to specific type, you need XmlAdapter as I described here: JAXB inheritance, unmarshal to subclass of marshaled class

like image 76
ivan_ivanovich_ivanoff Avatar answered Nov 01 '22 23:11

ivan_ivanovich_ivanoff