The Dynamic Invocation Interface





The Dynamic Invocation Interface

With the dynamic invocation interface (DII), a client can call a remote procedure even if the signature of the remote procedure or the name of the service are unknown until runtime.

1 When to Use DII

Although DII clients are flexible, they are more complex than clients that use static stubs. (For an example of a client with static stubs, see Coding the Client (page 315).) Compared to clients with static stubs, clients with DII are more difficult to code, debug, and test. Therefore, a client should use DII only if it cannot use static stubs.

However, there are two cases that require the flexibility of a DII client. The first case is a service broker that dynamically discovers services, configures the remote calls, and executes the calls. For example, an application for an online clothing store might access a service broker that specializes in shipping. This broker would use the Java API for XML Registries (JAXR) to locate the services of the shipping companies that meet certain criteria, such as low cost or fast delivery time. At runtime, the broker uses DII to call remote procedures on the web services of the shipping companies. As an intermediary between the clothing store and the shipping companies, the broker offers benefits to all parties. For the clothing store, it simplifies the shipping process, and for the shipping companies, it finds customers.

The second case requiring DII is less common: a development environment that does not support the generation of static stubs.

2 A DII Client Example

The source code for this example is in the HelloClient.java file of the docs/tutorial/examples/jaxrpc/dynamic directory.

The HelloClient program makes two remote procedure calls: sayHelloand sayHelloOneWay. The sayHello call is synchronous and follows the familiar request-response model. During a synchronous call, the client makes the call (request) and waits for the call's return (response) before continuing. The sayHelloOneWay call has a one-way invocation mode. In the one-way mode, the client thread does not block and wait for the server to process the remote call. For more information about invocation modes, see the JAX-RPC Specifications.

DII Classes and Interfaces

The HelloClient program uses the following interfaces and classes for dynamic invocation.

  • Call— supports the dynamic invocation of a remote operation on a service port

  • Service— a factory for Call objects, dynamic proxies, and stubs; only generated services are factories for stubs

  • TypeMapping— a set of tuples that describe the mapping between Java programming language types and XML data types; each TypeMapping is for a specific encoding; each tuple in a TypeMapping contains the following information:

    • Java programming language type

    • SerializerFactory

    • DeserializerFactory

    • XML data type

  • TypeMappingRegistry— a storage area (registry) for TypeMapping instances; this registry enables you to store and retrieve TypeMapping instances for specific encodings

  • Qname— a qualified name based on the Namespaces in XML Specifications

To see how to set up and invoke a dynamic invocation, refer to the HelloClient source code that is shown in the next section. As you examine the source code, note the classes and interfaces that belong to the packages whose names begin with com.sun. These packages are specific to the reference implementation and are not defined in the JAX-RPC Specifications.

DII HelloClient Listing

Here is the full listing for the HelloClient.java file of the docs/tutorial/examples/jaxrpc/dynamic directory. Note how much longer the DII client is than the static stub client shown in Coding the Client (page 315).


package dynamic; 
import java.rmi.RemoteException; 

import javax.xml.rpc.Call; 
import javax.xml.rpc.Service; 
import javax.xml.rpc.JAXRPCException; 
import javax.xml.rpc.namespace.QName; 
import javax.xml.rpc.encoding.TypeMapping; 
import javax.xml.rpc.encoding.TypeMappingRegistry; 

import com.sun.xml.rpc.client.ServiceImpl; 
import com.sun.xml.rpc.client.dii.CallImpl; 
import com.sun.xml.rpc.client.dii.CallPropertyConstants; 

import com.sun.xml.rpc.encoding.Initializable; 
import com.sun.xml.rpc.encoding.TypeMappingImpl; 
import com.sun.xml.rpc.encoding.SerializerConstants; 
import com.sun.xml.rpc.encoding.TypeMappingRegistryImpl; 

import com.sun.xml.rpc.encoding.soap.SOAPConstants; 
import com.sun.xml.rpc.encoding.soap.StandardSOAPTypeMappings; 

import com.sun.xml.rpc.soap.streaming.SOAPNamespaceConstants; 

public class HelloClient implements CallPropertyConstants, 
    SerializerConstants {

    public static void main(String[] args) {

        try {

            String bodyNamespaceValue = 
                new String("http://dynamic-hello.org/wsdl"); 

            QName stringQname = 
                new QName(SOAPNamespaceConstants.XSD, "string"); 
            TypeMapping typeMapping = 
                new StandardSOAPTypeMappings(); 
            TypeMappingRegistry registry = 
                 new TypeMappingRegistryImpl(); 
            registry.register(typeMapping, 
                SOAPConstants.URI_ENCODING); 

            QName port = new QName("HelloIF"); 
            Service service = 
                new ServiceImpl(new QName("Hello")); 
            service.setTypeMappingRegistry(registry); 

            Call call = service.createCall(); 
            call.setPortTypeName(port); 
            call.setTargetEndpointAddress(args[0]); 

            call.setProperty(BODY_NAMESPACE_PROPERTY, 
                bodyNamespaceValue); 
            call.setProperty(IS_SOAPACTION_USED_PROPERTY, 
                new Boolean(true)); 
            call.setProperty(SOAPACTION_VALUE_PROPERTY, ""); 
            call.setProperty(ENCODING_STYLE_PROPERTY, 
                SOAPConstants.URI_ENCODING); 

            ((CallImpl)call).setReturnType(stringQname, 
                 String.class); 
            call.setOperationName("sayHello"); 
            call.addParameter("String_1", stringQname, 
                Call.PARAM_MODE_IN); 
            String[] params = { new String("Duke!") }; 
            String result = (String)call.invoke(params); 
            System.out.println(result); 

            call.setOperationName("sayHelloOneWay"); 
            call.removeAllParameters(); 
            call.invokeOneWay(null); 
            System.out.println("One-way invoked"); 

        } catch (Exception ex) {
            ex.printStackTrace(); 
        } 
    } 
}
Building and Running the DII Example

To build this example, follow these steps:

  1. Make sure that you've performed the set up instructions in Setting Up (page 309) and Coding the Service Definition Interface and Implementation Class (page 309).

  2. Go to the docs/tutorial/examples/jaxrpc/dynamic directory.

  3. Type the following:

    
    ant build

    This command compiles the code, runs the xrpcc tool, packages the WAR file, and deploys the WAR file onto the Tomcat server. The section, A Simple Example: HelloWorld (page 306), instructed you to perform each of these tasks by executing separate ant targets. The build target executes the same set of targets, but is more convenient because it requires less typing.

  4. To run the client, type the following command:

    
    ant run

    The client should display the following lines:

    
    A dynamic hello to Duke! <time-stamp> 
    One-way invoked

(Useful for debugging, the time-stamp indicates when the server code for the example was compiled. You can check the time-stamp to make sure that the client is accessing the WAR file most recently built.)


 Python   SQL   Java   php   Perl 
 game development   web development   internet   *nix   graphics   hardware 
 telecommunications   C++ 
 Flash   Active Directory   Windows