2010-07-29 7 views
2

J'ai une classe abstraite qui ressemble à ceci.Génération de service Web (WSDL 1.2 ou supérieur) à partir de la classe Paramétrée en Java (Apache CXF, Axe 2)

public abstract class Entity<PK extends Serializable> implements Serializable { 

    private PK id; 

    //getters and setters generated here.... 
} 

public class User extends Entity<Long> { 

    //all attributes, getters and setters are done here... 
} 

Mon service ressemble à ce

public interface EntityService { 

    public void create(Entity<? extends Serializable> entity) throws ServiceException; 
    public boolean delete(Entity<? extends Serializable> entity) throws ServiceException; 
} 

et ma mise en œuvre est en classe EntityServiceImpl.

Quand je fais une génération de services Web avec Apache CXF, je reçois l'exception suivante:

Error: java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl cannot be cast to java.lang.reflect.TypeVariable 

java.lang.RuntimeException: java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl cannot be cast to java.lang.reflect.TypeVariable 
    at org.apache.cxf.frontend.AbstractServiceFactory.createService(AbstractServiceFactory.java:41) 
    at org.apache.cxf.tools.java2wsdl.processor.JavaToWSDLProcessor.process(JavaToWSDLProcessor.java:128) 
    at org.apache.cxf.tools.java2ws.JavaToWSContainer.processWSDL(JavaToWSContainer.java:109) 
    at org.apache.cxf.tools.java2ws.JavaToWSContainer.execute(JavaToWSContainer.java:75) 
    at org.apache.cxf.tools.common.toolspec.ToolRunner.runTool(ToolRunner.java:103) 
    at org.apache.cxf.tools.common.toolspec.ToolRunner.runTool(ToolRunner.java:58) 
    at org.apache.cxf.tools.common.toolspec.ToolRunner.runTool(ToolRunner.java:40) 
    at org.apache.cxf.tools.java2ws.JavaToWS.run(JavaToWS.java:77) 
    at org.apache.cxf.tools.java2ws.JavaToWS.main(JavaToWS.java:45) 
Caused by: java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl cannot be cast to java.lang.reflect.TypeVariable 
    at org.apache.cxf.jaxb.JAXBContextInitializer.addType(JAXBContextInitializer.java:232) 
    at org.apache.cxf.jaxb.JAXBContextInitializer.addType(JAXBContextInitializer.java:211) 

Ma question:

Comment générer un service Web qui a paramétrés types ou utilise Generics?

Répondre

2

Voyant que personne n'a répondu à cette question, je vais répondre moi-même.

Avec Apache CXF, A WS généré haricots, tous les getters retournent un objet not null, ce qui signifie que si une variable est nulle, voici ce qui se passe:

public List<? extends User> getParents() { 
     if (parents == null) { 
      parents = new ArrayList<User>(); 
     } 
     return this.parents; 
    } 

Comme vous pouvez le voir, ce qui suit provoque une exception pour CXF:

  • une classe Serializable est une interface, de sorte que si j'ai une variable de type Serializable, new Serializable() ne peut pas être défini lorsque CXF génère le code source du client.
  • Tous les objets doivent implémenter un constructeur public.

L'échec des 2 principes entraîne l'exception ci-dessus.


Solution

Pour attribut private List<? extends User> parents, nous avons ajouté cela.

@XmlElements({ 
    @XmlElement(type=Man.class), 
    @XmlElement(type=Female.class), 
    @XmlElement(type=Child.class) 
}) 
private List<? extends User> parents; 

Et pour les interfaces, nous avons utilisé le XmlJavaTypeAdapter et écrit un adaptateur pour toutes les sous-classes mises en œuvre de cette interface,

par exemple

public class IntegerConstraintBaseAdapter extends XmlAdapter<IntegerConstraint, ConstraintBase<Integer>> { 

    /* (non-Javadoc) 
    * @see javax.xml.bind.annotation.adapters.XmlAdapter#marshal(java.lang.Object) 
    */ 
    @Override 
    public IntegerConstraint marshal(ConstraintBase<Integer> v) throws Exception { 
     // TODO Auto-generated method stub 
     return null; 
    } 

    /* (non-Javadoc) 
    * @see javax.xml.bind.annotation.adapters.XmlAdapter#unmarshal(java.lang.Object) 
    */ 
    @Override 
    public ConstraintBase<Integer> unmarshal(IntegerConstraint v) throws Exception { 
     // TODO Auto-generated method stub 
     return null; 
    } 
} 

Espérons que cela aide quelqu'un.

Questions connexes