Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java.util.List is an interface, and JAXB can't handle interfaces

I seemed to get the following exception when trying to deploy my application:

Caused by: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 2 counts of     IllegalAnnotationExceptions java.util.List is an interface, and JAXB can't handle interfaces. this problem is related to the following location:     at java.util.List     at private java.util.List     foobar.alkohol.register.webservice.jaxws.GetRelationsFromPersonResponse._return     at     foobar.alkohol.register.webservice.jaxws.GetRelationsFromPersonResponse java.util.List does not have a no-arg default constructor.     this problem is related to the following location:         at java.util.List         at private java.util.List foobar.alkohol.register.webservice.jaxws.GetRelationsFromPersonResponse._return     at     foobar.alkohol.register.webservice.jaxws.GetRelationsFromPersonResponse 


My code worked just well until I changed the return type from List to List<List<RelationCanonical>>

Here is the partial webservice:

 @Name("relationService") @Stateless @WebService(name = "RelationService", serviceName = "RelationService") @SOAPBinding(style = SOAPBinding.Style.DOCUMENT, use = SOAPBinding.Use.LITERAL, parameterStyle = SOAPBinding.ParameterStyle.WRAPPED) public class RelationService implements RelationServiceLocal {      private boolean login(String username, String password) {         Identity.instance().setUsername(username);         Identity.instance().setPassword(password);         Identity.instance().login();         return Identity.instance().isLoggedIn();     }      private boolean logout() {         Identity.instance().logout();         return !Identity.instance().isLoggedIn();     }      @WebMethod     public List<List<RelationCanonical>> getRelationsFromPerson(@WebParam(name = "username")     String username, @WebParam(name = "password")     String password, @WebParam(name = "foedselsnummer")     String... foedselsnummer) {  ...... ...... ...... } 


I have also tried by removing the @SOAPBinding and trying default, but the same result occurs. Appreciate any help

UPDATE

I want to note out something. I changed all List to ArrayList, and then it compiled. The reason why I say compiled and not worked is because it behaves strange. I get an Object of type: RelationServiceStub.ArrayList but the object has no get methods or does not behave as a List either. I also tried to cast it to a List but that didnt work.

Note that this is after I have used Axis 2 and wsdl2java So yes, now it compiles, but I dont know how to get the data out.

like image 534
Shervin Asgari Avatar asked Nov 18 '08 13:11

Shervin Asgari


2 Answers

In my understanding, you will not be able to process a plain List via JAXB, as JAXB has no idea how to transform that into XML.

Instead, you will need to define a JAXB type which holds a List<RelationCanonical> (I'll call it Type1), and another one to hold a list of those types, in turn (as you're dealing with a List<List<...>>; I'll call this type Type2).

The result could then be an XML ouput like this:

<Type2 ...>     <Type1 ...>         <RelationCanonical ...> ... </RelationCanonical>         <RelationCanonical ...> ... </RelationCanonical>         ...     </Type1>     <Type1>         <RelationCanonical ...> ... </RelationCanonical>         <RelationCanonical ...> ... </RelationCanonical>         ...     </Type1>     ... </Type2> 

Without the two enclosing JAXB-annotated types, the JAXB processor has no idea what markup to generate, and thus fails.

--Edit:

What I mean should look somewhat like this:

@XmlType public class Type1{      private List<RelationCanonical> relations;      @XmlElement     public List<RelationCanonical> getRelations(){         return this.relations;     }      public void setRelations(List<RelationCanonical> relations){         this.relations = relations;     } } 

and

@XmlRootElement public class Type2{      private List<Type1> type1s;      @XmlElement     public List<Type1> getType1s(){         return this.type1s;     }      public void setType1s(List<Type1> type1s){         this.type1s= type1s;     } } 

You should also check out the JAXB section in the J5EE tutorial and the Unofficial JAXB Guide.

like image 152
Henning Avatar answered Sep 18 '22 12:09

Henning


If that suits your purpose you can always define an array like this:

YourType[] 

JAXB can certainly figure out what that is and you should be able to immediatly use it client side. I would also recommend you to do it that way, since you should not be able to modify the array retrieved from a server via a List but via methods provided by the web service

like image 34
Argo Avatar answered Sep 16 '22 12:09

Argo