Thursday, October 2, 2008

Axis2 wsdl2java - Generate Better Code with -uw

This is a question asked regularly on the axis-user list. "Code generated by the wsdl2java tool is hard to use. Is there any better way that I can generate code?".

The answer to this is that you could actually use wsdl2java to generate better code. Lets take an example scenario. For this I will be using a Service that I have deployed on Mooshup.com. This simple service has a operation called demo which accepts three parameters (firstParam, secondParam and thirdParam). I will be using the wsdl of this service for explanation. Lets first try to use wsdl2java on this wsdl and see what happens and how -uw can help.

If i was to generate a stub for this using the following command,
  1. sh wsdl2java.sh -uri http://mooshup.com/services/keith/DemoService?wsdl -o /home/keith/projects/demo  

I would have to use this stub as follows,
  1. DemoServiceStub stub = new DemoServiceStub();  
  2. DemoServiceStub.Demo demo = new DemoServiceStub.Demo();  
  3. DemoServiceStub.DemoType demoType = new DemoServiceStub.DemoType();  
  4. demo.setDemo(demoType);  
  5. demoType.setFirstParam("firstParam");  
  6. demoType.setSecondParam(10.0);  
  7. demoType.setThirdParam(true);  
  8. stub.demo(demo);  

Now this does not look too elegant, but if I were to generate code using the -uw option with the following command,
  1. sh wsdl2java.sh -uri http://mooshup.com/services/keith/DemoService?wsdl -o /home/keith/projects/demo -uw  

I would be able to use the stub as,
  1. DemoServiceStub stub = new DemoServiceStub();  
  2. stub.demo("firstParam"20.0true);  

Now what is more elegant and easier? Its a easy answer.

The secret to this lies in the schema. You wont be able to generate easy to use stubs such as this all the time. What gets unwrapped (when -uw is used) is the sequence within the complex type. In our case the schema was as follows,

  1. <xs:complexType name="demoType">  
  2.   
  3.    <xs:sequence>  
  4.   
  5.        <xs:element name="firstParam" type="xs:string" />  
  6.   
  7.        <xs:element name="secondParam" type="xs:double" />  
  8.   
  9.        <xs:element name="thirdParam" type="xs:boolean" />  
  10.   
  11.    </xs:sequence>  
  12.   
  13. </xs:complexType>  
  14.   
  15. <xs:element name="demo" type="ws:demoType" />  



So the bottom line is use the -uw option when generating code with wsdl2java, this would generate code that is easy to use. (This should have been the default in wsdl2java ;))

Most users are not aware of the set of options that wsdl2java offer (Will cover that in another post).

5 comments:

Yaron Naveh (MVP) said...

I think that when the part name in the WSDL is "parameters" then by convention it is doc/lit/wrapped. Maybe the flag can be implicitly added in such cases?

Keith Chapman said...

Yes it will be good default it such a manner, but as for now you got to use -uw explicitly. The default is to generated wrapped types.

Unknown said...

This was exactly was I was looking for! I'm primarily a .NET programmer, and using WCF I am used to the way that Visual Studio wraps up their classes. I started working with Axis2 and found the wsdl2java tool to be very obscure in its class generation. I started looking for a different tool altogether to make the java web service proxy code more like the .NET WCF code. Instead, your method does exactly what I need. Thanks!

Unknown said...

Thanks, great post.

One question :
I faced some ridiculous situation when I used -uw options.

I'm working on SugarCRM. When I create stubs using -u -d xmlbeans, everything's proper.

But, when I create stubs using -uw -d xmlbeans, all the basic methods in the stub are missing return type.
Even the login() returns void, which is supposed to return some holder of sessionId.

'-uw' does not work for xmlbeans databinding?

mayankbiyani said...

hi

I am trying to generate stub via ADB method. But when i am running build.xml it is giving me following error.

gen_wsdl_stub:
[axis2-wsdl2java] Retrieving document at '{env.CCWSCA}/scripts/src/collections.wsdl'.
[axis2-wsdl2java] log4j:WARN No appenders could be found for logger (org.apache.axis2.i18n.ProjectResourceBundle).
[axis2-wsdl2java] log4j:WARN Please initialize the log4j system properly.

BUILD FAILED
/comabpusers/com/aim/mayankbi/bb/ccl9e/v77_5/build.xml:176: org.apache.axis2.wsdl.codegen.CodeGenerationException: Error parsing WSDL


No more specific error is being followed.