[jboss-user] [JBossWS] - Re: Problem with inheritance and JBossWS
hannes.koller
do-not-reply at jboss.com
Fri Jun 22 05:07:48 EDT 2007
Ok I have managed to create a simple example of the behavior. Please note that I am pretty new to webservices and JBossWS (started using it a few days ago) so sorry if something is overly complicated. Feedback is highly appreciated.
I am using JBoss 4.2.0.GA and java version "1.5.0_08"
I started with the following WSDL (I have modified an echo tutorial I found on the web so please dont be confused by the namespace and other irregularities):
| <?xml version="1.0" encoding="UTF-8"?>
| <definitions name='EchoService' targetNamespace='http://echo/'
| xmlns='http://schemas.xmlsoap.org/wsdl/'
| xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/'
| xmlns:tns='http://echo/'
| xmlns:xsd='http://www.w3.org/2001/XMLSchema'>
| <types>
| <xs:schema targetNamespace='http://echo/' version='1.0'
| xmlns:tns='http://echo/'
| xmlns:xs='http://www.w3.org/2001/XMLSchema'>
|
| <xs:complexType name='Something'>
| <xs:sequence>
| <xs:element minOccurs='0' name='arg0' type='xs:string' />
| </xs:sequence>
| </xs:complexType>
|
| <xs:complexType name='A'>
| <xs:sequence>
| <xs:element minOccurs='0' name='arg0' type='xs:string' />
| </xs:sequence>
| </xs:complexType>
|
| <xs:complexType name='B'>
| <xs:complexContent>
| <xs:extension base="tns:A">
| <xs:sequence>
| <xs:element minOccurs='0' name='arg1' type='xs:string' />
| </xs:sequence>
| </xs:extension>
| </xs:complexContent>
| </xs:complexType>
| <xs:complexType name='C'>
| <xs:complexContent>
| <xs:extension base="tns:B">
| <xs:sequence>
| <xs:element minOccurs='0' name='arg2' type='xs:string' />
| </xs:sequence>
| </xs:extension>
| </xs:complexContent>
| </xs:complexType>
|
| <xs:complexType name="BResponse">
| <xs:sequence>
| <xs:element name="something" type="tns:Something" minOccurs="1" maxOccurs="1" nillable="true"/>
| <xs:element name="b" type="tns:B" minOccurs="1" maxOccurs="1" nillable="true"/>
| </xs:sequence>
| </xs:complexType>
|
| <xs:element name="bResponse" type="tns:BResponse"/>
| <xs:element name="something" type="tns:Something"/>
| </xs:schema>
| </types>
|
| <message name='GetB_Request' />
|
| <message name='GetB_GetBResponse'>
| <part name='para' element="tns:bResponse"/>
| </message>
|
| <portType name='GetB'>
| <operation name='getB' >
| <input message='tns:GetB_Request'/>
| <output message='tns:GetB_GetBResponse' />
| </operation>
| </portType>
| <binding name='GetBBinding' type='tns:GetB'>
| <soap:binding style='document' transport='http://schemas.xmlsoap.org/soap/http' />
| <operation name='getB'>
| <soap:operation soapAction='' />
| <input>
| <soap:body use='literal' />
| </input>
| <output>
| <soap:body use='literal' />
| </output>
| </operation>
| </binding>
| <service name='GetBService'>
| <port binding='tns:GetBBinding' name='GetBPort'>
| <soap:address location='REPLACE_WITH_ACTUAL_URL' />
| </port>
| </service>
| </definitions>
|
We have an A->B->C Class Hierarchy here, and a BResponse Complex Type which consists of a "B" and a "Something". Note the "minOccurs=1 maxOccurs=1 nillable=true " . If I throw the file at wsconsume it creates a number of classes. The BResponse Class looks like this:
| @XmlAccessorType(XmlAccessType.FIELD)
| @XmlType(name = "BResponse", propOrder = {
| "something",
| "b"
| })
| public class BResponse {
|
| @XmlElement(required = true, nillable = true)
| protected Something something;
| @XmlElement(required = true, nillable = true)
| protected B b;
| ....}
|
I have written a very simple Server:
| @javax.jws.WebService(endpointInterface="echo.GetB", serviceName="GetBService", targetNamespace="http://echo/", portName="GetBPort" )
| public class DummyGetB implements GetB {
|
| public BResponse getB() {
|
| BResponse response = new BResponse();
|
| C c = new C();
| c.setArg0("1");
| c.setArg1("2");
| c.setArg2("3");
|
| response.setB(c);
|
| return response;
| }
|
| }
|
and a Client:
| public class Client {
|
| public static void main(String[] args) throws Exception {
| GetBService getB = new GetBService(new URL("http://127.0.0.1:8080/server?wsdl"),new QName("http://echo/", "GetBService"));
|
| GetB getBPort = getB.getGetBPort();
| BResponse bResponse = getBPort.getB();
|
| System.out.println(bResponse.getB().getClass());
| B b = bResponse.getB();
| System.out.println(b.getArg0());
| System.out.println(b.getArg1());
| C c = (C)bResponse.getB();
| System.out.println(c.getArg2());
| }
|
If I try this example I get:
| class echo.B
| 1
| 2
| Exception in thread "main" java.lang.ClassCastException: echo.B
| at at.ac.arsenal.Client.main(Client.java:53)
|
Only a "B" gets transmitted, although it should be a "C"
Now, to get the behavior I was talking about change the minOccurrs parameter of something element of BResponse to 0:
| ..............
| <xs:complexType name="BResponse">
| <xs:sequence>
| <xs:element name="something" type="tns:Something" minOccurs="0" maxOccurs="1" nillable="true"/>
| <xs:element name="b" type="tns:B" minOccurs="1" maxOccurs="1" nillable="true"/>
| </xs:sequence>
| </xs:complexType>
| ................
|
Then rerun wsconsume. The generated BResponse class now looks like this. Notice the JAXBElement type of variable something;
| @XmlAccessorType(XmlAccessType.FIELD)
| @XmlType(name = "BResponse", propOrder = {
| "something",
| "b"
| })
| public class BResponse {
|
| @XmlElementRef(name = "something", type = JAXBElement.class)
| protected JAXBElement<Something> something;
| @XmlElement(required = true, nillable = true)
| protected B b;
|
I Recompile and Redeploy the server then rerun the Client. The output is now:
| class echo.C
| 1
| 2
| 3
|
now C gets transmitted and the arg2 property has the correct value.
As I said before this is of course no solution to the original problem, but I think it might be useful in tracking down the source of it.
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4056777#4056777
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4056777
More information about the jboss-user
mailing list