How To Script Webservices with Jython and Axis

This post covers the steps required to build and use a Jython webservice client.  The goal is to end up with a scripting environment that is easy to use.  The short version of the post is as follows:

  1. Use Apache Axis to generate and build a java library (jar) for the target webservice.
  2. Add that library and the supporting Axis libraries to Jython via the CLASSPATH.
  3. Write and run your Jython script, using the webservice.

The rest of the post shows how you do each of those steps in detail.

Quick Intro

Webservices based mashups are all the rage these days and most commercial applications of any size and user base will have web services that allow more direct access to their data.  There are lots of ways to use these including Integrated Development Environments like NetBeans, Eclipse and Microsoft’s .Net set of tools.  None of these tools though are accessible to an end user like a scripting tool would be.  So, I’ve spent some time figuring out how to use Jython to script webservices.

My first shot at it was to do it pretty low level, and that worked, but there is no way that I would make it available to folks who didn’t have a pretty detailed understanding of webservices, xml and Jython.

My second shot is more successful.  I used Apache Axis to generate client stub code and compiled that using Java, and added it to a jar file.  Once I had that, all that was necessary was to add the new jar file to my classpath settings along with the necessary axis, javax.activation, and javax.mail supporting jar files, and I had a Jython environment that provided a remarkeably friendly scripting environment for the target tool.  While it is likely beyond the capabilities (or interest) of end users to go through the java hoops to make the jar files available, it makes a lot of sense for application creators to do this.  It opens up applications that provide webservices so much more.

Step 1 - Setup your environment

So here is how I did this for an application that I have access to.   The webservice in this case is Telelogic Change, an enterprise Change Request management tool that is integrated with Telelogic Synergy.  I’ve written about Synergy before, it’s a changeset based Configuration Management tool.

Telelogic Change

The first step is to setup your environment with all the supporting tools will need.  Here is the list of resources I used for this:

Jython - I used the latest stable release: 2.2.1
Java JDK- Your Choice on version as long as it is newer than 1.5
Apache Ant- Use Ant to build the jar file for the webservice you want to script
Apache Axis- I used version 1.4

Note if the JDK you have is not the Enterprise Edition that comes with the java mail api the java bean activation framework, you will need to grab these jars and add them to your classpath.

Java Mail API
Java Beans Activation Framework - activation.jar

These provide support for attachments in webservices so you may not need them if the webservice you are scripting doesn’t use attachments.

Step 2 - Build the web service client jar file for jython

The next step was to write an ant build file that would use the axis wsdl2java tool to generate the java stub code that jython would use to script the webservice.  To do this I needed to know the webservice wsdl url and feed that into axis.  Once that was complete, I compiled the generated sources and included them in jar file.  That made it easy to add to the Jython environment.  So here is the ant build script that did that:

<project> <path id="axis.classpath"> <fileset dir="c:/tools/axis/lib"> <include name="**/*.jar" /> </fileset> </path> <taskdef resource="axis-tasks.properties"classpathref ="axis.classpath" /> <target name="default"> <axis-wsdl2java
	output="./src"testcase ="false"verbose ="true"url ="http://linux:8606/webservices/ChangeService?wsdl" > <mapping
      	namespace="http://www.telelogic.com/change/types"package ="webservice.types" /> <mapping
      	namespace="http://www.telelogic.com/change"package ="webservice" /> </axis-wsdl2java> <javac
	srcdir="./src/"destdir ="./bin/"classpathref ="axis.classpath" /> <jar
    destfile="./webservice.jar"basedir ="bin"> </jar> </target> </project> 

To generate the webservice.jar file, you just need to run ant and give it the target.

ant default

Note that I played a little with the mappings in the wsd2java task so that the resulting java packages wouldn’t have such large names. This is a scripting environment, and typing webservices.ChangeService was a lot easier than com.telelogic.www.change.ChangeService …

Step 3 - Setup Jython Environment to use Webservice

The next step is to ensure that all the appropriate jar files are in the CLASSPATH prior to invoking Jython. For this, I wrote a small wrapper batch file that set the classpath and loaded Jython. Don’t forget to include the jar file you just built.

Here is my batch file:

set CLASSPATH=%CLASSPATH%;c:\temp\axis\webservice.jar
set CLASSPATH=%CLASSPATH%;c:\tools\axis\lib\mailapi.jar;
set CLASSPATH=%CLASSPATH%;c:\tools\axis\lib\activation.jar;
set CLASSPATH=%CLASSPATH%;c:\tools\axis\lib\axis-ant.jar;
set CLASSPATH=%CLASSPATH%;c:\tools\axis\lib\axis.jar;
set CLASSPATH=%CLASSPATH%;c:\tools\axis\lib\commons-discovery-0.2.jar;
set CLASSPATH=%CLASSPATH%;c:\tools\axis\lib\commons-logging-1.0.4.jar;
set CLASSPATH=%CLASSPATH%;c:\tools\axis\lib\jaxrpc.jar;
set CLASSPATH=%CLASSPATH%;c:\tools\axis\lib\log4j-1.2.8.jar;
set CLASSPATH=%CLASSPATH%;c:\tools\axis\lib\saaj.jar;
set CLASSPATH=%CLASSPATH%;c:\tools\axis\lib\wsdl4j-1.5.1.jar

c:\tools\jython\jython.bat

Step 4 - Scripting the WebService

Now it is a simple matter of using the webservice within jython.  You don’t have to supply the wsdl to jython because it is encoded in the generated stub classes in the webservice.jar you produced in Step 2 above.  The beauty of Jython emerges here because you can play with the webservice “live” using the interactive console.

Here is a quick python script that uses the Telelogic Change webservice to query for CRs.

from webservice import ChangeService_ServiceLocator

# Use the generated stub toconnect tothe webservice
service =ChangeService_ServiceLocator ()port =service .getChangeServiceHttpPort()# Login intothe webservice and geta security token
token =port .login("userid", "password", "/some/database/path", "User")# run a quick CR Query
results =port .query(token , "crstatus='entered'", ("problem_number", "problem_synopsis", "owner", "resolver"))# display the results forcr inresults :crid =cr .attributes[0].getStringValue();synopsis =cr .attributes[1].getStringValue();owner =cr .attributes[2].getStringValue();resolver =cr .attributes[3].getStringValue(); print "CR %s (%s) is owned by %s and is being resolved by %s.\n" % (crid,synopsis ,owner ,resolver )# alldone 

The output should look something like this:

CR 11 (Sample Cr for webservice testing) is owned by axyech and is being resolved by developerA.
CR 12 (Another Sample CR) is owned by useryxz and is being resolved developerX.
CR 13 (Final Sample CR) is owned by userabc and is being resolved by developerY.

Conclusion

Jython, with its tight java integration, makes a nice platform for scripting webservices, building applications that combine different webservices, and also for exploring what a webservice has to offer. In playing with the webservice for Telelogic Change, I found it easy to use Jython commands like dir(xxx) in the interactive console to explore the methods and properties of the webservice objects.  That made it a lot easier to learn how the webservice worked.  Further, in comparison to a lot of the java code I used trying to figure this out, I found Jython to be much more concise and straightforward to work with.  This was partly because I didn’t have to predeclare all the types for objects that were returned by the service.

I can see jython being used very effectively in the webservice arena.  Here are some ideas of things you can do with it:

  1. Provide an end user scripting capability.
  2. Prototype applications that use multiple webservices … ie mashups.
  3. Write test cases / unit tests in jython to exercise a webservice.

All in all this is a very useful way to use a webservice, and apache axis and jython together make it easy.

Related Articles

JSJaC GWT(Google Web Toolkit) AJAXInterceptor Facebook API XSTM Prototype script.aculo.us jQuery UI Django template newjs

Related Projects

JSJaC GWT(Google Web Toolkit) AJAXInterceptor Facebook API XSTM Prototype script.aculo.us jQuery UI Django template newjs