Main Page

Previous Section Next Section

JAX-RPC Interoperability

In the context of Web services, interoperability can be summarized as meaning that the functional characteristics of the service should remain immutable across differing application platforms, programming languages, hardware, operating systems, and application data models. By definition, Web services should be interoperable, and the service consumer should not be tied to the service implementation.

However there are bound to be issues when applications use disparate SOAP libraries that generate and manipulate the underlying SOAP message, disparate programming languages, and disparate hardware-software stacks. The following are common causes for interoperability problems between these libraries or toolkits:

In general, architects should keep the following in mind while designing Web services:

  1. Avoid propeietary extensions. Avoid building dependencies into the application that use any vendor-specific extension to the specifications JAX-RPC depends on (SOAP, WSDL, XML schemas, and HTTP).

  2. Test interoperability. Never assume things will work as they should. It is essential to test interoperability of the service implementation across multiple consumers, especially if the consumers are outside the boundaries of the organization. Public interoperability tests are also available from the Web Services Interoperability organization (www.ws-i.org) and White Mesa (www.whitemesa.com).

  3. Analyze disparate data models. When a service is used to integrate applications that have disparate data models, the models may need to be resolved by creating an intermediate model. For example, flutebank.com integrates with brokerage.com to provide customers the ability to view their accounts simultaneously online when in any of the portals. The data model for an account as represented in flutebank.com may be quite different from an account in brokerage.com. In this scenario, the architects will need to reconcile the models by creating an XML schema acceptable to both parties.

  4. Analyze disparate data types. Data types passed as arguments and return types from the service invocation can impact interoperability.

    • JAX-RPC-defined data types. The data types and mappings defined in the specifications are available in all JAX-RPC runtimes. Because they are subsets of the XML schema specifications and map directly to the data types in the SOAP encoding, they are completely interoperable.

    • Custom data types. If the data type is custom defined (e.g., a java.util.HashMap of com.flutebank.accounts.Account objects), an XML schema must be created to describe the representation of the data and the custom serializer and deserializer for that data on the server. Such a schema may not be completely interoperable. In addition, the JAX-RPC client would need to write serializers and deserializers to invoke the service. We looked at handling custom data types earlier in this chapter. In summary, custom data types may not be completely interoperable across all service consumers.

  5. Avoid custom data types. Custom data types that force the use of custom serializers and deserializers can potentially cause interoperability issues with other implementations. For example, a List may be represented differently by implementations from vendors A and B. If vendor A's client runtime is used to invoke a service deployed in vendor B's runtime, serialization errors may occur, because each implementation uses its own XML mapping of that data type. If the mapping is not available, the corresponding serailizers and deserializers will need to be written.

    For collection classes in particular, the SOAPBuilders community plans to pursue interoperability testing across vendor runtime implementations.

  6. Customize data, protocols, and encoding schemes. Architects should be wary of any code that customizes the messages. A good example is the Compress-Secure handlers example in Listing 10.13. The endpoint of that service cannot be invoked by clients that are not aware of the compression and security algorithm used and understood by the service. From a service perspective, there is no standard way to communicate this information (e.g., it cannot be specified in WSDL).

  7. Promote portability of client code between JAX-RPC implementations. J2EE developers would be familiar with the concept of writing an EJB and deploying it transparently in a J2EE server. The EJB client can be written with complete transparency and used in any J2SE environment by simply altering configuration properties. This portability of client code does not translate identically in the JAX-RPC environment, especially when using custom data types. A JAX-RPC client is not guaranteed to be portable if it uses anything beyond the simple data types. This is tied to the way the serializers and deserializers are written, as discussed earlier. In other words, if architects choose vendor A's implementation of JAX-RPC and write client code that uses serializers and deserializers to invoke the service, they should not expect to simply take the client code and use it in vendor B's runtime. Applications should be designed to abstract away the specificity, minimizing the changes needed.

Let us now look at an example of interoperability in action. We will write a Microsoft C#.NET client to demonstrate how a JAX-RPC Web service can be consumed from a Microsoft.NET environment. We will use the BillPay service developed and deployed previously in this chapter. As in most practical service consumer scenarios, we will invoke a service based on the WSDL describing it.

During service deployment, xrpcc was used to generate the WSDL. This WSDL file can now be passed to the Microsoft.NET wsdl compiler, to generate the client-side stubs:

wsdl /l:CS /protocol:SOAP http://127.0.0.1:9090/billpayservice/billpayservice.wsdl

The above generates the C# source file Billpayservice.cs, which contains the structures and serialization rules based on the schema and bindings defined in WSDL.

Next, we build a Windows DLL out of the generated proxy code using the C# compiler, passing it the referenced dlls from the .NET framework:

csc /t:library /r:System.Web.Services.dll /r:System.Xml.dll Billpayservice.cs

The next step is to write a client and invoke the three methods exposed by the JAX-RPC Web service. Listing 10.17 shows the C# client code for this purpose.

Listing 10.17: C# client for JAX-RPC
Start example
BillPay service
using System;
namespace BillpayClient{
     /// <summary>
     /// This is a simple C# client to invoke the flutebank.com Web service.
     /// @Author Sameer Tyagi
     /// </summary>
     class JAX-RPCClient{
           /// <summary>
           /// The main entry point for the application.
           /// </summary>
           [STAThread]
           static void Main(string[] args) {

     // Instantiate the stub/proxy
                Billpayservice serv = new Billpayservice();
     // Set the endpoint URL
           if(args.Length ==1)
                 serv.Url=args[0];
           else
                 serv.Url= "http://127.0.0.1:9090/billpayservice/jaxrpc/BillPay";

// Invoke the schedule payment method
           PaymentConfirmation conf = serv.schedulePayment(DateTime.Today," my
                                                        account at sprint",190);
           Console.WriteLine("Payment was scheduled "+ conf.confirmationNum);

// Invoke the listSchedulePayment method
           PaymentDetail[] detail= serv.listScheduledPayments();
                 for(int i=0;i< detail.Length;i++){
                       Console.WriteLine("Payee name "+ detail[i].payeeName);
                       Console.WriteLine("Payee name "+ detail[i].account);
                       Console.WriteLine("Payee name "+ detail[i].amt);
                       Console.WriteLine("Payee name "+ detail[i].date);
                 }
// Invoke the getLastPayment method
          Double lastpaid= serv.getLastPayment("my cable tv provider");
          Console.WriteLine("Last payment was "+ lastpaid);
          }
     }
}
End example

The C# client code is remarkably similar to the JAX-RPC stub client written earlier, because of the syntactic and semantic similarities between the two programming languages. The client code can now be compiled and executed. The output will be similar to the following:

C:\Dotnetclient>billpayClient
Payment was scheduled 81263767
Payee name Digital Credit Union
Payee name Credit
Payee name 2000
Payee name 8/1/2002 11:27:33 PM
Last payment was 829

We have just developed a Web service in Java, deployed it in a JAX-RPC runtime, and exposed the service with only a WSDL interface. WSDL was used to develop a client in a completely different language and platform, C# and .NET, yet produced identical behavior.


Previous Section Next Section


JavaScript Editor Java Tutorials Free JavaScript Editor