Tuesday, May 26, 2009

Using Axis WSDL2Java ant task to develop web service client


In my previous post Developing web service client using WebSphere WSDL2Java ant task we have seen how to use WebSphere wsdl2java ant task to develop web service clients. In this post, let us examine how to generate client side java artifacts using Axis wsdl2java ant task and code a simple web service client.
To run axis wsdl2java, all we need is Apache Axis(JAX-RPC compliant web service engine) installed. We also need Apache Xerces2 (XML parser) installed for running the client. I have Axis v1.4 and Xerces 2.9.1 installed in my system.
I have deployed a tiny sample Web Service 'ServiceA' in a application server running locally for this purpose. We will use the WSDL of this web service to generate stubs. I have defined an simple request/response operation 'createUser' in this.
Following is how I used wsdl2java in this example, in it's simplest way.
<axis-wsdl2java
output="${src-gen.dir}"
verbose="true"
url="${wsdl}"/>
</target>
The generated java files will be placed under folder represented by the output attribute. In my case I have assigned property 'src-gen.dir', which points the folder named src-gen under basedir. Attribute 'url' represents the WSDL on which we are running wsdl2java. It can be URL (like http://host:port/.../ServiceA.wsdl) or the path to the WSDL file in local file system. In this example, I have placed the WSDL file directly under the basedir, so the value of wsdl ant property is just 'ServiceA.wsdl'. Even though we can use the wsdl's URL in wsdl ant task, it becomes little tricky when the WSDL URL is HTTPS (URL with HTTPS protocol, like https://host:port/.../ServiceA.wsdl). In one of my previous post Running Axis WSDL2Java on HTTPS WSDL I have posted some info I had collected about this. If we are generating the client code frequently, it's better to use the WSDL URL to generate client code reflecting changes in web service, which is the ideal way. Otherwise it is better to copy the WSDL to local file system and run wsdl2java.
WSDL2Java ant task has many more advanced options, for example, mapping namespace to a package structure of your choice (by default package structure is derived from namespace), so that the generated classes arranged in this package structure, like given below. Please read more by going through Axis documentations.
<axis-wsdl2java
output="${src-gen.dir}"
verbose="true"
url="${wsdl}" >
<mapping
namespace="http://servicea.test.ws.ibswings.com"
package="com.ibswings.ws.test" />
</axis-wsdl2java>
In my example ant build script, I have called wsdl2java from a target viz. gen. Before we call wsdl2java, we need to provide ant with task definition for this, unless the jar containing these classes are placed under ant's lib folder, to be loaded while starting up. I have loaded the ant tasks like given below.
<taskdef resource="axis-tasks.properties" classpathref="axis.classpath" />
Classpath reference 'axis.classpath' loads all the required jars from the lib direct of Axis installation folder, for loading wsdl2java ant task. Axis is installed under C:\Dev\Installed\axis-1_4 in my computer, and an ant property 'axis.home' points to this folder.
<path id="axis.classpath">
<fileset dir="${axis.home}/lib">
<include name="**/*.jar" />
</fileset>
</path>
I have coded a simple java client program to test the web service, using the generated stubs. Here is the code.
package com.ibswings.ws.test.servicea;

public class Main {

public static void main(String ... args) {

try {
ServiceAImpl proxy = new ServiceAPortServiceLocator().getServiceAPort();
proxy.createUser(null);
} catch (Exception exp) {
exp.printStackTrace();
}
}
}
To compile all the generated and above java code, I have defined a ant target named build as shown below.
<target name="build" depends="gen">
<javac srcdir="${src.dir}"
destdir="${build.dir}"
classpathref="axis.classpath"
debug="on">
<src path="${src-gen.dir}"/>
</javac>
</target>
And finally a target to run the client:
<target name="run">
<java classname="com.ibswings.ws.test.servicea.Main" classpathref="master.classpath"/>
</target>
Here is the complete ant script which has all targets needed from generating java stubs from wsdl, compile and finally to run the client.
<project name="axis" default="run">

<property name="axis.home" value="C:\Dev\Installed\axis-1_4"/>
<property name="xerces.home" value="C:\Dev\Installed\xerces-2_9_1"/>
<property name="src-gen.dir" value="src"/>
<property name="src.dir" value="src"/>
<property name="build.dir" value="build"/>
<property name="wsdl" value="ServiceA.wsdl"/>

<path id="axis.classpath">
<fileset dir="${axis.home}/lib">
<include name="**/*.jar" />
</fileset>
</path>

<path id="master.classpath">
<pathelement path="${build.dir}"/>
<path refid="axis.classpath"/>
<fileset dir="${xerces.home}">
<include name="xercesImpl.jar"/>
</fileset>
</path>

<taskdef resource="axis-tasks.properties" classpathref="axis.classpath" />

<target name="init">
<mkdir dir="${build.dir}"/>
<mkdir dir="${src-gen.dir}"/>

<delete includeemptydirs="true">
<fileset dir="${build.dir}" includes="**/*.*"/>
</delete>

<delete includeemptydirs="true">
<fileset dir="${src-gen.dir}" includes="**/*.*"/>
</delete>
</target>

<target name="gen" depends="init">
<axis-wsdl2java
output="${src-gen.dir}"
verbose="true"
url="${wsdl}" >
</axis-wsdl2java>
</target>

<target name="build" depends="gen">
<javac srcdir="${src.dir}"
destdir="${build.dir}"
classpathref="axis.classpath"
debug="on">
<src path="${src-gen.dir}"/>
</javac>
</target>

<target name="run">
<java classname="com.ibswings.ws.test.servicea.Main" classpathref="master.classpath"/>
</target>

</project>

7 comments:

Kaleb Brasee said...

Thanks Ishwara, this is a great post. Wish I would have found this last Friday, would have saved a lot of confusion!

Ishwara Varnasi said...

Thank you!

Luis Sardinha said...

Thanks, it was very helpful.

nishant kumar said...

Hey Ishwara....thanks a lot man...for the content helped me a lot in generating the client from the provided wsdl....

Thanks again!!

prashant devda said...
This comment has been removed by the author.
Prashant said...

Thanks a lot..
It is very helpful.

Divakar Renganathan said...

Thanks a lot, was really helpful.