tags:

views:

483

answers:

1

I've build the following case. An interface for all JAXBLists:

public interface JaxbList<T> {
public abstract List<T> getList();
}

And an base implementation:

@XmlRootElement(name="list")
public class JaxbBaseList<T> implements JaxbList<T>{
    protected List<T> list;

    public JaxbBaseList(){}

    public JaxbBaseList(List<T> list){
        this.list=list;
    }

    @XmlElement(name="item" )
    public List<T> getList(){
        return list;
    }
}

As well as an implementation for a list of URIs:

@XmlRootElement(name="uris")
public class JaxbUriList2 extends JaxbBaseList<String> {

    public JaxbUriList2() { super();    }
    public JaxbUriList2(List<String> list){
        super(list);
    }


    @Override
    @XmlElement(name="uri")
    public List<String> getList() {
        return list;
    }
}

And I'm using the List in the following way:

public JaxbList<String> init(@QueryParam("amount") int amount){

        List<String> entityList = new Vector<String>();
        ...
        enityList.add("http://uri");
    ...
        return new JaxbUriList2(entityList);
    }

I thought the output should be:

<uris>
<uri>
http://uri
</uri>
...
</uris>

But it is something like this:

<uris>
<item xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:string">
http://uri
</item>
...
<uri>
http://uri
</uri>
...
</uris>

I think it has something to do with the inheritance, but I don't get it...

What's the problem? - How can I fix it?

Thanks in advance!

+2  A: 

Annotations are obtained through reflection. The annotation is bound to the type it's defined in.

public class AnnotationTest {

    public static class A
    {
        @XmlElement(name="item")
        public void doIt() { }
    }

    public static class B extends A
    {
        @XmlElement(name="name")
        public void doIt() { }
    }

    public static void main(String[] args)
    {
        B b = new B();
        Method m = b.getClass().getMethods()[0];
        Annotation[] ann =  m.getDeclaredAnnotations();
        System.out.println( ann.length  );  // prints 1
    }
}

So this behavior is not due to the reflection mechanism itself. It seems like the JAXB framework does explicitly list the annotation on the method in the class and the super classes. Surprisingly this still works, but not as you would like.

Can't you just remove @XmlElement(name="item") in the base class?

EDIT

According to your comment (but still not sure if I understand all correctly), I would suggest:

@XmlRootElement(name="list")
public class JaxbBaseList<T> implements JaxbList<T>{
    protected List<T> list;

    public List<T> getList(){
        return list;
    }
}


public class JaxbPrimitiveList<T> extends JaxbList<T>{
    protected List<T> list;

    @XmlElement( name="item" )
    public List<T> getList(){
        return list;
    }
}

@XmlSeeAlso( Uri )
public class JaxbUriList<Uri> extends JaxbList<Uri>{
    protected List<Uri> list;

    @XmlElement( name="uri" )
    public List<Uri> getList(){
        return list;
    }
}
ewernli
The problem is, that the JaxbBaseList should be used for language types as Long, Integer, String, etc. and that the other implementation should be used for other types. So JaxbUriList2 is just a missleading example, better I had used URI instead of String. then we need the @XmlSeeAlso annotation.So I need both classes as they are. The JaxbBaseList for the language types and all other for implementations with the @XmlSeeAlso annotation, i.e.:"@XmlSeeAlso(URI.class) public class JaxbUriList extends JaxbBaseList<URI>".
gerry
Regarding to your EDIT. Okay, that works. BUT JaxbBaseList<T> and JaxbPrimitiveList<T> are the same, except of the @XmlElement( name="item" ) only in the JaxbPrimitiveList. That doesn't follows the DRY concepts. Yeah, well, not the JaxbUriList<Uri> either; but there is no solution I can think of.To repeat, my question is "Why the name of the @XmlRootElement(name="list") annotation is overridden but not the @XmlElement( name="item" )? And why is the list added two times: one time as 'item' and one time as 'uri' ?"
gerry
I know it's not really an answer to your initial question. I was just trying to figure out myself whether it was the reflection mechanism or JAXB that were faulty. Regarding your question, that's how JAXB is implemented and I fear the answer is hence something like "because it's like this". But maybe somebody will come with a more convincing answer explaining the rationale and/or inconsistencies of the JAXB implementation.
ewernli