Jax-Ws vs Jax-Rpc: Comparison and Differences
In this article, we will compare the JAX-WS and JAX-RPC programming APIs with respect to the Java programming model.
Note: This article is for academic purposes only. JAX-RPC is obsolete and its use is discouraged for any new Java development projects.
1. Introduction
The Web Services Architecture evolved in part to address interoperability between disparate and heterogeneous systems. SOAP (Simple Object Access Protocol) was designed to be an agnostic message format for exchanging messages. WSDL (Web Service Description Language) was developed to describe web services and how to access them. JAX-RPC (Java API for XML-based Remote Procedure Call) was subsequently introduced to specify how to write Java web services components for disparate systems using SOAP and WSDL.
JAX-RPC is based on the RPC programming model for invoking operations of a web service. The RPC programming model invokes stubs located on the client to call methods on a remote server.
JAX-WS is the successor to JAX-RPC. JAX-WS provides support for message-oriented web services. This model allows service requests to be sent asynchronously. Additionally, JAX-WS provides support for the more recent versions of the following specifications: SOAP, WSDL, WS-I BP (Basic Profile), and SAAJ (SOAP with Attachments API for Java).
2. Comparison and Differences
Let’s take a look at some other differences between these two APIs as they pertain to the Java programming model.
2.1 Java 5
Java 5 introduced new features to the Java API, such as annotations, generics, and executors. JAX-WS relies on many of these features and requires the Java 5 compile and runtime components. This union is a boon to developers as it simplifies the development process. For example, annotations can be used to expose endpoints and clients as web service components within the code itself instead of using XML descriptor files, WSDL files, and data mapping XML files, which can be tedious to work with. By including annotations within the Java classes, you encapsulate the metadata with the source files.
Also, mapping tools used for top-down or WSDL-first Java development (such as the WSDL2Java tool) will generate Java classes with annotations.
Here is an example of how to define a Service Endpoint Interface (SEI) as a web service using an annotation:
HelloWorld.java
import javax.jws.WebService; @WebService public interface HelloWorld { public String sayHello(String name); }
There are two things to note here:
- The
@WebService
annotation communicates to the JAX-WS runtime to expose all public methods on this bean as web service operations. - JAX-WS does not require the SEI to extend
java.rmi.Remote
, as is the case with JAX-RPC, since it does not use the RPC programming model.
You can fine-tune the web service by adding additional annotations on individual methods and parameters. Here are some common annotations used.
Note: These annotations are part of the javax.jws
package.
Annotation | Description |
@WebMethod | Used to indicate that this method is a web service operation. Typically used when specific public methods in the class should be exposed as web service operations. |
@WebParam | Used to map the name of the parameter to the element in the WSDL file. |
@WebResult | Used to map the name of the result response to the element in the WSDL file. |
Here is an example of how these annotations are used:
Other Web Service Annotations Example
@WebMethod() @WebResult(name="NumberOutput") public int echoNumber( @WebParam(name="NumberInput") int input) { System.out.println("echoNumber '" + input + "' back to you."); return input; }
The JAX-RPC programming model was based on the older 1.4 version of Java.
2.2 Asynchronous Invocation of Web Services
When invoking a web service synchronously, the client must wait for the response before resuming its work. When invoking a web service asynchronously, the client can work on other tasks while it waits for the response.
JAX-WS supports both the callback and polling methods of invoking a web service asynchronously. When using the callback method, the client provides a callback handler to accept and process the response.
When using the polling method, a client issues a request and receives a response object, which is polled intermittently to check if the server has responded. When the server responds, the actual response is acquired.
Here is an example of a Service Endpoint Interface with methods for both synchronous and asynchronous requests:
ChangeMessage.java
import java.util.concurrent.Future; import javax.jws.WebService; import javax.xml.ws.AsyncHandler; import javax.xml.ws.Response;; @WebService public interface ChangeMessage { // sync operation public String changeMessage(String message); // async operation with callback public Future changeMessageAsync(String message, AsyncHandler asyncHandler); // async operation with polling public Response changeMessageAsync(String message); }
Asynchronous method names are suffixed with “Async” as this is the naming convention. The AsyncHandler callback handler is provided by the caller and is responsible for handling the response when using the callback method. The method returns a Future
that represents the pending result of the task. The Future interface exposes methods to test for completion of a task and to retrieve the result of the task.
The client receives an object of type javax.xml.ws.Response
when using the polling method,. The Response object is polled to determine when the operation is complete and to get the actual result, as described earlier.
JAX-RPC does not support asynchronous invocation of a web service.
2.3 Java-XML Data Binding
SOAP-based web services use XML to exchange request and response messages. This requires an architecture for converting Java objects to XML and the reverse. JAXB (Java Architecture for XML Binding) was developed for this purpose.
JAX-RPC uses its own data mapping model. This is because the JAXB specification had not been finalized when when the first version of JAX-RPC was completed. The JAX-RPC data mapping model lacks support for some XML schemas.
JAX-WS uses JAXB for data binding. JAXB provides mapping for virtually all schemas.
You can use JAXB annotations on your Java bean and JAX-WS will convert it and its properties to XML elements at runtime when sending the SOAP message.
Person.java
import javax.xml.bind.annotation.*; @XmlRootElement(name = "person") @XmlType(propOrder = {"id","name"}) public class Person { @XmlElement(name = "id", required = true) int ID; @XmlElement(name = "name", required = true) String Name; // accessors and mutators }
Sample SOAP Request
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" > <soapenv:Header/> <soapenv:Body> <addPerson> <person> <id>0</id> <name>This Person</name> </person> </addPerson> </soapenv:Body> </soapenv:Envelope>
The following table describes the JAXB annotations used in the code example above.
Annotation | Description |
@XmlRootElement(name = “preferredName”) | Defines the root element for an XML tree |
@XmlType(propOrder = { “field2”, “field1”,.. }) | Used to define the order in which the fields are written in the XML file |
@XmlElement(name = “newName”) | Define the XML element name to use for this property. This is only used if the “newName”is different than the JavaBean name |
2.4 SOAP Message Attachments and MTOM
JAX-RPC uses the SOAP with Attachments (Sw/A) model for exchanging binary data and uses the SAAJ specification. The SAAJ specification includes the javax.xml.soap
package and provides the API for creating and populating a SOAP message. The following example shows how to create and populate a SOAP message using SAAJ:
SAAJ Example
// Create a message. This example works with the SOAPPart. SOAPMessage request = mf.createMessage(); SOAPPart part = request.getSOAPPart(); // Obtain the SOAPEnvelope and header and body elements. SOAPEnvelope env = part.getEnvelope(); SOAPHeader header = env.getHeader(); SOAPBody body = env.getBody(); // Construct the message payload. SOAPElement operation = body.addChildElement("sayHello", "http://com/javacodegeeks/example/helloworld/"); SOAPElement value = operation.addChildElement("name"); value.addTextNode("Java Code Geeks");
While JAX-WS also supports Sw/A, it adds support for Message Transmission Optimization Mechanism (MTOM). MTOM is a web service standard for optimizing the transfer of binary data in a SOAP message. The standard specifies the message format for packaging base64Binary data (such as an image file or PDF file).
For example, you can add the following annotation to the SEI implementation to indicate that the web service should use MTOM optimization:
FileServiceImpl.java
// This example is for SOAP version 1.2. @BindingType(value = SOAPBinding.SOAP12HTTP_MTOM_BINDING) @WebService public class FileServiceImpl { ... }
Here is an example on how to enable MTOM on the web service client:
MTOM Client Example
import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import javax.activation.DataHandler; import javax.xml.ws.BindingProvider; import javax.xml.ws.soap.SOAPBinding; public class AttachmentClient { static FileAttachmentService service; static FileAttachment port; public static void main(String[] args) { service = new FileAttachmentService(); port = service.getFileAttachmentPort(); BindingProvider bp = (BindingProvider)port; SOAPBinding binding = (SOAPBinding)bp.getBinding(); //Enable MTOM.. binding.setMTOMEnabled(true); DataHandler downloadfile = port.downloadFile(); try (InputStream input = downloadfile.getInputStream(); OutputStream output = new FileOutputStream( new File("/Users/gilbertlopez/uploaded/testingfile.jpg"));) { byte[] b = new byte[100000]; int bytesRead = 0; while ((bytesRead = input.read(b)) != -1) { output.write(b, 0, bytesRead); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); System.exit(-1); } System.exit(0); } }
These are the steps for enabling MTOM on the web service client:
- Instantiate a
BindingProvider
from the web service port. - Instantiate a
SOAPBinding
from the BindingProvider. - Set the MTOM enabled property of the SOAPBinding to
true
.
JAX-WS leverages JAXB, which provides APIs for marshalling and unmarshalling both Sw/A and MTOM attachments.
JAX-RPC does not provide MTOM support.
2.5 Dynamic Clients
Both JAX-RPC and JAX-WS hide the details of mapping Java method invocations to the underlying SOAP messages. Both use a dynamic invocation interface (DII) to call operations on the web service.
JAX-RPC clients use javax.xml.rpc.Call
for this purpose. Here is an example:
JAX-RPC Dynamic Client Example
// Create the dynamic invocation object from this service. Call call = service.createCall(); call.setTargetEndpointAddress( "http://localhost:8080/HelloWorldService/services/port"); // Build the message. QName operationName = new QName( "urn:helloWorld/example/javacodegeeks/com", "sayHello"); call.setOperationName(operationName); call.addParameter( "name", // parameter name XMLType.XSD_STRING, // parameter XML type QName String.class, // parameter Java type class ParameterMode.IN); // parameter mode call.setReturnType(XMLType.XSD_STRING); // Invoke the operation. Object[] actualArgs = {"Java Code Geeks"}; String response = (String) call.invoke(actualArgs);
With JAX-RPC, the Call object is configured to invoke a specific operation from the WSDL.
In some cases, working at the XML message level is preferred. JAX-WS allows this capability by providing the javax.xml.ws.Dispatch
interface. In JAX-WS’s messaging model, the Dispatch object is not concerned about the operation being invoked and is only sending XML data. Here is an example:
JAX-WS Dynamic Client Example
// Create a service and add at least one port to it. Service service = Service.create(serviceName); service.addPort(portName, SOAPBinding.SOAP11HTTP_BINDING, "http://localhost:8080/HelloWorldService/services/port"); // Create a Dispatch instance from a service. Dispatch dispatch = service.createDispatch(portName, SOAPMessage.class, Service.Mode.MESSAGE); // Create SOAPMessage request. // compose a request message MessageFactory mf = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL); // Create a message. This example works with the SOAPPART. SOAPMessage request = mf.createMessage(); SOAPPart part = request.getSOAPPart(); // Obtain the SOAPEnvelope and header and body elements. SOAPEnvelope env = part.getEnvelope(); SOAPHeader header = env.getHeader(); SOAPBody body = env.getBody(); // Construct the message payload. SOAPElement operation = body.addChildElement("sayHello", "http://com/javacodegeeks/example/helloworld/"); SOAPElement value = operation.addChildElement("name"); value.addTextNode("Java Code Geeks"); request.saveChanges(); // Invoke the service endpoint. SOAPMessage response = dispatch.invoke(request);
The javax.xml.ws.Service
object acts as a factory for creating:
- Proxies for a target service endpoint.
- Instances of Dispatch for dynamic message-oriented invocation of a remote operation.
There are several methods available to create a Dispatch client. In the example above, it is created by calling the createDispatch
method with the following parameters:
endpointReference
– The EndpointReference for the target service endpoint that will be invoked by the returned Dispatch object.type
– The class of object used for messages or message payloads. Implementations are required to supportjavax.xml.transform.Source
andjavax.xml.soap.SOAPMessage
.mode
– Controls whether the created dispatch instance is message or payload oriented, i.e. whether the client will work with complete messages or message payloads. The Mode must beMESSAGE
when the type isSOAPMessage
.
The dispatch client is an XML messaging oriented client. Data is sent in either PAYLOAD
or MESSAGE
mode. When using the PAYLOAD
mode, the dispatch client is responsible for providing the contents of the SOAP body only and JAX-WS adds the SOAP envelope and header. When using the MESSAGE
mode, the dispatch client is responsible for providing the entire SOAP envelope including the SOAP header and body. This example uses the MESSAGE
mode since the “type” parameter is SOAPMessage
.
As you can see, the difference between the two is that JAX-RPC follows the RPC model, while JAX-WS follows a messaging model.
3. Conclusion
Although JAX-RPC is still supported by some application server vendors, it does not provide support for the latest web services specifications and standards and is, for all intents and purposes, obsolete. For that reason, JAX-WS should be used when developing SOAP-based web services.
Thanks for the great article. I know its bee a while, but hoping I can get some clarification…We are in the process of a tech refresh and are planning to move our JAX-RPC webservices from websphere 8.5 to weblogic 12.2.x( company preferences) . This is going to be a interim solution with the webservices being replaced eventually, so prefer to keep the effort low for both us the service providers & consuming clients. If we do upgrade the webservices to JAX-WS, will it be transparent to the JAX-RPC clients?Or do the JAX-RPC based clients need to make any code/configuration changes… Read more »