[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