Java APIs for XML-based Remote Procedure Call (JAX-RPC) have reached the final recommendation stage at the Java Community Process as JSR 101. XML Web services vendors have started using this package as a core API for building interoperable Web services on the Java platform. In this series, I'll provide a step-by-step tour through the major features provided by this standard, using sample code to guide you along the way. By the end of this series, you will be familiar with the core features of the JAX-RPC specification; this knowledge will help service, client, and toolset developers design Web services that are as interoperable as possible.
For this discussion, I will assume that you are familiar with basic Web service concepts such as SOAP, WSDL, and XML. (See the Resources section below for more information on these and other relevant topics.) The code samples you'll encounter were all developed using Apache Axis beta 3 and Sun's Web Services Developer Pack -- in other words, they were developed using the reference implementation for the JAX-RPC specification.
This article is the first in a two-part series. I'll begin the discussion by tackling one of the most important aspects of JAX-RPC: the type-mapping system. This system enables the run-time system to map each XML type defined in a WSDL document to its corresponding Java type as specified by the Java service interface, and vice versa. This is a major step towards interoperable Web services. JAX-RPC specifies extensible type mapping support for an extended set of XML and Java types. The JAX-RPC run-time system implements a serialization framework to support this type mapping.
In a subsequent article, I'll build on the foundation I've established here and get into the nuts and bolts of the remainder of the specification.
As a Web service developer, you should already be familiar with the advantages and architectural flexibilities offered by Web services standards (SOAP, WSDL, XML). The concepts behind Web services help you design loosely coupled services with abstract interfaces, thus decoupling service implementation from service definition. The most important problem that faces the Web services community is the development of interoperable services. To meet this challenge, there are numerous efforts underway from various standard groups, including WS-I, OASIS, W3C, and SOAPBuilders, to define standards for interoperability (see Resources for more information).
JAX-RPC is a Java community effort to eliminate this problem and provide a well-known application programming interface (API) for Web service implementations on both the client and the server side. By adopting a standard API for Web services, JAX-RPC aims to help service users (clients) and service implementers get maximum flexibility by transferring the burden of service interoperability to the run-time infrastructure. The run-time framework can provide wire-level interoperability by adopting the global standards provided by standards organizations and using well-defined profiles (for example, WS-I) and creating IDEs and other development tools to match those standards.
At its core, JAX-RPC defines and uses an XML-based remote procedure call mechanism. It enables the server (that is, the service provider) to define its services using standard APIs and describe its services using WSDL; it enables the client (that is, the service consumer) to communicate with a server using standard APIs.
The specification is extensive (about 160 pages) and covers new programming patterns for Java developers. Here are the list of the concepts I'll discuss in this series:
- Type-mapping system
- Service endpoint
- Exception handling
- Service endpoint context
- Message handlers
- Service clients and service context
- SOAP With Attachments
- Run-time services
- JAX-RPC client invocation models
As noted above, this first article will focus only on the first concept: JAX-RPC's type-mapping system. In a future article, I'll examine the specification's other key concepts.
As I cover each topic, I'll illustrate important points with code for a sample Web service provided by a fictitious bookstore, hereafter called Acme Booksellers.
Figure 1. Acme Booksellers sample Web service application using JAX-RPC framework

This bookstore provides services that partners can use in various ways:
- Customers can search for books based on certain search criteria (ISBN, author name, etc.).
- Approved authors can upload updates of books.
- Reviewers can write reviews of books.
As you all know, there are two architectural approaches to Web service architecture and implementation:
- Top-down (that is, start with WSDL)
- Bottom-up (that is, start from a Java implementation class)
I will use the Acme Booksellers sample to explain how to use the top-down design and implementation that is consistent with JAX-RPC programming model. You can see the WSDL file for the sample service in the Sidefile. Once you've examined its code, you'll be ready to move on to the next section.
JAX-RPC's type-mapping system: An introduction
One of the most important achievements of the JAX-RPC specification is its definition of a standard for mapping a WSDL document (which represents a service description) to its Java representation (service endpoints, stubs, ties, and Java types), and vice versa. This was previously a major area of confusion, as each of the Web service toolkit vendors has its own interpretation of the relevant standards (WSDL, SOAP, and XML) and the relationships among them. The confusion multiplies because these standards are evolving in parallel and are not mature enough to rely upon.
Let's drill down to the details to see how JAX-RPC is trying to eliminate these problems by defining a common programming model. Note that this standardization effort is based on WSDL 1.1 and SOAP 1.1.
The section of the JAX-RPC specification concerned with WSDL to Java mapping addresses:
- The mapping of XML types to Java types.
- The mapping of abstract WSDL definitions (port types, operations, and messages) to Java interfaces and classes.
- The mapping of concrete WSDL definitions (ports, bindings, and services) to Java classes.
I'll consider each of these areas in turn.
Mapping XML types to Java types
Most of the simple XML data types defined by XML Schema and SOAP 1.1 encoding are mapped to their corresponding Java types. You can see the details of the mapping in Table 4-1 of the JAX-RPC specification (see Resources).
As a developer, you should keep a few points in mind on mapping simple XML types. First of all, the JAX-RPC mapping specification does not dictate a specific Java mapping for xsd:anyType.
Second, an element declaration with a nillable attribute set to true for a built-in simple XML data type is mapped to the corresponding Java wrapper class for a Java primitive type. For instance, the code below is mapped to java.lang.Integer.
<xsd:element name="code" type="xsd:int" nillable="true" /> |
This provides the flexibility in type system design to map null objects to their corresponding XML types. You can see the complete list of these mapping in Table 4-2 of the JAX-RPC specification (see Resources).
Finally, the SOAP 1.1 encoding specification maps most of its types as nillable. JAX-RPC maps these types using Java wrapped objects. See Table 4-3 of the JAX-RPC specification for more information.
XML Schema complex types are mapped to JavaBeans with getters and setters to access each element in the complex type. When dealing with these types, you need to keep a few things in mind. First off, it's important to note that no sequencing of elements is maintained in the JavaBeans even if the complex type contains xsd:sequence.
Also, complex types with a positive value for the element attribute maxOccurs map to a Java array of the corresponding type. Such a type does not define all possible combinations of minOccurs and maxOccurs. This may be problem for Java developers seeking to map all of the semantics associated with XML Schema.
Finally, one of the major problem areas of this mapping is XML element attributes mapping. Since there is no metadata associated with the Java classes, you may encounter a mapping problem when you try to convert JavaBeans to WSDL; hence, the JAX-RPC specification does not dictate how to map the xsd:attribute. However, in the case of a SOAP binding, you can use SOAPElement for this purpose. This may be rectified in future by a Java language extension; see the sidebar entitled "Metadata and JSR 175" for more on this.
Listing 1 below you shows how the complex type mapping works.
Listing 1. Complex type mapping in action
<xsd:complexType name ="Book"> <sequence> <element name="author" type="xsd:string" maxOccurs="10" /> <element name="price" type="xsd:float" /> </sequence> <xsd:attribute name="reviewer" type="xsd:string" /> </xsd:complexType> |
In Listing 2, you can see how the types in Listing 1 map onto JavaBeans with getter and setter methods.
Listing 2. Java mapping of types from Listing 1
Public class Book{
private float price;
private String[] author;
private String reviewer; // attribute
//....
public String[] getAuthor() {.......}
public setAuthor(String[] author) {.......}
public float getPrice() {.......}
public void setPrice(float price) {.......}
public String getReviewer() {.....}
public void setReviewer(String reviewer) {.....}
}
|
JAX-RPC maps XML arrays to Java arrays with the operator []. You can find several different kinds of array declarations in the WSDL service declaration.
The first type is an array derived from soapenc:Array by restriction using the wsdl:ArrayType attribute as specified by WSDL 1.1.
Listing 3. Defining an array with restriction and wsdl:ArrayType
<complexType name = "ArrayOfString">
<complexContent>
<restriction base="soapenc:Array">
<attribute ref="soapend:ArrayType"
wsdlArrayType="xsd:string[]">
</restriction>
</complexContent>
</complexType>
|
JAX-RPC maps these types of complex arrays to Java String[] with java.lang.Strings as elements in the array.
The next array type is derived from soapenc:Array by restriction as set down by the SOAP 1.1 specification.
Listing 4. Defining an array by restriction and soapenc:Array
<complexType name = "ArrayOfString">
<complexContent>
<restriction base="soapenc:Array">
<sequence>
<element name="stringArray" type="xsd:string"
maxOccurs="unbounded" />
</sequence>
</restriction>
</complexContent>
</complexType>
|
JAX-RPC maps these complex array types to Java String[], with java.lang.Strings as elements in the array.
Another kind of array declaration you can find in WSDL is seen below.
<element name="myNumbers" type="soapenc:Array" /> |
Listing 5 shows an instance of the above schema.
Listing 5. Mapping to a Java Object array
<myNumbers soapend:arrayType="xsd:int[2]" > <number>1</number> <number>2</number> </myNumbers> |
This declaration is mapped to a Java Object array, with individual elements of the array corresponding to the XML Schema type. (Here it maps to integer.)
Finally, you can also find arrays constructed from user-defined XML schema types. Listing 6 shows the definition of just such a type:
Listing 6. Defining a schema type
<complexType name="Article">
<all>
<element name="name" type="xsd:string">
<element name="author" type="xsd:string">
</all>
</complexType>
|
Now you need to define an array of type Article.
Listing 7. Defining an array with a user-defined schema type
<complexType name="ArrayOfArticles">
<complexContent>
<restriction base="soapenc:Array">
<sequence>
<element name="article" type="tns:Article"
maxOccurs="unbounded" />
</sequence>
</restriction>
</complexContent>
</complexType>
|
The above declaration in WSDL maps to a Java array of type Article (Article[] article;).
Mapping abstract WSDL types to Java types
Now that you understand how to map XML types to Java types, I'll consider the specific case of WSDL. First, I'll quickly examine how abstract WSDL types are mapped to their Java representations:
wsdl:porttype: This type is mapped to the service endpoint interface; it extends thejava.rmi.Remoteinterface. I will discuss service endpoint interfaces and their requirements in the next article in this series.wsdl:operation: Since WSDL 1.1 does not dictate that operation names need to be unique, there can be overloaded operations with the same name but different parameters. You should also remember that the JAX-RPC specification supports only one-way and request-response operations as defined by the WSDL specification; it does not support solicit-response or notification operation styles. You can specify the parameter order in the WSDL using the optionalparameterOrderattribute.
Let's take a look into the parameter passing styles. As outlined in Table 1, these can be in, out, and inout, depending on how the parameters are treated.
Table 1. Parameter passing style
| Parameter defined in | Parameter style | Possible JAX-RPC mapping classes | Sample JAX-RPC mapping class |
|---|---|---|---|
wsdl:input | in | Wrapper classes or JavaBeans | java.lang.Integer |
wsdl:output | out | Holder class | IntHolder, StringHolder, etc. |
wsdl:input and wsdl:output | inout | Holder class | IntHolder, StringHolder, etc. |
As shown Table 1, a new Holder class is defined in order to support out and inout parameters. The service client uses the Holder class instance to send the values of either the out or the inout parameter. The contents of the Holder class are modified by the remote method calls and the service client can use this changed content after the method invocation. Also note that the JAX-RPC specification defines a number of Holder classes to support the basic types. You can define your own Holder classes to support complex types by deriving from a standard interface called Holder.
Let me illustrate these points with some sample code. Listing 8 includes a sample WSDL definition.
Listing 8. Sample WSDL definition
<xsd:complexType name="Authors">
<xsd:all>
<xsd:element name="Authors" type="typens:AuthorArray"/>
</xsd:all>
</xsd:complexType>
<message name="AuthorPresentRequest">
<part name="Authors" type="typens:Authors"/>
</message>
<message name="AuthorPresentResponse">
<part name="return" type="xsd:boolean"/>
<part name="Authors" type="typens:Authors"/>
</message>
<portType name="AcmeAuthorPresentPortType">
<operation name="IsAuthorPresent">
<input message="typens:AuthorPresentRequest"/>
<output message="typens:AuthorPresentResponse"/>
</operation>
</portType>
|
You can see that the input and output messages contain an Authors type as a parameter. This is the inout style of parameter passing. This requires a Holder class for the Authors type, as shown in Listing 9.
Listing 9. Creating a sample Holder class for the Authors type
public final class AuthorsHolder implements javax.xml.rpc.holders.Holder {
public com.acme.www.Authors value;
public AuthorsHolder() {}
public AuthorsHolder(com.acme.www.Authors value) {
this.value = value;
}
}
|
Finally, Listing 10 shows how to implement the Java endpoint.
Listing 10. Java endpoint implementation
public interface AcmeAuthorPresentPortType extends java.rmi.Remote {
public boolean isAuthorPresent(AuthorsHolder authors) throws java.rmi.RemoteException;
}
|
You need to understand how the name of a service endpoint interface and the signature of the endpoint methods are derived. They can be derived either from the wsdl.portType's name attribute and operation definition, or from the wsdl.binding name and operation declaration. This is an important point to keep in mind, as there can be multiple bindings with different styles (for example, RPC/document) pointing to the same portType. This difference in binding style may result in the creation of a different endpoint with a different name and signature. Thus, you should be on guard against this confused mapping.
Mapping concrete WSDL types to Java types
Now turn your attention to the concrete WSDL elements, along with their Java mappings.
wsdl:binding: JAX-RPC does not define any standard Java representation for wsdl.binding. This means that the runtime can define the bindings required. At the least, the JAX-RPC run-time system should provide support for SOAP binding with:
- RPC style with operation mode encoded (RPC/encoded).
- Document style with operation mode literal (document/literal).
In the case of literal mapping, each message part is mapped to a Java type, as I described earlier in the previous Mapping XML Types to Java Types section. If no such mapping exists, the message part is represented using a javax.xml.soap.SOAPElement Java class. An example for this mapping is a complex type containing attributes. Since no standard mapping is defined for attributes, this complex type is represented as a SOAPElement.
See the sidebar entitled SOAP Messaging Style and Operation Encoding and Table 2 for more on these different styles and modes.
Table 2. SOAP message styles and JAX-RPC
| Style (SOAP message body format) | Mode (parameter encoding) | JAX-RPC related information |
|---|---|---|
| Document (uses a schema to define body format) | Literal (uses XML Schema for each parameter encoding) | Required |
| Document | Encoded (using SOAP Section 5 encoding) | Optional |
| RPC (using SOAP Section 7 rules to define body format) | Encoded | Required |
| RPC | Literal | Optional |
wsdl:service: This WSDL concrete definition groups a set of service endpoints (or wsdl:ports). JAX-RPC maps wsdl:service to a Java service class. This service class implements the javax.xml.rpc.Service interface or a generated Java interface mapped to the wsdl.service definition, which in turn implements javax.xml.rpc.Service.
This service class acts as a factory for:
- A dynamic proxy for a service endpoint (more on which in the next installment in this series). You can create the dynamic proxy by using the
getPort(..)methods in the service object. - An instance of the type
javax.xml.rpc.Callfor the dynamic invocation of a remote operation on a service endpoint (more on which in the next installment in this series). The dynamic invocation interface requires aCallobject to be created at runtime. For that, you can use thecreateCall(..)operation on the service class. - An instance of a generated stub class (more on which in the next installment in this series). These stubs are provided by the generated classes, which are created by tools.
The implementation of the Service interface is the responsibility of the JAX-RPC run-time system. There can be different implementations of stubs based on the binding requirements. Also note that the Service implementation class should implement either the java.io.Serializable or the javax.naming.Referenceable interface to support registration in the JNDI namespace.
Of course, a sizable portion of the JAX-RPC specification discusses mapping Java types to XML types, and mapping Java service endpoint interfaces to WSDL definitions. Such mapping is similar to what I've already covered here, but the process is reversed. I am not going to explain this process in detail here. Please refer to Section 5 of the JAX-RPC specification for more information. This is a bottom-up architecture for Web service design and is mainly used to convert existing Java-based applications to Web services or to create wrappers around those applications.
In this article, I have discussed JAX-RPC's support for simple type mapping. This is a core concept you need to understand to achieve maximum interoperability between Web service implementations. Though the current type mapping listings are elaborate, they are not extensive enough to support all the requirements of the data types. Thus, JAX-RPC run-time implementers are free to support other extensible type-mapping mechanisms through custom serializers.
I hope that this discussion on type mapping support in JAX-RPC helps you grasp the basic concepts of how the JAX-RPC system works with XML and Java types, and how each of those types can be converted to the other without losing its semantics.
In the next part of this series, I will discuss the other aspects of the JAX-RPC specification including service implementation, service clients, and other core concepts. Until then, work on mastering the type mapping information outlined here.
-
Check out the second installment in this series, Developer's introduction to JAX-RPC, Part 2. (developerWorks, January 2003).
-
Get the JAX-RPC specification from the source, the Java Community Process.
-
The reference implementation for the JAX-RPC specification is based on Apache Axis beta 3 and Sun's Web Services Developer Pack. The code for this article has been tested using these technologies.
-
You can also experiment with the latest version of IBM Web Services Toolkit, available from alphaWorks.
-
You may find it handy to consult the following W3C specifications while reading
this series: WSDL; XML; SOAP.
-
The following groups strive to preserve Web services interoperability: WS-I; W3C; OASIS.
- For more on Web services type mapping, check out Part 1
and Part 2
of Gavin Bong's series, "Apache SOAP Type Mapping" (developerWorks, March
2002).

Joshy Joseph is a software engineer working with the IBM OGSA development team. His primary programming interests are working with emerging technologies like Web services, the semantic Web, and REST and Grid computing, as well as using programming models based on UML, AOP, and XP. You can contact him at joshy@us.ibm.com.





