| By Adelene Ng | Article Rating: |
|
| October 27, 2003 12:00 AM EST | Reads: |
13,809 |
This article is a follow-up to an earlier article "Exposing Legacy Applications" (WSJ, Vol. 3, issue 5). It demonstrates how to integrate legacy applications with Web services using Apache Axis. Axis, which is a complete rewrite of Apache SOAP, promises to be faster and more flexible than Apache SOAP.
Two approaches will be illustrated here. The first uses the Axis API. In the second approach, the Axis tools (Java2WSDL, WSDL2Java) will be used to generate stubs. We then write a client that uses the generated stubs to access the Web service.
The legacy application used in this article captures and outputs system accounting information in an ASCII format.
Application Overview
The details of the architecture and description of the various components can be found in the first article. I had a legacy application in which I wanted to expose its commonly called operations as Web services. One of the uses of the application was to capture and track print job information for customer accounting purposes. It was based on a two-tier client/server model and the underlying communication protocol used was ONC–RPC. No changes were made to the existing legacy application. Converting the legacy application into a Web services application would allow a user to query these operations residing on a Web Server via a Web browser and have the results displayed to the user through the Web page
To achieve this, a three-tier architecture was adopted. The legacy server resides on the third tier. The second tier contains both the Web server and the legacy client. A wrapper class was created to isolate the legacy client code, making it easier to maintain. The SOAP client lives on the first tier. It accesses the legacy client on the Web server through the wrapper class. SOAP is used to communicate between the SOAP client and the services exposed on the Web server. The services communicate with the legacy client through the wrapper class. ONC–RPC is the protocol used between the legacy client and server. Figure 1 shows the overall system architecture.

Figures 2 and 3 illustrate the call sequence between the SOAP client, Web server (containing the wrapper class and legacy client), and legacy server. The sequence diagram summarizes the interactions between the different tiers and clearly shows which platform each of the classes reside on.

Tools Used
The entire system was written in Java running on Windows 2000 Professional. The tools used to build this system are:
What Is Apache Axis?
Axis is an implementation of an XMLSOAP– based protocol used for exchanging data in a distributed environment.
Several implementations of SOAP are available, for example, Apache SOAP (http://ws.apache.org/soap/), JWSDP (http://java.sun.com/webservices/webservicespack.html), GLUE (www.themindelectric.com), WASP (www.systinet.com) – the best known of which is Apache SOAP. Think of Axis as Apache SOAP 3.0. It is a complete rewrite of Apache SOAP 2.2.
Differences Between Axis and Apache SOAP
Apache Axis supports SOAP 1.1 and 1.2, Web Services Description Language 1.1, XML Schema 1.0, and JAX-RPC whereas Apache SOAP supports only SOAP 1.1, with limited support for XML Schemas. It does not support WSDL and uses a proprietary API. For those of you who are unfamiliar with WSDL, it is an XML document that describes Web services. It specifies the location of the service and the operations the service exposes.
In addition, Axis supports both RPC/encoded and Doc/literal Message formats whereas Apache SOAP supports only the former. RPC/encoded messages follow both SOAP RPC and encoding rules. This means that the SOAP body contains an element with the name of the remote procedure to be invoked. This element in turn contains an element for each parameter for that remote procedure. Both the parameters and return results are encoded in the SOAP body. The "encoding" portion refers to a set of serialization rules defined in the SOAP 1.2 Specification. These specify how objects, structures, and arrays should be serialized.
Doc/literal does not use the SOAP encoding rules for data. Instead, data is serialized according to some schema usually expressed using the W3C XML Schema. Table 1 summarizes the differences between Axis and Apache SOAP.

Advantages over Apache SOAP
Axis offers the following advantages over Apache SOAP. These are:
Points to Note When Migrating from Apache SOAP to Axis
Following are some of the items you need to be aware of when you attempt to migrate from Apache SOAP to Axis.
1. Axis does not return a generic Parameter type. The return type has to be explicitly set via the setReturnType() call.
2. The SOAPException class in Apache SOAP maps to AxisFault in Axis.
3. Although not used here, the MessageContext class is the Axis implementation of the Apache SOAP SOAPMessageContext class, and is core to message processing in handlers.
Building Web Services with Axis
Two approaches to building Web services with Axis are illustrated here. The first approach shows us how we can use the Axis API to build Web services. The second utilizes the tools that come with Axis to generate stubs. The client code is then written to utilize these stubs to access the Web service.
Using the Axis API
Create and Implement the "MyService" class These are the Web service methods that will be called from a client. For our purposes, two methods will be exposed as Web services and are defined in the class MyService. The methods are:
Create the Web Service Deployment Descriptor File
The WSDD is an XML file containing the deployment descriptor for statically configuring the Axis engine. This is proprietary to Axis. Axis uses the information contained in this deployment descriptor to track operations and type mappings. Note, this is different from WSDL, which defines the custom XML types and methods exposed as Web services, the request and response pairs associated with each method, and the URL bound to this service. To create the file deploy.wsdd:
1. Specify the WSDD deployment and define the "java" namespace
<deployment
xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
2. Define the service and provider name. The latter indicates it is a Java RPC service that is built into Axis.
<service name="MyService" provider="java:RPC">
3. Specify the name of the Java class
<parameter name="className" value="Accounting.MyService"/>
4. List all the methods callable from the client
<parameter name="allowedMethods" value="*"/>
5. The "*" allows all methods under the MyService class to be called. This can be further constrained by replacing the "*" with a space or comma-separated list of available method names:
<parameter name="allowedMethods"
value="GetNumberOfRecords_WGetFileData_W"/>
Axis can only send user-defined Java objects over the wire if there is a registered Axis serializer for it. The arbitrary Java classes have to be defined following the standard JavaBean convention. The Bean- Serializer class is then used to serialize this class. The registration calls are made in your client code. Next, we need to tell Axis which Java classes map to which XML Schema type. This is done in the deployment descriptor file by adding the following line:
<beanMapping qName="ns:MyJavaClass" xmlns:ns="urn:SomeService"
languageSpecificType="java:my.java.MyJavaClass" />
If the default bean serialization model is insufficient to meet your application needs, Axis provides the ability to write your own custom serializers/deserializers. Once these are built, Axis needs to be told which types they should be mapped to. This is done by adding the typeMapping tag into the deployment descriptor file as follows:
<typeMapping qname="ns:MyJavaClass" xmlns:ns="urn:SomeService"
languageSpecificType="java:my.java.MyJavaClass"
serializer="my.java.Serializer"
deserializer="my.java.DeserializerFactory"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
Writing the Client Code to Test the Web Service
The following steps are required to create the client code. The client accesses the Web services defined in the MyService class.
1. JAX-RPC Setup
- Create a Service object
Service service = new Service();
- Create a Call object
Call call = (Call)service.createCall()
2. Set the URL for the Web service
String endpoint = "http://localhost:8080/axis/services/MyService";
call.setTargetEndpointAddress(new java.net.URL(endpoint));
3. Define the serializers/deserializers (if required) for the classes. Since the application does not need to transmit any application-defined data classes as part of the SOAP Requests, no serializers and deserializers are needed.
4. Set the name of the method that you will be calling. To associate the GetNumberOf Records_W() method with the "call" instance, we invoke
call.setOperationName(new QName("MyService",
"GetNumberOfRecords_W"));
Likewise, to associate the GetFileData_W() method with the "call" instance, we invoke
call.setOperationName
(new QName("MyService", "GetFileData_W"));
5. Set the method arguments
call.addParameter("arg1", XMLType.XSD_STRING, ParameterMode.IN);
6. Set the return type of the method. To set the return type associated with the method GetNumberOfRecords_W(), we make the following call
call.setReturnType(org.apache.axis.encoding.XMLType.XSD_INT);
Likewise, to set the return type associated with the method, GetFileData_W(), we make the following call,
call.setReturnType(new QName
("ArrayOf_xsd_string"),java.lang.String[].class);
7. If the method name has been set to "GetNumberOfRecords_W", then it is invoked via
Integer ret = (Integer) call.invoke( new Object[] { s } );
"s" here refers to the argument that is being passed to the method that is being called. In this case, "s" represents the input filename.
8. Handle the errors
Deploying the Application
1. Compile all the classes 2. JAR the resulting class files and move the JAR file to the C:\jakartatomcat-4.1.24\webapps\ axis\WEB-INF\lib directory.
3. Make sure that the distinct ONC-RPC JAR files are placed in the C:\jakarta-tomcat-4.1.24\webapps\axis\WEB-INF\lib directory.
4. Before deploying the service, make sure that your Web server is up and running. Here we are using the Apache Tomcat Server. It has several scripts under the C:\jakarta-tomcat-4.1.24\bin directory. To start the Apache Tomcat Server, go to the directory, C:\jakarta-tomcat-4.1.24\bin and type startup.
5. Deployment is done via the AdminClient tool, java org.apache.axis.client.AdminClient deploy.wsdd
6. Next, run the legacy server application (if not already running).
7. Finally, run the SOAPClient.
To make things simple, I have created batch files for steps 1, 2, 4, 5, 6, and 7 to facilitate the execution of these commands.
Testing Whether the Web Service Is Correctly Deployed
There are two ways that you can check if your Web service is properly deployed. The first is to go directly to the Axis home page, http://localhost: 8080/axis/ (see Figure 4) and click on "View the list of deployed Web services". The page will show all the methods associated with MyService (see Figure 5). If the page only shows the heading, "And now...Some Services", then there is most likely an error in the deploy.wsdd file. To get a good idea of the cause of the error, look at the server log files (Apache Tomcat) located under C:\jakarta-tomcat-4.1.24\logs\localhost_log.<date>.txt

The second way is to directly invoke the service and the name of the method to test from the browser, for example,
http://localhost:8080/axis/services/MyService?method=GetNumberOf
Records_W&s=C:\\Experimental\\Axis\\src\\ACCOUNT.LOG
Figure 6 shows the result of invoking the service through the browser.

Using the Axis Tools
The second approach utilizes the tools that come bundled with Axis to generate the stubs.
Define the MyService and MyServiceImpl Classes
MyService is an interface class containing two methods. These are:
The MyServiceImpl class implements the methods defined in MyService.
Java2WSDL
The first step is to generate the WSDL file for the given MyService Interface. Use the Java2WSDL command to generate the WSDL file
java org.apache.axis.wsdl.Java2WSDL
-o Accounting.wsdl
-l"http://localhost:8080/axis/services/Accounting"
-n urn:Accounting
-p"Accounting" urn:Accounting
Accounting.MyService
Where
-o: Name of the output WSDL file, Accounting.wsdl
-l: URL of the Web Service, http://localhost:8080/axis/services/ Accounting
-n: Target Namespace for the WSDL, urn:Accounting
-p: Package to NameSpace name,value pairs (Accounting = urn: Accounting)
class-of-portType : Fully qualified class (Accounting.MyService)
WSDL2Java
Next, generate the server-side wrapper code and stubs. The Axis tool, WSDL2Java, does all of this automatically when we run the following command.
java org.apache.axis.wsdl.WSDL2Java -o . -d Session -s -p
Accounting.ws Accounting.wsdl
Where
-o: Output directory for generated files
-d: Deployment Scope. This can be one of: Application, Request or Session
-s: Generate the server side bindings for Web Service
-p: Package – override all namespace to package mappings and use this package name instead
Name of the WSDL file: Accounting.wsdl (this was generated in the previous step).
The files shown in Table 2 are generated as a result of running the WSDL2Java command.

Modifying the AccountingSoapBindingImpl Class
Modify the AccountingSoapBindingImpl class as follows:
1. Add the following import statement after the package Accounting.ws statement:
import Accounting.MyServiceImpl;
2. Add the MyServiceImpl attribute and create an instance of the class:
MyServiceImpl ms = new MyServiceImpl();
3. Replace the generated return statement, "return –3;" in the method getNumberOfRecords_W() by:
return ms.GetNumberOfRecords_W(in0);
The argument, in0, is of type String and is the name of the file to be processed. Note that the return value of -3 is a value arbitrarily generated by the WSDL2Java tool.
4. Replace the generated return statement, "return null;" in the method getFileData_W() by:
return ms.GetNumberOfRecords_W(in0);
The argument, in0, is of type String and is the name of the file to be processed. Note that the return value of null is a value arbitrarily generated by the WSDL2Java tool.
Writing the Client Code to Test the Web Service
1. Create an MyServiceService object via the MyServiceServicetServiceLocator:
Accounting.ws.MyServiceService service = new Accounting.ws.MyService
ServiceLocator();
2. We use the MyServiceService object to get a remote handle to the service,
Accounting.ws.MyService acct = service.getAccounting();
3. Finally, we make a call to the method
acct.getNumberOfRecords_W("C:\\Experimental\\Axis\\src2\\ACCOUNT.LOG");
Deploying the Service
1. Compile all the classes
2. JAR the resulting class files and move the JAR file to the C:\jakarta-tomcat-4.1.24\webapps\axis\WEB-INF\libdirectory.
3. Make sure that the distinct ONC-RPC JAR files are placed in the C:\jakarta-tomcat-4.1.24\webapps\axis\WEB-INF\libdirectory.
4. Before deploying the service, make sure that your Web server is up and running. Here we are using the Apache Tomcat Server. It has several scripts under the C:\jakarta-tomcat-4.1.24\bin directory. To start the Apache Tomcat Server, go to the directory, C:\jakarta-tomcat-4.1.24\bin and type startup.
5. Deployment is done via the AdminClient tool java org.apache.axis.client.AdminClientdeploy.wsdd
6. Run the legacy server application (if not already running).
7. Run the client.
Conclusion
I have presented two approaches that show how we can integrate legacy applications with Axis. The first utilizes the Axis API. The second uses the tools that come bundled with Apache Axis. I have also summarized the differences between Axis and Apache SOAP, listed the advantages of using Axis, and brought up some salient points to note when migrating from Apache SOAP to Axis.
Acknowledgments
I would like to thank Tzu-Khiau Koh and Chui-Ching Low for their comments on the initial drafts of this paper.
References
Published October 27, 2003 Reads 13,809
Copyright © 2003 SYS-CON Media, Inc. — All Rights Reserved.
Syndicated stories and blog feeds, all rights reserved by the author.
More Stories By Adelene Ng
Adelene Ng is an independent software consultant. She holds a PhD in Computer Science from the University of London, and an M.Sc. from the University of Manchester, United Kingdom.
![]() |
Nuwan 12/09/04 12:33:14 AM EST | |||
Your example would be COMPLETE if you could also publish the coding for a custom serializer. This article helped us a lot in many ways. But for some time now I have been trying to implement a custom serializer... but without success. No documentation on this area is available. I sincerely hope you can help me out with this. Thanking you in advance Nuwan |
||||
- The Top 150 Players in Cloud Computing
- Commercial vs Federal Cloud Computing
- Why IBM’s Server Chief Got Busted
- Industry Experts Discuss the State of Cloud Computing
- Cloud Expo New York Call for Papers Deadline December 15
- Cloud Computing on Gartner's Top 10 List and SYS-CON Events' 2010 Calendar
- US Federal Government is Major Cloud Computing Innovator
- Google Wave
- Ulitzer.com Named Exclusive "New Media" Sponsor of Cloud Computing Conference & Expo
- Tactical Cloud Computing Panel at 1st Annual GovIT Expo
- Adaptivity & Cloud Computing: Exclusive Q&A with CEO Tony Bishop
- 4th International Cloud Expo: Photo Album
- The Top 150 Players in Cloud Computing
- SYS-CON.TV: Cloud Computing Expo Power Panel
- Commercial vs Federal Cloud Computing
- Why IBM’s Server Chief Got Busted
- 1st Annual GovIT Expo: Letter from the Technical Chair
- Deputy CIO of the CIA to Keynote 1st Annual GovIT Expo
- Industry Experts Discuss the State of Cloud Computing
- SOA World Power Panel on SYS-CON.TV
- CIA was Headed to an Enterprise Cloud All Along: Jill Tummler Singer
- 1st Annual Government IT Conference & Expo: Themes & Topics
- Cloud Expo New York Call for Papers Deadline December 15
- Stock in Focus: Dragon Capital
- The i-Technology Right Stuff
- Who Are The All-Time Heroes of i-Technology?
- Get the Message
- Where Are RIA Technologies Headed in 2008?
- i-Technology Viewpoint: Is Web 2.0 the Global SOA?
- i-Technology Viewpoint: Thinking Outside the VC Box
- ESB Myth Busters: 10 Enterprise Service Bus Myths Debunked
- i-Technology Viewpoint: When to Leave Your First IT Job
- SOA Web Services Edge Conference Coverage on SYS-CON.TV
- Five Reasons Why Web 2.0 Matters
- SYS-CON.TV's "SOA Web Services" and "Enterprise Open Source" Programs To Air in December
- SOA World Conference & Expo SYS-CON.TV Power Panel Live From Times Square










There are a variety of applications that supp...

























