WSDL

 

WSDL is an acronym for Web Services Definition Language.  It provides a standards-based way of rigorously describing a Web service.  For example, it is sufficiently well-defined that a computer program can take a wsdl description of a deployed Web service and automatically generate Java stubs and skeletons that can be used by a client program to interact with the deployed service.  

WSDL comes into play at several points in the life of a Web Service.  First, it plays a critical role at design time by allowing a developer to publish the interface to a service he or she is building or by allowing a vendor to implement a service that his or her organization plans to offer that conforms to the published interface defined for a given type of service, such as a quotation and purchasing interface for electronic parts.  A second use occurs at run time when a program contacts a uddi registry and obtains a list of vendors who offer a particular type of service, as defined by a standard wsdl for that type of service.  The registry could return a wsdl for each vendor, enabling the program to contact any and all for functions defined in the wsdl and at the address also included there.  A third use, similar to the first, could be for two companies who wish to support frequent interaction between their two systems to build stub and skeleton interfaces between them.  

In this lesson, the discussion will cover general aspects of wsdl but illustrate them with respect to stub and skeleton architectures.  The lesson on UDDI will consider run time aspects.

In this discussion, both the deployed service and the client are assumed to be Java classes and, hence, the generated stubs and skeletons will also Java classes.  Generation tools no doubt exist for other languages, but they will not be considered.

Written in XML, a wsdl description includes the following:

IBM, Microsoft, and others submitted wsdl to the W3C for adoption as a standard in September, 2000.  A description of the standard is available at http://www.w3.org/TR/wsdl.html.

 


Concepts and Terms

The developers of wsdl have gone to some lengths to define it in abstract terms, as opposed to any implementation of those terms within a particular computer language or for a particular hardware/software platform.  However, for someone experienced developing distributed applications using Java, it may be easier to understand the wsdl generalized architecture if its main components are mapped, first, to familiar Java constructs. 

One can think of a Web service as a collection of functions provided by a set of Java objects available at a particular network address.  Each such object is defined by an interface that includes the methods that may be accessed by a client.  These interfaces also include descriptions of the parameters expected by the methods and the data types they return.

From a bottom-up perspective, then, a wsdl includes the following:

Now, let's look at a description of WSDL quoted verbatim from the 1.1 specification published byW3C.

A WSDL document defines services as collections of network endpoints, or ports. In WSDL, the abstract definition of endpoints and messages is separated from their concrete network deployment or data format bindings. This allows the reuse of abstract definitions: messages, which are abstract descriptions of the data being exchanged, and port types which are abstract collections of operations. The concrete protocol and data format specifications for a particular port type constitutes a reusable binding. A port is defined by associating a network address with a reusable binding, and a collection of ports define a service. Hence, a WSDL document uses the following elements in the definition of network services:

  • Types– a container for data type definitions using some type system (such as XSD).
  • Message– an abstract, typed definition of the data being communicated.
  • Operation– an abstract description of an action supported by the service.
  • Port Type–an abstract set of operations supported by one or more endpoints.
  • Binding– a concrete protocol and data format specification for a particular port type.
  • Port– a single endpoint defined as a combination of a binding and a network address.
  • Service– a collection of related endpoints.

 


Rationale

Now that we have some idea of what WSDL is, why would we want to use it?  I'll try to answer that question from a developer's point of view.  Actually, two developers' points of view: one working on the service side, the other working on the client side.  For simplicity, I'll assume that the service is provided through a single object whose interface encompasses all of the functions included in the service.

A main idea behind wsdl is that the wsdl definition can be used to automatically generate service side skeletons that can interact with the deployed object that provides the service and to generate client side stubs that can communicate with the skeletons, thereby providing the client program with access to the functions provided by the service.  Make the wsdl for a service available and you open the door to fast, easy programmable access to that service.

Whereas the wsdl is sufficient to generate mechanisms that can interact with the methods offered by a service, it says nothing about their semantics.  That is, a client program can confidently call methods and receive recognizable data types back, but nothing in the wsdl says anything about the actual processing that will take place behind the called method.  One must rely on external descriptions of those details and trust the vendor to reliably provide the actually processing it promises to deliver.


Process

The following steps can be used to provide access  through a WSDL to a Web service deployed on an AXIS SOAP engine:

  1. Develop the Java class that implements the functionality of the service.
  2. Deploy the class.
  3. Use Axis to generate and obtain a WSDL for the deployed class.
  4. Generate the service-side skeletons.
  5. Re-implement the service function in the generated class referenced by the skeleton. 
  6. Deploy WSDL-based version of the service, thereby also replacing the original deployed class.
  7. Use Axis to generate and obtain a WSDL for the deployed class.
  8. Generate the client-side stubs.
  9. Incorporate the stubs as an import package into the client program and use them to access service functions.

1. MessageObject Class

This class implements the functionality of the service.  It a large system, it might be one of several such classes or a controller class that provides the interface to multiple classes that implement portions of the overall service.

public class MessageObject extends java.lang.Object
{

protected java.lang.String message;

public MessageObject()
{
    message = "Hello, World, from jbs MessageObject";
}

public void setMessge(java.lang.String message)
{
    this.message = message;
}

public java.lang.String getMessage()
{                        
            return this.message;
}

public java.lang.String getMessageXML()
{
    String xmlString  = "<?xml version='1.0'?>\n";
                   xmlString += "<return_message>"; 
                   xmlString += this.message; 
                   xmlString += "</return_message>\n";
                             
            return xmlString;
}

    }

This class is straight forward.  It includes a getMessage() method that returns an Hello, World message.  


2. Deploy MessageObject

The class representing the service should be explicitly deployed using a Web Service Deployment Descriptor (WSDD) rather than relying on the instant deployment approach used in the SOAP example (e.g., through a .jws source file).

WSDD File

<deployment xmlns="http://xml.apache.org/axis/wsdd/"
   xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">

 <service name="MessageObject" provider="java:RPC">
  <parameter name="className" value="MessageObject"/>
  <parameter name="allowedMethods" value="*"/>
 </service>

</deployment>

 Axis provides a utility to perform the deployment.  An example invocation follows:

java org.apache.axis.client.AdminClient 
-lhttp://localhost:8888/axis/services/AdminService 
deploy.wsdd

This example assues that Axis is running locally on port 8888 and that the deploy.wsdd file is accessible to the JVM

Note that this deployment is necessary to enable Axis to automatically generate a WSDL, as discussed next, but that its functionality will have to be transferred to the implementation class, MessageObjectSoapBindingImpl, generated when the skeleton is generated.


3. & 7. WSDL Description of MessageObject

Below is the WSDL generated by Axis from the deployed class.  It may be accessed dynamically from http://jbs.cs.unc.edu:8888/axis/services/MessageObject?wsdl.

<?xml version="1.0" encoding="UTF-8"?>

<wsdl:definitions targetNamespace="http://localhost:8888/axis/services/MessageObject/axis/services/MessageObject" 
    xmlns="http://schemas.xmlsoap.org/wsdl/" 
    xmlns:apachesoap="http://xml.apache.org/xml-soap" 
    xmlns:impl="http://localhost:8888/axis/services/MessageObject/axis/services/MessageObject-impl" 
    xmlns:intf="http://localhost:8888/axis/services/MessageObject/axis/services/MessageObject" 
    xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" 
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
    xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<!-- General description of service, constituting a standard -->

  <wsdl:types>
    <schema targetNamespace="http://schemas.xmlsoap.org/soap/encoding/" 
        xmlns="http://www.w3.org/2001/XMLSchema">
      <import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
      <element name="Array" nillable="true" type="soapenc:Array"/>
    </schema>
    </wsdl:types>

  <wsdl:message name="setMessgeResponse">
    </wsdl:message>
  <wsdl:message name="setMessgeRequest">
    <wsdl:part name="message" type="xsd:string"/>
  </wsdl:message>
  <wsdl:message name="getMessageXMLResponse">
    <wsdl:part name="return" type="xsd:string"/>
  </wsdl:message>
  <wsdl:message name="getOperationDescByNameResponse">
    <wsdl:part name="return" type="soapenc:Array"/>
  </wsdl:message>
  <wsdl:message name="getMessageRequest">
  </wsdl:message>
  <wsdl:message name="getMessageResponse">
    <wsdl:part name="return" type="xsd:string"/>
  </wsdl:message>
  <wsdl:message name="getOperationDescsRequest">
  </wsdl:message>
  <wsdl:message name="getOperationDescsResponse">
    <wsdl:part name="return" type="soapenc:Array"/>
  </wsdl:message>
  <wsdl:message name="getMessageXMLRequest">
  </wsdl:message>
  <wsdl:message name="getOperationDescByNameRequest">
    <wsdl:part name="in0" type="xsd:string"/>
  </wsdl:message>

  <wsdl:portType name="MessageObject">
    <wsdl:operation name="getMessage">
      <wsdl:input message="intf:getMessageRequest" name="getMessageRequest"/>
      <wsdl:output message="intf:getMessageResponse" name="getMessageResponse"/>
    </wsdl:operation>
    <wsdl:operation name="setMessge" parameterOrder="message">
      <wsdl:input message="intf:setMessgeRequest" name="setMessgeRequest"/>
      <wsdl:output message="intf:setMessgeResponse" name="setMessgeResponse"/>
    </wsdl:operation>
    <wsdl:operation name="getMessageXML">
      <wsdl:input message="intf:getMessageXMLRequest" name="getMessageXMLRequest"/>
      <wsdl:output message="intf:getMessageXMLResponse" name="getMessageXMLResponse"/>
    </wsdl:operation>
    <wsdl:operation name="getOperationDescs">
      <wsdl:input message="intf:getOperationDescsRequest" name="getOperationDescsRequest"/>
      <wsdl:output message="intf:getOperationDescsResponse" name="getOperationDescsResponse"/>
    </wsdl:operation>
    <wsdl:operation name="getOperationDescByName" parameterOrder="in0">
      <wsdl:input message="intf:getOperationDescByNameRequest" name="getOperationDescByNameRequest"/>
      <wsdl:output message="intf:getOperationDescByNameResponse" name="getOperationDescByNameResponse"/>
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="MessageObjectSoapBinding" type="intf:MessageObject">
    <wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="getMessage">
      <wsdlsoap:operation soapAction=""/>
      <wsdl:input name="getMessageRequest">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
          namespace="http://localhost:8888/axis/services/MessageObject/axis/services/MessageObject" 
          use="encoded"/>
      </wsdl:input>
      <wsdl:output name="getMessageResponse">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
          namespace="http://localhost:8888/axis/services/MessageObject/axis/services/MessageObject" 
          use="encoded"/>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="setMessge">
      <wsdlsoap:operation soapAction=""/>
      <wsdl:input name="setMessgeRequest">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
          namespace="http://localhost:8888/axis/services/MessageObject/axis/services/MessageObject" 
          use="encoded"/>
      </wsdl:input>
      <wsdl:output name="setMessgeResponse">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
          namespace="http://localhost:8888/axis/services/MessageObject/axis/services/MessageObject" 
          use="encoded"/>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="getMessageXML">
      <wsdlsoap:operation soapAction=""/>
      <wsdl:input name="getMessageXMLRequest">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
          namespace="http://localhost:8888/axis/services/MessageObject/axis/services/MessageObject" 
          use="encoded"/>
      </wsdl:input>
      <wsdl:output name="getMessageXMLResponse">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
          namespace="http://localhost:8888/axis/services/MessageObject/axis/services/MessageObject" 
          use="encoded"/>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="getOperationDescs">
      <wsdlsoap:operation soapAction=""/>
      <wsdl:input name="getOperationDescsRequest">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
          namespace="http://localhost:8888/axis/services/MessageObject/axis/services/MessageObject" 
          use="encoded"/>
      </wsdl:input>
      <wsdl:output name="getOperationDescsResponse">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
          namespace="http://localhost:8888/axis/services/MessageObject/axis/services/MessageObject" 
          use="encoded"/>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="getOperationDescByName">
      <wsdlsoap:operation soapAction=""/>
      <wsdl:input name="getOperationDescByNameRequest">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
          namespace="http://localhost:8888/axis/services/MessageObject/axis/services/MessageObject" 
          use="encoded"/>
      </wsdl:input>
      <wsdl:output name="getOperationDescByNameResponse">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
          namespace="http://localhost:8888/axis/services/MessageObject/axis/services/MessageObject" 
          use="encoded"/>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
<!-- Description of a specific implementation of a service, -->
<!-- as defined in the above general description (standard) -->
  <wsdl:service name="MessageObjectService">
    <wsdl:port binding="intf:MessageObjectSoapBinding" name="MessageObject">
      <wsdlsoap:address location="http://localhost:8888/axis/services/MessageObject"/>
    </wsdl:port>
  </wsdl:service>

</wsdl:definitions>

A best practices strategy is to store the two parts of the wsdl in separate files and to import the generic portion into the specific, implementation portion.


4. Generate Skeletons, etc.

 The first step in generating both skeletons and stubs is to obtain a WSDL for the deployed service, as discussed and illustrated above.

Axis provides a utility to generate the skeletons from the WSDL..  An example invocation follows:

java org.apache.axis.wsdl.WSDL2Java 
--server-side --skeletonDeploy true MessageObject.wsdl

This example assumes that the WSDL file has been saved as MessageObject.wsdl and is accessible to the JVM.  The generated files will appear in a subdirectory of the current directory created by Axis.  Both deploy.wsdd and undeploy.wsdd files are generated and used to deploy the re-implemented service file, skeletons, and supporting files.


5. Re-implement the Service Function

A template version of a service implementation file -- corresponding to MessageObject in this example -- is generated by Axis as part of the skeleton generation process.  The actual function of the service must be transferred or re-implemented in this file.  It is this file that is actually deployed and replaces the originally deployed service file, whose primary purpose was to generate the WSDL.  The various methods and core function for the getMessage() method are highlighted in the example file, below.

/**
 * MessageObjectSoapBindingImpl.java
 *
 * This file was auto-generated from WSDL
 * by the Apache Axis WSDL2Java emitter.
 */

package localhost;

public class MessageObjectSoapBindingImpl implements localhost.MessageObject{
    
    private java.lang.String message = "Hello, World, from jbs MessageObjectSoapBindingImpl";

    public java.lang.String getMessage() throws java.rmi.RemoteException {
        return this.message;
    }

    public void setMessge(java.lang.String msg) throws java.rmi.RemoteException {
    	  this.message = msg;
    }

    public java.lang.String getMessageXML() throws java.rmi.RemoteException {
        
	  String xmlString =  "<?xml version='1.0'?>\n";
               xmlString += "<return_message>"; 
               xmlString += this.message; 
               xmlString += "</return_message>\n";
                             
         return xmlString;
    }

}

6. Deploy Skeletons and Re-implementation of MessageObject

This deploy.wsdd file is generated by the Axis utility and can be used to deploy the skeletons, the re-implemented service function, and supporting files.

<!-- Use this file to deploy some handlers/chains and services      -->
<!-- Two ways to do this:                                           -->
<!--   java org.apache.axis.client.AdminClient deploy.wsdd          -->
<!--      after the axis server is running                          -->
<!-- or                                                             -->
<!--   java org.apache.axis.utils.Admin client|server deploy.wsdd   -->
<!--      from the same directory that the Axis engine runs         -->

<deployment
    xmlns="http://xml.apache.org/axis/wsdd/"
    xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">

  <!-- Services from MessageObjectService WSDL service -->

  <service name="MessageObject" provider="java:RPC">
      <parameter name="wsdlTargetNamespace" value="http://localhost:8888/axis/services/MessageObject/axis/services/MessageObject"/>
      <parameter name="wsdlServiceElement" value="MessageObjectService"/>
      <parameter name="wsdlServicePort" value="MessageObject"/>
      <parameter name="className" value="localhost.MessageObjectSoapBindingSkeleton"/>
      <parameter name="wsdlPortType" value="MessageObject"/>
      <parameter name="allowedMethods" value="*"/>

  </service>
</deployment>

The command to do the actual deployment is identical to that used for the original deployment:

java org.apache.axis.client.AdminClient 
-lhttp://localhost:8888/axis/services/AdminService 
deploy.wsdd


8. Generate Stubs, etc.

Axis provides a utility to generate the stubs from the WSDL..  An example invocation follows:

java org.apache.axis.wsdl.WSDL2Java MessageObject.wsdl

This example assumes that the WSDL file has been saved as MessageObject.wsdl and is accessible to the JVM.  The generated files will appear in a subdirectory of the current directory created by Axis.


9. WSDL Client

The key issue for WSDL stub-skeleton based systems, as illustrated with the MessageObject service being used in this discussion, is to substitute the following core statements:

MessageObjectService service = new MessageObjectServiceLocator();
localhost.MessageObject port = service.getMessageObject();        
msg = port.getMessage();

for

String endpoint = "http://localhost:8888/axis/MessageObject.jws"; 
Service service = new Service(); 
Call call = (Call) service.createCall(); 
call.setTargetEndpointAddress( new java.net.URL(endpoint) ); 
call.setOperationName(new QName("http://soapinterop.org/", "getMessage") ); 
msg = (String) call.invoke( new Object[]{} );

The second sequence of code involves direct interaction with the service through package-supported generation of SOAP protocol messages.  It requires the user to know the network address of the service, to create the call, and to invoke it.

The first is based on RPC- or RMI-style access.  The Axis tools generate the ServiceLocator object from the automatically generated WSDL for the service.  The locator is used to get a stub for the service which, in turn, allows the client to call the desired method of the service -- i.e.,  getMessage().  Here, the client is not required to know the network address of the service or to perform the call by creating the service, getting a call object, and then invoking the method through it.

However, the WSDL-based stub-skeleton approach does exactly what the SOAP approach does, only all of the paraphernalia to do so is generated automatically.  In the example code below, the calling sequences are shown to map from the RPC-like code shown at the top to its SOAP implementation, resembling the code shown at the bottom..


Top-level Client: WSDL_Call

import localhost.*;

public class WSDL_Call
{
    public static String callService()
    {
        String msg = "Error in callService";
        try {

            MessageObjectService service = new MessageObjectServiceLocator();
            localhost.MessageObject port = service.getMessageObject();        
            msg = port.getMessage();

        }  catch ( Exception e )  {
            e.printStackTrace();
        }
        return msg;
    }

    public WSDL_Call()
    {
        super();
    }

}

localhost.MessageObjectServiceLocator

/**
 * MessageObjectServiceLocator.java
 *
 * This file was auto-generated from WSDL
 * by the Apache Axis WSDL2Java emitter.
 */

package localhost;

public class MessageObjectServiceLocator extends org.apache.axis.client.Service implements localhost.MessageObjectService {

    // Use to get a proxy class for MessageObject

    private final java.lang.String MessageObject_address = "http://localhost:8888/axis/services/MessageObject";

    public String getMessageObjectAddress() {
        return MessageObject_address;
    }

    public localhost.MessageObject getMessageObject() throws javax.xml.rpc.ServiceException {
       java.net.URL endpoint;
        try {
            endpoint = new java.net.URL(MessageObject_address);
        }
        catch (java.net.MalformedURLException e) {
            return null; // unlikely as URL was validated in WSDL2Java
        }
        return getMessageObject(endpoint);
    }

    public localhost.MessageObject getMessageObject(java.net.URL portAddress) throws javax.xml.rpc.ServiceException {
        try {
            return new localhost.MessageObjectSoapBindingStub(portAddress, this);
        }
        catch (org.apache.axis.AxisFault e) {
            return null; // ???
        }
    }

    /**
     * For the given interface, get the stub implementation.
     * If this service has no port for the given interface,
     * then ServiceException is thrown.
     */
    public java.rmi.Remote getPort(Class serviceEndpointInterface) throws javax.xml.rpc.ServiceException {
        try {
            if (localhost.MessageObject.class.isAssignableFrom(serviceEndpointInterface)) {
                return new localhost.MessageObjectSoapBindingStub(new java.net.URL(MessageObject_address), this);
            }
        }
        catch (Throwable t) {
            throw new javax.xml.rpc.ServiceException(t);
        }
        throw new javax.xml.rpc.ServiceException("There is no stub implementation for the interface:  " + (serviceEndpointInterface == null ? "null" : serviceEndpointInterface.getName()));
    }

}

localhost.MessageObjectSoapBindingStub

/**
 * MessageObjectSoapBindingStub.java
 *
 * This file was auto-generated from WSDL
 * by the Apache Axis WSDL2Java emitter.
 */

package localhost;

public class MessageObjectSoapBindingStub extends org.apache.axis.client.Stub implements localhost.MessageObject {
    
    private java.util.Vector cachedSerClasses = new java.util.Vector();
    private java.util.Vector cachedSerQNames = new java.util.Vector();
    private java.util.Vector cachedSerFactories = new java.util.Vector();
    private java.util.Vector cachedDeserFactories = new java.util.Vector();

    public MessageObjectSoapBindingStub() throws org.apache.axis.AxisFault {
         this(null);
    }

    public MessageObjectSoapBindingStub(java.net.URL endpointURL, javax.xml.rpc.Service service) throws org.apache.axis.AxisFault {
         this(service);
         super.cachedEndpoint = endpointURL;
    }

    public MessageObjectSoapBindingStub(javax.xml.rpc.Service service) throws org.apache.axis.AxisFault {
        try {
            if (service == null) {
                super.service = new org.apache.axis.client.Service();
            } else {
                super.service = service;
            }
        }
        catch(java.lang.Exception t) {
            throw org.apache.axis.AxisFault.makeFault(t);
        }
    }

    private org.apache.axis.client.Call createCall() throws java.rmi.RemoteException {
        try {
            org.apache.axis.client.Call call =
                    (org.apache.axis.client.Call) super.service.createCall();
            if (super.maintainSessionSet) {
                call.setMaintainSession(super.maintainSession);
            }
            if (super.cachedUsername != null) {
                call.setUsername(super.cachedUsername);
            }
            if (super.cachedPassword != null) {
                call.setPassword(super.cachedPassword);
            }
            if (super.cachedEndpoint != null) {
                call.setTargetEndpointAddress(super.cachedEndpoint);
            }
            if (super.cachedTimeout != null) {
                call.setTimeout(super.cachedTimeout);
            }
            java.util.Enumeration keys = super.cachedProperties.keys();
            while (keys.hasMoreElements()) {
                String key = (String) keys.nextElement();
                if(call.isPropertySupported(key))
                    call.setProperty(key, super.cachedProperties.get(key));
                else
                    call.setScopedProperty(key, super.cachedProperties.get(key));
            }
            // All the type mapping information is registered
            // when the first call is made.
            // The type mapping information is actually registered in
            // the TypeMappingRegistry of the service, which
            // is the reason why registration is only needed for the first call.
            synchronized (this) {
                if (firstCall()) {
                    // must set encoding style before registering serializers
                    call.setEncodingStyle(org.apache.axis.Constants.URI_SOAP11_ENC);
                    for (int i = 0; i < cachedSerFactories.size(); ++i) {
                        Class cls = (Class) cachedSerClasses.get(i);
                        javax.xml.namespace.QName qName =
                                (javax.xml.namespace.QName) cachedSerQNames.get(i);
                        Class sf = (Class)
                                 cachedSerFactories.get(i);
                        Class df = (Class)
                                 cachedDeserFactories.get(i);
                        call.registerTypeMapping(cls, qName, sf, df, false);
                    }
                }
            }
            return call;
        }
        catch (Throwable t) {
            throw new org.apache.axis.AxisFault("Failure trying to get the Call object", t);
        }
    }

    public java.lang.String getMessage() throws java.rmi.RemoteException{
        if (super.cachedEndpoint == null) {
            throw new org.apache.axis.NoEndPointException();
        }
        org.apache.axis.client.Call call = createCall();
        call.setReturnType(new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string"));
        call.setUseSOAPAction(true);
        call.setSOAPActionURI("");
        call.setOperationStyle("rpc");
        call.setOperationName(new javax.xml.namespace.QName("http://localhost:8888/axis/services/MessageObject/axis/services/MessageObject", "getMessage"));

        Object resp = call.invoke(new Object[] {});

        if (resp instanceof java.rmi.RemoteException) {
            throw (java.rmi.RemoteException)resp;
        }
        else {
            try {
                return (java.lang.String) resp;
            } catch (java.lang.Exception e) {
                return (java.lang.String) org.apache.axis.utils.JavaUtils.convert(resp, java.lang.String.class);
            }
        }
    }

    public void setMessge(java.lang.String message) throws java.rmi.RemoteException{
        if (super.cachedEndpoint == null) {
            throw new org.apache.axis.NoEndPointException();
        }
        org.apache.axis.client.Call call = createCall();
        javax.xml.namespace.QName p0QName = new javax.xml.namespace.QName("", "message");
        call.addParameter(p0QName, new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string"), java.lang.String.class, javax.xml.rpc.ParameterMode.IN);
        call.setReturnType(org.apache.axis.encoding.XMLType.AXIS_VOID);
        call.setUseSOAPAction(true);
        call.setSOAPActionURI("");
        call.setOperationStyle("rpc");
        call.setOperationName(new javax.xml.namespace.QName("http://localhost:8888/axis/services/MessageObject/axis/services/MessageObject", "setMessge"));

        Object resp = call.invoke(new Object[] {message});

        if (resp instanceof java.rmi.RemoteException) {
            throw (java.rmi.RemoteException)resp;
        }
    }

    public java.lang.String getMessageXML() throws java.rmi.RemoteException{
        if (super.cachedEndpoint == null) {
            throw new org.apache.axis.NoEndPointException();
        }
        org.apache.axis.client.Call call = createCall();
        call.setReturnType(new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string"));
        call.setUseSOAPAction(true);
        call.setSOAPActionURI("");
        call.setOperationStyle("rpc");
        call.setOperationName(new javax.xml.namespace.QName("http://localhost:8888/axis/services/MessageObject/axis/services/MessageObject", "getMessageXML"));

        Object resp = call.invoke(new Object[] {});

        if (resp instanceof java.rmi.RemoteException) {
            throw (java.rmi.RemoteException)resp;
        }
        else {
            try {
                return (java.lang.String) resp;
            } catch (java.lang.Exception e) {
                return (java.lang.String) org.apache.axis.utils.JavaUtils.convert(resp, java.lang.String.class);
            }
        }
    }

}

localhost.MessageObjectService

 

/**
 * MessageObjectService.java
 *
 * This file was auto-generated from WSDL
 * by the Apache Axis WSDL2Java emitter.
 */

package localhost;

public interface MessageObjectService extends javax.xml.rpc.Service {

    public String getMessageObjectAddress();

    public localhost.MessageObject getMessageObject() throws javax.xml.rpc.ServiceException;

    public localhost.MessageObject getMessageObject(java.net.URL portAddress) throws javax.xml.rpc.ServiceException;
}

localhost.MessageObject

/**
 * MessageObject.java
 *
 * This file was auto-generated from WSDL
 * by the Apache Axis WSDL2Java emitter.
 */

package localhost;

public interface MessageObject extends java.rmi.Remote {
    public java.lang.String getMessage() throws java.rmi.RemoteException;
    public void setMessge(java.lang.String message) throws java.rmi.RemoteException;
    public java.lang.String getMessageXML() throws java.rmi.RemoteException;
}


Example

This program simply returns a Hello, World message using stubs and skeletons generated from the wsdl description of the deployed object.

Run the program.