Problem using inheritance in Webservice value types
grp_eee Jan 4, 2006 4:33 PMHi,
We are using JBoss 4.0.3 for our webservice implementation.
We want to expose a generic interface which can take a valuetype or any of its subtypes as parameters.
My Service Interface looks like this
public interface PolicyWS extends java.rmi.Remote { public Policy createPolicy(Policy policy) throws java.rmi.RemoteException; }
Here the createPolicy method can take any valuetype of type Policy as its parameter
Policy and its subclasses looks like this:
public abstract class Policy { private String policytype; private String name; .......getters and setters } public class AVPolicy extends Policy implements Serializable { private Integer avpolicyid; .......getters and setters } public class BackupPolicy extends Policy implements Serializable { private Integer backuppolicyid; .......getters and setters }
We use extension mechanism in our wsdl to expose this interface
WSDL looks like:
<?xml version="1.0" encoding="UTF-8"?> <definitions name="PolicyWebservice" targetNamespace="http://sample/prd/r1" xmlns:tns="http://sample/prd/r1" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:ns2="http://sample/prd/r1/types" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"> <types> <schema targetNamespace="http://sample/prd/r1/types" xmlns:tns="http://sample/prd/r1/types" xmlns:soap11-enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://www.w3.org/2001/XMLSchema"> <complexType name="createPolicy"> <sequence> <element name="Policy_1" type="tns:Policy" nillable="true"/></sequence></complexType> <complexType name="BackupPolicy"> <complexContent> <extension base="tns:Policy"> <sequence> <element name="backuppolicyid" type="int" nillable="true"/> </sequence></extension></complexContent></complexType> <complexType name="AVPolicy"> <complexContent> <extension base="tns:Policy"> <sequence> <element name="avpolicyid" type="int" nillable="true"/> </sequence></extension></complexContent></complexType> <complexType name="Policy"> <sequence> <element name="name" type="string" nillable="true"/> <element name="policytype" type="string" nillable="true"/></sequence></complexType> <complexType name="createPolicyResponse"> <sequence> <element name="result" type="tns:Policy" nillable="true"/></sequence></complexType> <element name="createPolicy" type="tns:createPolicy"/> <element name="createPolicyResponse" type="tns:createPolicyResponse"/></schema></types> <message name="PolicyWS_createPolicy"> <part name="parameters" element="ns2:createPolicy"/></message> <message name="PolicyWS_createPolicyResponse"> <part name="result" element="ns2:createPolicyResponse"/></message> <portType name="PolicyWS"> <operation name="createPolicy"> <input message="tns:PolicyWS_createPolicy"/> <output message="tns:PolicyWS_createPolicyResponse"/></operation></portType> <binding name="PolicyWSBinding" type="tns:PolicyWS"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/> <operation name="createPolicy"> <soap:operation soapAction=""/> <input> <soap:body use="literal"/></input> <output> <soap:body use="literal"/></output></operation></binding> <service name="PolicyWebservice"> <port name="PolicyWSPort" binding="tns:PolicyWSBinding"> <soap:address location="REPLACE_WITH_ACTUAL_URL"/></port></service></definitions>
When we try to invoke this service passing a parameter of type BackupPolicy the request works fine( i.e it converts to the proper subtype on the server side). But when i return the BackupPolicy instance , I get a ClassCastException.
When i had a look at the SOAP request and response, I found that the request is encoded with the value type whereas the response is not.That is why the client is unable to instantiate the proper value type.
SOAP Request XML
<?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Body> <createPolicy xmlns="http://sample/prd/r1/types"> <Policy_1 xsi:type="ns1:BackupPolicy" xmlns:ns1="http://sample/prd/r1/types" xmlns=""> <name xsi:nil="true"/> <policytype>backup</policytype> <backuppolicyid>1</backuppolicyid> </Policy_1> </createPolicy> </soapenv:Body> </soapenv:Envelope>
SOAP Response XML
<?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Body> <ns1:createPolicyResponse xmlns:ns1="http://sample/prd/r1/types"> <result> <name>backup</name> <policytype xsi:nil="1"/> <backuppolicyid xsi:nil="1"/> </result> </ns1:createPolicyResponse> </soapenv:Body> </soapenv:Envelope>
My client snippet
PolicyWebserviceLocator loc = new PolicyWebserviceLocator(); PolicyWS policyws = loc.getPolicyWSPort(); BackupPolicy policy = new BackupPolicy(); policy.setBackuppolicyid(1); policy.setPolicytype("backup"); BackupPolicy bp = (BackupPolicy)policyws.createPolicy(policy); //ClassCastException bp.getBackuppolicyid();
Is this an issue with JBoss ? Please provide me any pointers on this.
Thanks in advance
-Ram