Reputation: 89189
I have an abstract class that looks as follows.
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...
}
My Service looks like this
public interface EntityService {
public void create(Entity<? extends Serializable> entity) throws ServiceException;
public boolean delete(Entity<? extends Serializable> entity) throws ServiceException;
}
and my implementation is on class EntityServiceImpl
.
When I do a Web Service generation with Apache CXF, I get the following exception:
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)
My question:
How do I generate a Web Service that has Parametrized Types or uses Generics?
Upvotes: 2
Views: 2612
Reputation: 89189
Seeing that nobody answered this question, I'll answer this myself.
With Apache CXF, A WS generated bean, all getters return a not null
object, meaning that if a variable is null, this is what happens:
public List<? extends User> getParents() {
if (parents == null) {
parents = new ArrayList<User>();
}
return this.parents;
}
As you can see, this following causes an exception for CXF:
Serializable
, new Serializable()
cannot be defined when CXF generates client source-code.public
constructor.Failure for the 2 principles, causes the exception above.
Solution
For attribute private List<? extends User> parents
, we added this.
@XmlElements({
@XmlElement(type=Man.class),
@XmlElement(type=Female.class),
@XmlElement(type=Child.class)
})
private List<? extends User> parents;
And for interfaces, we used the XmlJavaTypeAdapter
and wrote an adapter for every implemented subclasses of that interface,
e.g.
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;
}
}
Hope this helps someone.
Upvotes: 2