This chapter provides guidelines for ensuring interoperability.
The goal of the Web service architecture is to allow heterogeneous business applications to smoothly work together. The architecture is loosely coupled and based on XML standards. Web services are designed to work with each other by defining Web Service Description Language (WSDL) files as service contracts, regardless of which operating system and development technology are behind them. However, because of the complexity involved in service contracts, standards like WSDL and SOAP leave room for ambiguous interpretations. In addition, vendor-specific enhancements and extensions work against universal interoperability.
Business applications must invoke each other's services. These services are often implemented with different technologies. Interoperability failures tend to increase as Web service complexity increases. If you host a publicly available Web service, you will want to ensure that your clients from all over the world, using vastly different tool kits, can successfully invoke it. Likewise, your business application might need to integrate or interact with another vendor's Web service that was built on top of an existing legacy system and has an unusual interface design.
Interoperability issues can originate from any layer of the protocol stack. On the transport level, both parties involved in exchanging messages must agree on a specific physical transport mechanism. For example, you cannot expect to use JMS transport from a non-Java platform. This is why using basic HTTP protocol increases your chance of interoperability. On the message level, because SOAP allows virtually any type of data encoding to be used, interoperability can become difficult. For example, a standard ArrayList on a Java platform will not be automatically translated into a System.collections.ArrayList on the .NET platform. Also, interoperability issues arise at the basic WSDL and SOAP level—advanced Web service developers will find many more new challenges when they start implementing quality of service (QOS) features such as security, reliability, and transaction services.
Difficulties in interoperability do exist. However, with a few good guidelines, your Oracle Infrastructure Web service should work seamlessly with other Java EE vendor platforms or non-Java platforms like the Microsoft .NET platform.
As interoperability gains more and more importance in the Web service community, a number of organizations have been established to achieve this goal.
SOAPBuilders is a loosely organized forum of developers working towards a set of tests for interoperability between SOAP implementations. Interoperability is demonstrated by implementing a canonical set of tests that are collectively defined by the participants in the forum.
The tests developed by the SOAPBuilder community are, by and large, based on vendor practices. However, practices shift over time. Clean and well-defined rules organized in a formal manner are needed for Web service vendors, Web service developers, and Web service consumers. See the following Web site for more information on SOAPBuilder tests:
The Web Services Interoperability organization (WS-I) is an open industry organization that creates, promotes, and supports generic protocols for the interoperable exchange of messages between Web services. WS-I profiles are guidelines and recommendations for how the standards should be used. These profiles aim to remove ambiguities by adding constraints to the underlying specifications.
WS-I deliverables are profiles, common or best practices, scenarios, testing software, and testing materials. You should design your Web service so that it adheres to WS-I basic profiles. WS-I compliant services agree to clear contracts and have a greater chance of interoperability.
For example, a WS-I basic profile-compliant Web service should use the following features.
Use HTTP or HTTPS as the transport binding. HTTP 1.1 is preferred over HTTP 1.0.
Use literal style encoding. Do not use SOAP encoding.
Use stricter fault message syntax. When a MESSAGE contains a soap:Fault element, its element children must be unqualified.
Use XML version 1.0.
The service should not declare array wrapper elements using the convention ArrayOfXXX.
The WS-I Web site provides more information about WS-I profiles, and the rules defined within profiles:
Oracle is a member of the WS-I organization and is fully committed to helping our customers achieve interoperability. The Oracle Infrastructure Web Services platform allows a high degree of flexibility to help you create interoperable Web services.
Oracle JDeveloper supports integrated testing of WSDL files and running Web services for WS-I Basic Profile conformance. It delivers an enhanced HTTP Analyzer for monitoring and logging, and provides a built-in analysis and reporting tool to better diagnose interoperability issues. For more information, see the Oracle JDeveloper online help.
The first general guideline is to create Web services which are WS-I compliant, if possible. The WS-I profiles, however, do not solve all interoperability problems. Many Web services were implemented before WS-I profiles existed. Also, the legacy systems that you are enabling as a Web service might have placed restrictions on your designs. Thus, good practice in designing Web services should always be adopted from the beginning of the development process, whenever possible.
The following sections provide general guidelines for creating interoperable Web services.
The top-down from WSDL approach enables you to design your Web service from service contracts that are not tied to any platform or language-specific characteristics. Contract-level interoperability can be ensured even before your Web service is implemented. Other Web service platform tools will be able to process your WSDL file and it is less likely that the service will be affected by existing legacy APIs.
If possible, use an XSD schema editor to design your data types with schema types. Resist using platform-specific data types such as the .NET DataSet data type, Java collections, and so on.
Avoid unnecessarily complex schema data types such as
xsd:choice. Simple types provide the best interoperability and have the added benefit of improved performance.
Use single dimensional arrays, if possible. Use arrays of arrays instead of multi-dimensional arrays.
Multi-dimensional arrays (applicable in RPC-encoded formats only) are not supported on the .NET platform. Also, in the case of multi-dimensional arrays, the length of the inner arrays must be the same. Arrays of arrays provides flexibility in such a way that the length of contained arrays can be different.
Note:While XSD supports the definition of multi-dimensional arrays in the WSDL, programming languages such as Java map them to arrays of arrays and express the payload in a multi-dimensional format. While converting the payload to multi-dimensional format, the Java VM must ensure that the length of each inner array is the same, as well as perform other checks.
If you have an array with attributes
xsd:nillable=true, for example, and the service implementation attempts to return a null reference to this array, then the representation of the payload becomes problematic. Some implementations can completely ignore this element in the payload as
minoccurs=0, while other implementations can specify this in the payload with the attribute
The same question arises when you attempt to deserialize the array. You can deserialize either to a null reference or to an array that contains no element. In this case, the guideline is to check for null always before checking for length.
Although sparse, variable-sized, and multi-dimensional arrays are supported by XSD, they may not be supported by your target platform. If you are creating your Web service top down from WSDL, try to avoid these array types and use regular arrays.
xsd:anyType is mapped to
java.lang.Object in the Java platform; this allows you to pass any run-time that will require a separate serializer and deserializers to be registered. The guideline is to find all the possible types that can be used in the runtime and define them in the WSDL.
The following example illustrates a class
MyAnyType and two classes,
MyPossibleType2, that extend it. In this case, use
MyAnyType instead of
xsd:anyType, in the Web method.
It is possible for the presence of only one unsupported
xsd:type in the WSDL to affect interoperability. The easy work around is to map the unsupported XSD type to SOAPElement by using a mapping mechanism, such as a JAX-RPC mapping file. Even if you have a type that is supported but fails during runtime, you can still attempt to map it to SOAPElement, then parse the SOAPElement inside the client or server.
Decide what you want to do with null values. For example, should an array be allowed to be null? Should you use a null string or an empty string? If you are sending a null value across platforms, will it cause exceptions on the receiver side?
Avoid sending null values if possible. If you must use null values in your application, design your schema types to clearly indicate that a null value is allowed.
If your Web service is designed to be WS-I compliant, use the WS-I monitor tool to log messages and the analyzer tool to validate for conformance. You can obtain free downloads of WS-I tools from the following Web site:
Some schema types, such as
xsd:unsignedint, do not always have a direct native type mapping. For example, there are no Java platform equivalent unsigned types. Schema numeric types such as
xsd:decimal might have different precisions once mapped to their platform native types.
There are also limitations on the
xsd:string type. The strings must not contain illegal XML characters and the \r (carriage return) character will typically be mapped to the \n (line feed) character.
byte instead of
xsd:string when you do not know the character set that the source data uses. Binary content is more interoperable than text content.
If you are creating the Web service bottom up from Java classes, you must ensure that you use the closest possible data type. Thus, use Java data types closer to the
xsd:type. For example, if you want to use
xsd:dateTime to represent a date and time, then use the
javax.xml.datatype.XMLGregorianCalendar data type instead of
XMLGregorianCalendar data type can return a more precise time because it can store fractional seconds.
If you are creating the Web service top down from WSDL, use mapping files to map the
XMLGregorianCalendar if time accuracy is very important.
Note:All of the pre-Java EE platforms, such as J2EE 1.*, used
Calendar, but now Java EE-compliant platforms use
XMLGregorianCalendar. This provides better .Net interoperability because it can handle long fractions of seconds.
By itself, the RPC-encoded message format does not imply that you will not be able to interoperate with other platforms and clients. In many cases, there are RPC-encoded Web services which are in use today. The reason to move away from RPC-encoded message formats is to avoid some of the edge cases where different interpretations of the underlying specification and implementation choices break interoperability. Some examples include the treatment of sparse arrays, multi-dimensional arrays, custom fault code QNames, un-typed payloads, and so on.
If you are creating Web services bottom up from Java classes, you can avoid name collisions by using explicit package names in your classes. If you are creating Web services top down from WSDL, you can avoid name collisions by using unique namespace URIs.
Note:By default, when most Web service assembly tools use the top down approach, they will try to derive a package name for the generated classes from the namespace URI. When they use the bottom up approach, they will try to use the Java package name to derive a namespace URI.
Unfortunately, because of valid package name limitations, this derivation is not 1-1. So, specifying namespace URI in such a way that it does not produce a conflicting package name that another namespace URI has yielded, is very important.
You can use message handlers, custom serializers, or interceptors to easily fix some interoperability issues. This idea is to fix the issue on the payload at a very granular level, by intercepting and changing the message either before it encounters the deserializers, or after the payload is generated by the serializers and before it is put on the wire.
Many WS-* specifications are in early adoption phase, and could potentially reveal interoperability issues with different stacks. A suggestion would be to make sure that a WS-* feature is absolutely required before applying it. Another suggestion would be to apply features that are most commonly used in the Web services space. For example, if you are in a situation where there are several possible options, such as choosing either Basic Authentication, X.509, or Kerberos for security, then choose the option which is most commonly used in the Web services space.