JAX-RPC Client-Side Programming Models

JAX-RPC Client Environment:

JAX-RPC defines three client-side programming models that Java application can be use to access Web service:

Generated stub and dynamic proxy methods use the Service Endpoint Interface (SEI). The SEI is basically the Java representation of the Web service operations described in the WSDL portType element. The SEI is a Java interface defining methods used by the Java client to interact with the Web service. The SEI is generated by a WSDL to Java mapping tool.


Generated stub  (Static stub)

Dynamic proxy

Dynamic Invocation Interface (DII)

Web service not expected to change

Some changes to the Web Service expected, such as the location of the service

Considerable changes to the Web service expected, such as:

  • Location of the service
  • Request/response format
  • Data types

Most common scenario

Less common

Less common

You can generate a stub class either from WSDL (using WSDL2Java) or from a service endpoint interface. A generated stub class is required to implement both javax.xml.rpc.Stub and the service endpoint interface. This stub interface provides APIs to configure stubs by setting properties like endpoint address, session, user name, password, etc.

The client at runtime creates dynamic proxy stubs using the javax.xml.rpc.Service interface. The client has a prior knowledge of the WSDL and the service it is going to invoke. It uses the javax.xml.rpc.ServiceFactory classes to create the service and get the proxy.

This software pattern eliminates the need for clients to know in advance a service's exact name and parameters. A DII client can discover this information at runtime using a service broker that can look up the service's information. This flexibility in service discovery enables the run-time system to use service brokers, which can adopt varying service discovery mechanisms - ebXML registries, UDDI, etc.


Generated Stub

The stub-based model generates local stub classes for the proxy from a WSDL document. When you change the WSDL document, you must regenerate the stubs. Web service vendors provides tools to generate and compile stubs. Along with the stubs, the tools generate additional classes, and a service definition interface (SDI), which is the interface that is derived from a WSDL's portType. This is the interface you use to access the operations on the Web service. The combination of these files are called client-side artifacts. Client-side artifacts are a collection of files on the client-side that handle communication between a client and a Web service. Generated client-side artifacts must include:

The following is the interface of stub class define in package javax.xml.rpc:

package javax.xml.rpc;

import java.util.Iterator;

public interface Stub {

     * Standard property: User name for authentication.
    public static final String USERNAME_PROPERTY = Call.USERNAME_PROPERTY;

     * Standard property: Password for authentication.
    public static final String PASSWORD_PROPERTY = Call.PASSWORD_PROPERTY;

     * Standard property: Target service endpoint address. The
     * URI scheme for the endpoint address specification must
     * correspond to the protocol/transport binding for this
     * stub class.
    public static final String ENDPOINT_ADDRESS_PROPERTY =

     * Standard property: This boolean property is used by a service
     * client to indicate whether or not it wants to participate in
     * a session with a service endpoint. If this property is set to
     * true, the service client indicates that it wants the session
     * to be maintained. If set to false, the session is not maintained.
     * The default value for this property is false.

    public void _setProperty(String name, Object value);
    public Object _getProperty(String name);
    public Iterator _getPropertyNames();

Let's summarize the Stub-based Invocation Model:

Steps of coding and building a Static Stub Client:

  1. Generate Stubs
    • Run the wscompile command (in one line):

       wscompile -gen:client -d build -classpath build config-client.xml

    • Generates stub files based on the information it reads from the WSDL and config-client.xml files

       – The location of the WSDL is specified by the <wsdl> element of the config-client.xml file

       – –doption can be used to specify a directory where to place generated output files

    • A config-client.xml example:

       <wsdl location="build/Hello.wsdl" packageName="com.myco"/>

  2. Create client code
    1). Creates a Stub object:

      (Stub)(new MyHelloService_Impl().getHelloIFPort())

    The code in this method is implementation-specific because it relies on a MyHelloService_Impl object, which is not defined in the specifications. The MyHelloService_Impl class will be generated by wscompile.

    2). Sets the endpoint address that the stub uses to access the service:

      stub._setProperty(javax.xml.rpc.Stub.ENDPOINT_ADDRESS_PROPERTY, args[0]);

    At runtime, the endpoint address is passed to HelloClient in args[0] as a command-line parameter, which ant gets from the endpoint.address property in the build.properties file.

    3). Casts stub to the service endpoint interface, HelloIF:

      HelloIF hello = (HelloIF)stub;

    The following is a stand-alone Stub-based client example:

    package hello;
    import javax.xml.rpc.Stub;
    public class HelloClient {
        public static void main(String[] args) {
            try {
                Stub stub = (Stub)(new MyHelloService_Impl().getHelloIFPort());
                stub._setProperty (javax.xml.rpc.Stub.ENDPOINT_ADDRESS_PROPERTY, args[0]);
                HelloIF hello = (HelloIF)stub;
            } catch (Exception ex) {

    The following is a J2EE based Stub-based client using JNDI to lookup service:

    package hello;
    import javax.xml.rpc.Stub;
    public class HelloClient {
        public static void main(String[] args) {
            try {
                Context ic = new InitialContext();
                Service service = (Service) ic.lookup("java:comp/env/service/HelloService");
                HelloIF hello = (HelloIF) service.getHelloServiceProviderPort();
            } catch (Exception ex) {

  3. Compile the client code with remote interface and stubs in CLASSPATH

    javac –classpath system_jars:dir_with_server_class_files:dir_with_stub_class_files HelloClient.java

  4. Package client classes and run the client code with JAX-RPC generated code and runtime system
    • Command to pack the client

    jar cvf hello_client.jar all_client_class_files:all_server_class_files

    • Command to run the client

    java –classpath hello_client.jar:jwsdp-jars hello.HelloClient

The step "Create client code" involves the Stub Configuration. The Stub instance must be configured XML protocol binding which is a compile time configuration and  service endpoint address which can be set at runtime. The stub configuration can be configured in two ways: Static configuration (Compile time) based on the WSDL description of a target service endpoint (such as wsdl:binding, soap:binding, wsdl:port) and Runtime configuration using the javax.xml.rpc.Stub API. The javax.xml.rpc.Stub provides few standard properties for Stub Configuration:

Standard Property
What is it?
javax.xml.rpc.Stub.ENDPOINT_ADDRESS_PROPERTY Target service endpoint address Required
javax.xml.rpc.Stub.PASSWORD_PROPERTY Password for authentication Required
javax.xml.rpc.Stub.USERNAME_PROPERTY User name for authentication Required
javax.xml.rpc.Stub.SESSION_MAINTAIN_PROPERTY This boolean property is used by a service client to indicate whether or not it wants to participate in a session with a service endpoint. Optioanl

Dynamic Proxy

The dynamic proxy client calls a remote procedure through a dynamic proxy stub, a class that is created during runtime by using JAX-RPC client APIs. Although the source code for the static stub client relied on an implementation-specific class, the code for the dynamic proxy client does not have this limitation. The client gets the service information from a given WSDL document. It uses the service factory class to create the service based on the WSDL document and obtains the proxy from the service.

The significant JAX-RPC client APIs used are:

Let's summarize the Dynamic Proxy-based Invocation Model:

Steps of coding and building Dynamic Proxy Client

  1. Generate Service Endpoint Interface Class
    • runs wscompile with the -import option
    • reads the wsdl file provided by the Web service and generates the service endpoint interface class

  2. Create Client Code
    1. Creates a Service object

      Service helloService = serviceFactory.createService(helloWsdlUrl,
                              new QName(nameSpaceUri, serviceName));

      • Service object is a factory for proxies
      • Service object itself is created from ServiceFactory object
      • Parameters of createService()
      • URL of the WSDL file
      • QName object

    2. Create a proxy with a type of the service endpoint interface

      dynamicproxy.HelloIF myProxy = (dynamicproxy.HelloIF)helloService.getPort(
                            new QName(nameSpaceUri,portName),

      • HelloIF.class is generated by wscompile (at compile time)
      • The port name (HelloIFPort) is specified by the WSDL file
  3. Compile Client Code with Service Endpoint Interface class CLASSPATH
  4. Package Client to a jar file with SEI class.

The following is a sample of Dynamic Proxy Client code:

package dynamicproxy;
import java.net.URL;
import javax.xml.rpc.Service;
import javax.xml.rpc.JAXRPCException;
import javax.xml.namespace.QName;
import javax.xml.rpc.ServiceFactory;
import dynamicproxy.HelloIF;

public class HelloClient {

    public static void main(String[] args) {
        try {

            String UrlString = args[0] + "?WSDL";
            String nameSpaceUri = "http://sample.proxy.org/wsdl";
            String serviceName = "MyHelloService";
            String portName = "HelloIFPort";
            URL helloWsdlUrl = new URL(UrlString)

            ServiceFactory serviceFactory = ServiceFactory.newInstance();
            //Create a Service using  the WSDL document
            Service helloService = serviceFactory.createService(helloWsdlUrl,
                        new QName(nameSpaceUri, serviceName));
           //Get the proxy by calling getPort method from an instance of Service. 
           dynamicproxy.HelloIF myProxy = (dynamicproxy.HelloIF) helloService.getPort(
                        new QName(nameSpaceUri, portName),


        } catch (Exception ex) {

Dynamic Invocation Interface

The Dynamic Invocation Interface (DII) client does not require a WSDL file to generate static stubs or pass the WSDL file to the service factory to create the service; instead, the client must know a service's address, operations, and parameters in advance. Using the Dynamic Invocation Interface (DII) enables the client to discover target services dynamically on runtime and then to invoke methods. During runtime, the client uses a set of service operations and parameters, establishes a search criterion to discover the target service, and then invokes its methods.This also enables a DII client to invoke a service and its methods without knowing its data types, objects, and its return types.

DII looks up a service, creates a javax.xml.rpc.Call object by setting the endpoint specific parameters and operations, and finally invokes the call object to execute the remote methods. The significant JAX-RPC client APIs used are:

Let's summarize the Dynamic Invocation Model:

Steps of coding  DII Client:

  1. Create a Service object
    • Invoke createService() method of a ServiceFactory object

      Service service = factory.createService(new QName(qnameService));

    • qnameService parameter is the name of the service specified in WSDL

      <service name="MyHelloService">

  2. From the Service object, create a Call object
    • A Call object supports the dynamic invocation of the remote procedures of a service

      QName port = new QName(qnamePort);
      Call call = service.createCall(port);

    • The parameter of createCall is a QName object that represents the service endpoint interface, which is specified in WSDL

      <portType name="HelloIF">

  3. Set the service endpoint address on the Call object
    • In the WSDL file, this address is specified by the <soap:address> element


  4. Set properties on the Call object
    • Properties to set


  5. Sepcify the method's return type, name, and parameter
    • Return type, method name, parameter

      QName QNAME_TYPE_STRING = new QName(NS_XSD, "string");
      call.setOperationName(new QName(BODY_NAMESPACE_VALUE,"sayHello"));
      call.addParameter("String_1", QNAME_TYPE_STRING,ParameterMode.IN);

  6. Invoke the remote method on the Call object
    • Assign the parameter value (Murphy) to a String array (params) and then executes the invoke method with the String array as an argument

      String[] params = { "Murphy" };
      String result = (String)call.invoke(params);

The following is a sample of DII client:

package dii;
import javax.xml.rpc.Call;
import javax.xml.rpc.Service;
import javax.xml.rpc.JAXRPCException;
import javax.xml.namespace.QName;
import javax.xml.rpc.ServiceFactory;
import javax.xml.rpc.ParameterMode;

public class HelloClient {
    private static String qnameService = "MyHelloService";
    private static String qnamePort = "HelloIF";
    private static String BODY_NAMESPACE_VALUE = "urn:Foo";
    private static String ENCODING_STYLE_PROPERTY ="javax.xml.rpc.encodingstyle.namespace.uri";
    private static String NS_XSD = "http://www.w3.org/2001/XMLSchema";
    private static String URI_ENCODING = "http://schemas.xmlsoap.org/soap/encoding/";

    public static void main(String[] args) {
        System.out.println("Endpoint address = " + args[0]);
        try {
            ServiceFactory factory = ServiceFactory.newInstance();
            Service service =factory.createService(
                new QName(qnameService));
                QName port = new QName(qnamePort);
            //Create an instance of the Call object
            Call call = service.createCall(port);
            //Set service endpoint
            //Configure your Call instance with its setter methods
                    new Boolean(true));
            //Set definition of the return Type
            QName QNAME_TYPE_STRING =new QName(NS_XSD, "string");
            //Set Name of the method to invoke 
                    new QName(BODY_NAMESPACE_VALUE,"sayHello"));
            //Set parameters defintions in the call object
            call.addParameter("String_1", QNAME_TYPE_STRING,
            String[] params = { "Murph!" };
            //Finally invoke the method
            String result = (String)call.invoke(params);
        } catch (Exception ex) {

A DII client also can be invoked using one-way RPC mechanisms. In that case, the client does not require setting the return value types, and the call can be invoked as follows: