Web services hints and tips: JAX-RPC versus JAX-WS, Part 3

The service endpoint interface

This third part of the series about Java™ API for XML-based RPC (JAX-RPC) 1.1 and Java API for XML Web Services (JAX-WS) 2.0 compares the mapping of Web Services Description Language (WSDL) to a service endpoint interface (SEI). The concept of an SEI was first introduced in JAX-RPC 1.0 and has been maintained in JAX-WS 2.0, with some additions. This tip walks you through the major differences.

Russell Butek (butek@us.ibm.com), IT Specialist, IBM

Russell Butek is an IBM SOA and web services consultant. He has been one of the developers of the IBM WebSphere web services engine. He has also been a member the JAX-RPC Java Specification Request (JSR) expert group. He was involved in the implementation of Apache's AXIS SOAP engine, driving AXIS 1.0 to comply with JAX-RPC.


developerWorks Contributing author
        level

Nicholas Gallardo, Staff Software Engineer, IBM

Nick Gallardo works as a software engineer on the IBM WebSphere platform, focusing on various aspects of the Web services--most recently, the JAX-WS support. His previous work in IBM includes other assignments within the WebSphere and Tivoli platforms. Nick came to IBM in 2001 after working in development in two different technology start-ups in Austin, Texas.



13 June 2007

Also available in Chinese

Introduction

Develop skills on this topic

This content is part of a progressive knowledge path for advancing your skills. See Building and deploying JAX-WS web services

Overall, the structures of a Java API for XML-based RPC (JAX-RPC) 1.1 service endpoint interface (SEI) and a Java API for XML Web Services (JAX-WS) 2.0 SEI are very similar. This article addresses the differences. Even with differences in structure, however, the goal of providing an interface that reflects the contract of the Web service is the same.

Comparing SEI mapping

Listing 1 shows the WSDL for a simple HelloWorld Web service.

Listing 1. HelloWorld WSDL
  <?xml version="1.0" encoding="UTF-8"?>
      <wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
      xmlns:tns="urn:helloWorld/sample/ibm/com"
      xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
      xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="HelloWorld"
      targetNamespace="urn:helloWorld/sample/ibm/com">
  <wsdl:types>
    <xsd:schema targetNamespace="urn:helloWorld/sample/ibm/com"
        xmlns:tns="urn:helloWorld/sample/ibm/com"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <xsd:element name="hello">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="name" nillable="true" type="xsd:string" />
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
      <xsd:element name="helloResponse">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="response" nillable="true" type="xsd:string" />
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
    </xsd:schema>
  </wsdl:types>
  <wsdl:message name="helloRequestMsg">
    <wsdl:part element="tns:hello" name="helloParameters" />
  </wsdl:message>
  <wsdl:message name="helloResponseMsg">
    <wsdl:part element="tns:helloResponse" name="helloResult" />
  </wsdl:message>
  <wsdl:portType name="HelloWorld">
    <wsdl:operation name="hello">
      <wsdl:input message="tns:helloRequestMsg" name="helloRequest" />
      <wsdl:output message="tns:helloResponseMsg" name="helloResponse" />
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="HelloWorldBinding" type="tns:HelloWorld">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
    <wsdl:operation name="hello">
      <soap:operation soapAction="urn:helloWorld/sample/ibm/com/hello" />
      <wsdl:input name="helloRequest">
        <soap:body use="literal" />
      </wsdl:input>
      <wsdl:output name="helloResponse">
        <soap:body use="literal" />
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="HelloWorldService">
    <wsdl:port name="port" binding="tns:HelloWorldBinding">
      <soap:address location="http://tempuri.org/" />
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

Listing 2 shows the JAX-RPC mapping of the Java SEI from this WSDL without the method signatures (you will see more about those later).

Listing 2. JAX-RPC HelloWorld SEI
package com.ibm.samples;
public interface HelloWorld extends java.rmi.Remote {
...
}

Listing 3 shows the JAX-WS SEI for the same WSDL.

Listing 3. JAX-WS HelloWorld SEI
package com.ibm.samples.helloworld;

import javax.jws.WebService;

@WebService(name = "HelloWorld", targetNamespace = "urn:samples.ibm.com/HelloWorld")
public interface HelloWorld {
  ...
}

There are three differences here:

  • Package: The target namespace is "urn:helloWorld/sample/ibm/com". Both mappings take the domain name-like string and reverse the order of the elements. JAX-RPC's mapping stops at the first slash. JAX-WS's mapping continues with the string, adding the information after the first slash. Both specifications allow for custom namespace-to-package mappings.
  • Annotations: JAX-WS requires that all SEIs include the @WebService annotation. As mentioned in Part 1 of this series, JAX-WS includes support for the annotations defined in JSR-181 Web Services Metadata.
  • java.rmi.Remote: The JAX-RPC SEI extends the java.rmi.Remote interface. JAX-WS no longer requires this.

Before moving into the details of operation mappings, there is one last thing about the SEI itself. Although JAX-WS provides support for Web services that have an SEI, this is not mandatory for all services. With JAX-WS, a JavaBean can be deployed on its own as a Web service implementation, as opposed to JAX-RPC where the bean must include an SEI. JAX-WS services deployed without an SEI are considered to have an implicit SEI.


Comparing operation mapping

Now that you have seen the interfaces, look at the comparison of how the operations are mapped. There are different ways of designing a WSDL document to represent Web services that have similar semantics. The article Which style of WSDL should I use? provides an overview of the different styles of WSDL documents available and how to determine which is best for you.

Now, look at how JAX-RPC and JAX-WS map to each of the WSDL styles.

Exploring the document/literal wrapped pattern

The WSDL in Listing 1 is formatted using the document/literal wrapped pattern. Listings 4 and 5 are mappings for the same wrapped operation in JAX-RPC and JAX-WS. Notice that JAX-WS adds the @RequestWrapper and @ResponseWrapper annotations to the method. These provide additional metadata about both the elements that will serve as the operation wrapper along with any Java beans that might have been generated for those wrapper elements. These annotations are optional.

Listing 4. JAX-RPC complete HelloWorld SEI
package com.ibm.samples;

public interface HelloWorld extends java.rmi.Remote {
    public java.lang.String hello(java.lang.String name) throws java.rmi.RemoteException;
}
Listing 5. JAX-WS complete HelloWorld SEI
package com.ibm.samples.helloworld;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.ResponseWrapper;

@WebService(name = "HelloWorld", targetNamespace = "urn:samples.ibm.com/HelloWorld")
public interface HelloWorld {

    @WebMethod(action = "urn:samples.ibm.com/HelloWorld/hello")
    @WebResult(name = "response", targetNamespace = "")
    @RequestWrapper(localName = "hello",
        targetNamespace = "urn:samples.ibm.com/HelloWorld", 
        className = "com.ibm.samples.helloworld.Hello")
    @ResponseWrapper(localName = "helloResponse", 
        targetNamespace = "urn:samples.ibm.com/HelloWorld", 
        className = "com.ibm.samples.helloworld.HelloResponse")
    public String hello(
        @WebParam(name = "name", targetNamespace = "")
        String name);
}

As you can see, the JAX-WS mapping again has a lot of annotations, but when you get down to the root signature, the only difference is that the JAX-RPC method can throw java.rmi.RemoteException while the JAX-WS method is not defined to do so.

Exploring document/literal patterns

Both JAX-RPC and JAX-WS support mapping operations that are document/literal, but are not wrapped. To accomplish this with the HelloWorld sample, you would need to remove the wrapper elements that represent the operation name. Listing 6 shows what the relevant portions of the WSDL document would look like in comparison to the WSDL in Listing 1.

Listing 6. Document/literal WSDL
<wsdl:types>
  <xsd:schema targetNamespace="urn:helloWorld/sample/ibm/com"
   xmlns:tns="urn:helloWorld/sample/ibm/com"
   xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <xsd:element name="hello" type="xsd:string"/>
      <xsd:element name="helloResponse" type="xsd:string"/>
  </xsd:schema>
</wsdl:types>

<wsdl:message name="helloRequestMsg">
  <wsdl:part element="tns:hello" name="helloParameters" />
</wsdl:message>

<wsdl:message name="helloResponseMsg">
  <wsdl:part element="tns:helloResponse" name="helloResult" />
</wsdl:message>

Now look at the Java mapping for this new WSDL. Listings 7 and 8 show the JAX-RPC and JAX-WS mappings respectively. Do you see how similar the JAX-RPC mapping is? The only difference is the parameter name. As with the previous case, putting the annotations aside, there is no real difference between the JAX-RPC mapping and the JAX-WS mapping.

Listing 7. JAX-RPC document/literal mapping
public interface HelloWorld extends java.rmi.Remote {
    public java.lang.String hello(java.lang.String helloParameters) 
        throws java.rmi.RemoteException;
}
Listing 8. JAX-WS document/literal mapping
@WebService(name = "HelloWorld", targetNamespace = "urn:helloWorld/sample/ibm/com")
@SOAPBinding(parameterStyle = ParameterStyle.BARE)
public interface HelloWorld {

    @WebMethod(action = "urn:helloWorld/sample/ibm/com/hello")
    @WebResult(name = "helloResponse", 
        targetNamespace = "urn:helloWorld/sample/ibm/com", 
        partName = "helloResult")
    public String hello(
        @WebParam(name = "hello", 
            targetNamespace = "urn:helloWorld/sample/ibm/com", 
            partName = "helloParameters")
        String helloParameters);

}

Notice that for JAX-WS, you no longer see the @RequestWrapper and @ResponseWrapper annotations. Also note that a new annotation appears at the interface level as well, @SOAPBinding. This annotation provides information about the parameter style. If absent, the default value for the parameterStyle attribute is wrapped, which would be like the WSDL in Listing 1.

Exploring the RPC/literal patterns

The next example is somewhat different from the previous two. With an RPC/literal style WSDL, the parts are defined in terms of types rather than elements. Listing 9 contains the relevant WSDL differences.

Listing 9. RPC/literal WSDL changes
<wsdl:types/>

<wsdl:message name="helloRequestMsg">
  <wsdl:part name="helloParameters" type="xsd:string"/>
</wsdl:message>

<wsdl:message name="helloResponseMsg">
  <wsdl:part name="helloResult" type="xsd:string"/>
</wsdl:message>

The Java mappings in Listings 10 and 11 reflect the changes to the WSDL. Again, you see an identical mapping when the annotations are stripped away.

Listing 10. JAX-RPC RPC/literal mapping
public interface HelloWorld extends java.rmi.Remote {
    public java.lang.String hello(java.lang.String helloParameters)
        throws java.rmi.RemoteException;
}
Listing 11. JAX-WS RPC/Literal mapping
@WebService(name = "HelloWorld", targetNamespace = "urn:helloWorld/sample/ibm/com")
@SOAPBinding(style = Style.RPC)
public interface HelloWorld {

    @WebMethod(action = "urn:helloWorld/sample/ibm/com/hello")
    @WebResult(name = "helloResult", partName = "helloResult")
    public String hello(
        @WebParam(name = "helloParameters", partName = "helloParameters")
        String helloParameters);

}

Comparing this JAX-WS interface to the previous, you see that the @SOAPBinding annotation remains, but now it is not used for the parameter style, but rather the WSDL style.

Exploring the RPC/encoded patterns

There is no comparison for RPC/encoded style operations that can be made. JAX-WS does not support any mappings for WSDL documents that contain an encoded representation for the data. This comes from JAX-WS's compliance with WS-I's Basic Profile 1.1, which does not allow usage of encoded WSDL documents. There are good reasons to build an RPC/encoded Web service, in which case you should stick with the JAX-RPC mappings, but if you want to write interoperable Web services, you should not use RPC/encoded.


Considering other differences

A major difference in operation mapping for JAX-WS over JAX-RPC is the introduction of asynchronous operations. Any WSDL operation with a two-way message flow, or one where the client expects to receive a response, can be mapped to an asynchronous Java representation. There are two different mechanisms, asynchronous with a callback and asynchronous polling, that require two different mappings. A future article will describe how these two types of operations work. This article just shows you an example. Listing 12 contains an asynchronous callback operation, where the javax.xml.ws.AsyncHandler object is the callback object. Listing 13 contains an asynchronous polling operation mapping.

Listing 12. JAX-WS asynchronous callback
@WebMethod(action = "urn:samples.ibm.com/HelloWorld/hello")
@RequestWrapper(localName = "hello",
    targetNamespace = "urn:samples.ibm.com/HelloWorld", 
    className = "com.ibm.samples.helloworld.Hello")
@ResponseWrapper(localName = "helloResponse", 
    targetNamespace = "urn:samples.ibm.com/HelloWorld", 
    className = "com.ibm.samples.helloworld.HelloResponse")
public Future<?> helloAsync(
    @WebParam(name = "name", targetNamespace = "")
    String name,
    @WebParam(name = "asyncHandler", targetNamespace = "")
    AsyncHandler<String> asyncHandler);
Listing 13. JAX-WS asynchronous polling
@WebMethod(action = "urn:samples.ibm.com/HelloWorld/hello")
@RequestWrapper(localName = "hello", 
    targetNamespace = "urn:samples.ibm.com/HelloWorld", 
    className = "com.ibm.samples.helloworld.Hello")
@ResponseWrapper(localName = "helloResponse", 
    targetNamespace = "urn:samples.ibm.com/HelloWorld", 
    className = "com.ibm.samples.helloworld.HelloResponse")
public Response<String> helloAsync(
    @WebParam(name = "name", targetNamespace = "")
    String name);

There is no asynchronous mapping for WSDL operations in JAX-RPC, so you do not have anything to make a comparison to here. One important note, however, is that the asynchronous mappings only apply to the client side. No such asynchronous mappings exist for service endpoints, only for clients.

Comparing IN/OUT parameters

Both JAX-RPC and JAX-WS support parameters known as IN/OUT parameters. In Listing 14, you see an IN/OUT parameter added to the WSDL from Listing 1. Notice that the parameter with the name "inout" appears in both the input and the output. In this scenario, both JAX-RPC and JAX-WS map that parameter to a holder parameter, but the impact this has is different for each mapping.

Listing 14. A WSDL with an IN/OUT parameter
<xsd:element name="hello">
  <xsd:complexType>
    <xsd:sequence>
      <xsd:element name="name" nillable="true" type="xsd:string" />
      <xsd:element name="inout" nillable="true" type="xsd:string" />
    </xsd:sequence>
  </xsd:complexType>
</xsd:element>

<xsd:element name="helloResponse">
  <xsd:complexType>
    <xsd:sequence>
      <xsd:element name="response" nillable="true" type="xsd:string" />
      <xsd:element name="inout" nillable="true" type="xsd:string" />
    </xsd:sequence>
  </xsd:complexType>
</xsd:element>

Listing 15 has the JAX-RPC mapping for a holder parameter, and Listing 16 has the JAX-WS mapping.

Listing 15. JAX-RPC SEI with IN/OUT parameters
public interface HelloWorld extends java.rmi.Remote {
    public java.lang.String hello(
        java.lang.String name, 
        javax.xml.rpc.holders.StringHolder inout) throws java.rmi.RemoteException;
}
Listing 16. JAX-WS SEI with IN/OUT parameters
@WebService(name = "HelloWorld", targetNamespace = "urn:helloWorld/sample/ibm/com")
public interface HelloWorld {

    @WebMethod(action = "urn:helloWorld/sample/ibm/com/hello")
    @RequestWrapper(localName = "hello", 
        targetNamespace = "urn:helloWorld/sample/ibm/com", 
        className = "helloworld.sample.ibm.com.Hello")
    @ResponseWrapper(localName = "helloResponse", 
        targetNamespace = "urn:helloWorld/sample/ibm/com", 
        className = "helloworld.sample.ibm.com.HelloResponse")
    public void hello(
        @WebParam(name = "name", targetNamespace = "")
        String name,
        @WebParam(name = "inout", targetNamespace = "", mode = Mode.INOUT)
        Holder<String> inout,
        @WebParam(name = "response", targetNamespace = "", mode = Mode.OUT)
        Holder<String> response);

}

For JAX-RPC, there are a set of classes defined by the specification as holder classes for known types. These include types like java.lang.String and other primitive types. For user defined types, JAX-RPC requires that custom holder classes be generated that can handle the user-defined types. JAX-WS, on the other hand, makes use of the Generics feature in Java 5 to provide a single class that can work for all types, including user-defined types.

Another interesting thing to note here is the difference in return types. Rather than keeping the return type as JAX-RPC does, JAX-WS makes the method void and makes use of the holder for what was the return value. By rule in JAX-WS, when there is more than one parameter that can be considered an OUT parameter for an operation, the return type must be void, and all OUT parameters are mapped to holder types.


Summary

The above examples illustrate that, while there are a number of differences between JAX-RPC and JAX-WS, the mapping from WSDL to the structure of a service endpoint interface is very similar. The key differences are:

  • The package names are different.
  • JAX-RPC requires java.rmi.Remote and java.rmi.RemoteException, which JAX-WS does not.
  • Holders are defined differently.

Even with all the similarities that exist, there is one major difference that makes the JAX-WS SEI a very different entity from the JAX-RPC one. The use of JSR-181 annotations gives the JAX-WS SEI the capability to not only represent the Java-centric view of the Web service, but also the WSDL-centric view. A number of the annotations included are used to map the Java information back to WSDL constructs. This information does not exist in any form in a JAX-RPC SEI. Some of the other things that are exclusive to JAX-WS are the asynchronous invocation model and the fact that it does not require a generated SEI in the first place. On the other hand, JAX-RPC has something that JAX-WS does not: it supports an RPC/encoded WSDL.

Resources

Learn

Get products and technologies

  • Innovate your next development project with IBM trial software, available for download or on DVD.

Discuss

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into SOA and web services on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=SOA and web services
ArticleID=230403
ArticleTitle=Web services hints and tips: JAX-RPC versus JAX-WS, Part 3
publish-date=06132007