Skip to main content

A developer's introduction to JAX-RPC, Part 2: Mine the JAX-RPC specification to improve Web service interoperability

Get acquainted with the details of this emerging standard

Joshy Joseph, Software Engineer, IBM OGSA Development Team
author
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.

Summary:  In the first article in this series, Joshy Joseph discussed a key aspect of the JAX-RPC standard: its type mapping system. Now that you understand how JAX-RPC maps XML types to Java types, you're ready to explore this specification in earnest, including its exception handling facilities and potential run-time services. When you've finished this article, you'll be ready to start building Java-based interoperable Web services.

Date:  01 Jan 2003
Level:  Introductory
Activity:  13484 views

The 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've taken you through a step-by-step approach through the major features provided by this standard, using sample code to guide you along the way.

In the first part of this series, I described the mapping between WSDL/XML types and Java types, and vice versa. I explained how the JAX-RPC standard defines this feature and some of the important points on designing an interoperable type system. To some extent, this type mapping standard helps the Web service run-time system achieve message-level interoperability.

In this second installment of the series, you'll learn how you can achieve the next level of Web service interoperability using the JAX-RPC standard's client- and server side interface definitions and message processing model.

As you'll recall, the JAX-RPC specification covers the following topics:

  • 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, in Part 1 of this series, I covered important aspects of JAX-RPC's type-mapping system. Now I'll explore the high points of the rest of the specification. As I did in Part 1, I'll illustrate the points here with code from a sample Web service for Acme Booksellers; see Part 1 for more on the example, and see the Sidefile for the example's complete WSDL listing. (See Resources for further information.)

Service endpoint

A JAX-RPC service endpoint refers to a Web service endpoint where the real service implementation lies. As you can see in Figure 1, there is a service endpoint implementation (concrete) class and a service endpoint interface definition.


Figure 1. Service implementation interface hierarchy
Service implementation interface hierarchy

Service endpoint interface

A Web service endpoint class is derived from the service endpoint interface created from the WSDL definitions using WSDL2Java, a WSDL-to-Java mapping tool provided by Apache Axis. These service endpoints must conform to the service endpoint interface definition as prescribed by Section 5.2 of the JAX-RPC specification. Some of the requirements of this definition are:

  • All service endpoints must extend the java.rmi.Remote interface.
  • All methods implemented by this interface must throw a java.rmi.RemoteException. There can be application-specific exceptions in addition to this standard exception.
  • The method parameters must be JAX-RPC-supported Java types. In this way, the specification assures a proper serialization/deserialization mechanism for the Java platform and its corresponding XML types.
  • Normally, Java interfaces can hold constant data using public static final declarations. However, the JAX-RPC specification discourages you from doing so, stating that WSDL 1.1 doesn't have a standard representation for constants in wsdl.porttype.
  • You can use Holder and SOAPElement classes as arguments to interface methods. (See Part 1 of this series for more information on Holder and SOAPElement classes.)

Listing 1 contains an example of a service endpoint interface.


Listing 1. Service endpoint interface
		
Public interface AuthorSearchService implements java.rmi.Remote{
Public Books[] seachForAuthor(String authorName) throws java.rmi.RemoteException,
com.acme.InvalidAuthorName;
}

Note that the sample endpoint interface in Listing 1 is handling both run-time RemoteExceptions and application-level InvalidAuthorNames. I'll take a closer look at the semantic meaning and relation of these application exceptions (in the context of WSDL) when I describe JAX-RPC exception handling.

Also note that one of the major implementation differences between SOAP-based distributed systems and distributed systems based on other protocols (for example, RMI) is that the former does not support passing and returning objects by reference. Hence, you should avoid creating a service endpoint that uses a remote reference as a parameter or return value. In addition, the Java value types and arrays should not hold a remote reference.

Some vendors (for example, WASP) have implementations that support remote object references. But code written for these implementations may lack portability across run-time systems. For instance, the code in Listing 2 may not be supported by all JAX-RPC systems, as the BookSearchBroker object is returned by reference.


Listing 2. Potentially nonportable code
		
Public interface BookSearchBroker extends java.rmi.Remote{
Public Books[] searchForAuthor(String tickerSymbol) throws java.rmi.RemoteException;
}

public interface StockQuote extends java.rmi.Remote{
public BookSearchBroker getBooksSearchBroker() throws java.rmi.RemoteException;
}

Service endpoint implementation class

The service endpoint implementation class is derived from the service endpoint interface. In addition to that interface, this service endpoint implementation class may implement the ServiceLifecycle interface for managing the service's life cycle (see Figure 1). This interface is declared as shown in Listing 3.


Listing 3. ServiceLifecycle interface declaration
		
Public interface ServiceLifecycle{
     void init (Object context) throws ServiceException;
     void destroy();
}

As you can see, this interface enables the JAX-RPC run-time system to manage the life cycle of a Web service instance. (This run-time system is a servlet container if the service implementation is a servlet.) The run-time system is responsible for loading the service endpoint class and instantiating it. After instantiation, it invokes the ServiceLifecycle.init() method to initialize the service instance. ServiceLifecycle.init() expects the run-time context (ServiceContext) as a parameter. I will discuss the run-time context in more detail in the section entitled "Service Context" below.

As you develop a service endpoint class, you must ensure that this endpoint does not maintain any state pertaining to a client. The run-time system may dispatch multiple client invocations to the service endpoint interface to this single instance. Also note that these service endpoint instances can be pooled by the run-time system for better performance.

The run-time system must also invoke the ServiceLifecycle.destroy() method when the run-time system removes the endpoint from servicing the clients. This helps the service class instance relinquish the resources it is using.


Exception handling

You can see that the JAX-RPC specification tries to address Web service run-time exceptions, at both the application level and the runtime-system level, based on the standard approach to service endpoint interface design and its mapping to wsdl.fault elements.

The service-specific exceptions are declared in the wsdl.fault element, and these exception types are derived from the java.lang.Exception class. The wsdl.operation declaration in Listing 4 includes specific wsdl.fault elements.


Listing 4. wsdl.operation declaration
		
<message name="AuthorNotFoundException">
     <part name="Author" type="xsd:string" />
</message>

<portType name ="BookSearch">
     <operation name="getBooksByAuthor" >
          <input message="tns:getAuthorName">
          <output message="tns:getBookList">
          <fault name=" AuthorNotFoundException" message=" tns: AuthorNotFoundException">
     </operation>
</portType>

In Listing 5, you can see how the JAX-RPC specification creates its service endpoints to address the service-specific Java exception.


Listing 5. Addressing the service-specific Java exception
		
Public interface BookSearch implements java.rmi.Remote{
Public Books[] getBooksByAuthor(String authorName) throws java.rmi.RemoteException,
com.acme.AuthorNotFoundException;
}

Listing 6 contains the Java exception class that is created as a result.


Listing 6. Java exception class
		
public class AuthorNotFoundException extends java.lang.Exception{
     ...........
     public AuthorNotFoundException(String Author ){
     .....
     }
     public getAuthor(){...}
}


Service endpoint context

JAX-RPC allows the run-time system to manage the context information (note that the ServiceLifecycle.init() method expects a context of type Object) in a flexible way. Each run-time environment can maintain its own distinct context information. For example, a servlet-based run-time system maintains a ServletEndpointContext object. The EJB 2.1 specification defines the EJB SessionContext.

As an example, let's explore a servlet-based run-time system and see how it manages context information. This servlet endpoint context contains information including user principal, message context, HTTP-based user session information, and servlet context. The specification requires that the service runtime maintain all this information between remote method invocations on a service endpoint instance. As you can see from the service context interface in Listing 7 below, this is very valuable information that a service can make use of in a number of ways:

  • HTTP session information helps the client maintain an HTTP session with the server. This is an optional feature.
  • The user principal (if the run-time system has already authenticated this user) helps the service developer validate the user for specific run-time actions.
  • Another nice feature provided by this interface is its support for SOAP message context propagation. This helps the service implementer obtain the SOAP message context from the request handler chain, and manipulate that context and associate it with the response handler chain.

In short, this interface provides dynamic run-time information about the details of the caller, the message, and the current environment.

Listing 7 shows you how to extend your service implementation class to support life cycle management and how to use the service context.


Listing 7. Service context interface
		
Public interface BookSearchServiceImpl implements java.rmi.Remote, javax.xml.rpc.server. 
ServiceLifecycle {
     public void init(Object context) throws ServiceException{
               ServletEndpointConext sC = (ServletEndpointConext)context;
          Java.security.Principal userPrinciple = sC. getUserPrincipal();
          HttpSession session = null;
          Try{
             session = sC.getHttpSession();
          }catch(JAXRPCException e){ // Not an HTTP based 
                                     //endpoint
          }
          MessageContext ctx = sC.getMessageContext();
     }
     public void destroy(){
     }
     public Books[] searchForBooks(String authorName) 
     throws java.rmi.RemoteException, com.acme.InvalidAuthor{
          return null;
     }
}


Message handlers

Now let's consider the most powerful feature of the JAX-RPC specification, the message handler. Message handlers provide additional message-handling facilities to Web service endpoints (both client and server) as extensions to the basic service implementation logic. Handlers can manage encryption and decryption, logging and auditing, and so on. The current JAX-RPC run-time system defines only SOAP message handlers, but it can flexibly define other handlers and is free from any processing model of the messages.


Figure 2. Service and handler invocation model
Service and handler invocation model

The JAX-RPC Handlers API defines three basic methods, along with two life cycle methods, as shown in Listing 8.


Listing 8. Handler methods
		
public class Handler{
     handleRequest(MessageContext context)
     handleResponse(MessageContext context)
     handleFaults(MessageContext context)

     init(HandlerInfo info);
     destroy();
     ...........
}

A handler should be implemented as a stateless instance. By providing the initialization interface (Handler.init (HandlerInfo info)), the run-time system can pass the required context information to the handler. This will help a handler obtain access to container-specific value-added features, including authentication mechanisms, transaction processing, a logging framework, etc.

Handler implementation and JSR 109

Before you develop JAX-RPC handlers for your J2EE container, you need to consult your J2EE container vendor. According the Implementing Enterprise Web Services specification (JSR 109), handlers run at application execution context and hence can support only limited functionality. To better understand this container-imposed limitation, consider the case of security: You may not be able to write a JAX-RPC handler to support WS-Security for authentication and authorization at the application level. This decision should be made prior to the application execution. Please consult your J2EE container vendor's documentation on Web services to find out more. For more on JSR 109, see the Resources below.

You are free to derive new handlers from the default handlers provided by the API, from SOAP message handlers (with SOAPMessageContext as a parameter), or from a generic handler. Handlers are permitted to modify the messages passed to them. Since these handlers are very flexible for security reasons, most of the frameworks currently available will manage them under the run-time system's control. For example, in a J2EE container, a handler may be a part of the J2EE container. Thus, you should refer to your application server (runtime) vendor's documentation to find out more about the built-in handlers provided with the product you're using. These built-in handlers may be for WS-Security, WS-Transaction, logging, etc. Even though you can write your own JAX-RPC handlers, the application server vendor can decide, based on configuration and security policies, whether to allow a new handler or not.

Handler chains

A handler chain represents an ordered list of handlers. This grouping helps you define policies that you want associated with the handler invocation model. Examples of such policies include order of invocation, style of invocation (for example, a one-way call invokes only handleRequest(); no handleResponse()), etc. Another possible policy you can set on the handler chain: A handler chain can invoke a handler based on the qname of the outermost element of a SOAP header. This association can be configured to the handler through the Handler.init() method passing a HandlerInfo object. The handler chain continues processing the handlers only if the current processing handler returns true.

You can associate a handler chain with SOAP actors (or roles; see the SOAP 1.1 specification for more details; you can find a link in the Resources section below) by specifying the URIs of the actors. By default, a handler chain is always associated with the special SOAP actor next. A handler chain is registered on a per service endpoint basis, as indicated by the qualified name of the WSDL port.

Listing 9 shows a sample implementation of a handler that can access a SOAP message header.


Listing 9. Sample handler
		
Public class AcmeSOAPHeaderHandler extends GenericHandler{
     Public Boolean handleRequest(MessageContext ctx){
          try{
          SOAPMessageContext mc = (SOAPMessageContext)ctx;
          SOAPMessage msg = mc.getMessage();
          SOAPPart sp = msg.getSOAPPart();
          SOAPEnvelop se = sp.getEnvelop();
          SOAPHeader header= se.getHeader();
          // Now we can process the header
          if (everything fine )
               return true; // chain handlers 
                            //continue processing
          else{
                    //Return false results in chaining to stop
               return false; 
              }
          }catch(Exception ex){
          }
     }
}


Service clients and service context

One of the beauties of JAX-RPC for the client is its ability to associate context information with an endpoint's remote method call. Note that the semantics of context information is not mandated by the JAX-RPC specification. It may be defined explicitly by the user, based on SOAP header definitions in WSDL binding; it may be defined based on standards such as WS-Security; or it may be defined by using binding-specific details -- an HTTP request header, say.

This run-time context information can be set either by the container or by the client. Container-managed context management is called implicit context management, while client-managed management is called explicit context management.

The term implicit is used because in implicit context management there are no programming requirements at either the client or the server to support the context propagation; such support is the responsibility of the run-time engine. Examples of such context information include security and transaction information.

The explicit service context is represented as additional parameters appended to the service method calls. This may introduce problems when mapping from Java parameters to WSDL, as these additional parameters map to WSDL headers. Listing 10 shows a WSDL definition with soap:header information and the explicit service context representation through the endpoint Java interface.


Listing 10. Endpoint Java interface for a WSDL definition
		
public interface BookSerachService implements java.rmi.Remote{
     public Books[] searchForBooks(String authorName, StringHolder context) 
     throws RemoteException;
}

In Listing 10, you can see that the context is added to the method parameter.

The JAX-RPC specification does not mandate a server-side model for processing the service context. It is up to the container vendor (for either implicit or explicit context management) and the programmer (for explicit context management) to define the handlers to process the service context. As you can see, this makes context routing and setting up the header message processors more flexible.


SOAP With Attachments

The JAX-RPC specification APIs support the use of MIME-encoded contents in remote procedure calls and/or return values. This is based on the SOAP With Attachments standard (see Resources). SOAP messages with attachments are created using the MIME multipart/related type. The root part is the original SOAP message, and the MIME contents are added as other parts of the message. These SOAP parts may contain references to the MIME part. Also note that each MIME part contains content ID or content location information to uniquely identify the MIME parts. See the Figure 3 below for a sample MIME message.


Figure 3. SOAP message package
SOAP message package

The remote method in a Java service endpoint interface may use one of several Java types to represent MIME-encoded content:

  • The JAX-RPC specification provides a set of Java classes that are direct mappings to MIME types. Examples include:

    • Image/gif maps to java.awt.image
    • text/plain maps to java.lang.string
    • text/xml maps to javax.xml.transform.Source


    Please see Section 7.5 of the JAX-RPC specification for the list of complete mappings. (You can find a link to this specification in Resources.)
  • javax.activation.DataHandler can map any MIME type.

The JAX-RPC run-time system determines the MIME type of the MIME part using:

  • The MIME type defined using the mime.content element in WSDL
  • Content-Type of the MIME part in the SOAP message

Run-time services

There are certain requirements that need to be supported by the JAX-RPC run-time infrastructure. I'll discuss two of the most important here.

Security

The JAX-RPC run-time system must support basic HTTP authentication. Clients send a user name and password to the HTTP server and they are validated there (the HTTP server is considered part of JAX-RPC run-time system). All other security mechanisms (digital certificates, SSL, WS-Security, etc.) are value-added features offered by client and server JAX-RPC run-time systems. These may be handled using JAX-RPC handlers and service context propagation. You can refer to the system documentation for your particular runtime for more details.

Session management

This requirement enables the client to participate in a session with the service endpoint. A JAX-RPC run-time system should support at least one of the following:

  • Cookie-based session management
  • URL rewriting
  • SSL sessions

The server initiates this session-management process. You can indicate a client's readiness to support the session by setting the session.maintain property to true. See the sample for more information on how to do this.

One of the most obvious omissions from JAX-RPC's session management is a requirement for SOAP header-based session correlation, which is currently supported by most of the toolkits. You can assume that the next iteration of the specification will dictate this once you have defined a standard approach for session management and all parties have agreed on WS-I profiles and other standards.


JAX-RPC client invocation models


Figure 4. JAX-RPC at the client side
JAX-RPC at the client side

There are three different models for invoking a service endpoint from a client, as shown in Figure 4. They are independent of any specific service implementation model. I'll discuss the details of each in turn.

  • Stub-based model (static stubs). There are two ways in which you can create service stubs:

    • From the Java service endpoint interfaces
    • From the WSDL description of the service


    You can generate a stub class either from WSDL (using WSDL2Java) or from a service endpoint interface. A generated stub class is required to implement both javax.xml.rpc.stub and the service endpoint interface. This stub interface provides APIs to configure stubs by setting properties like endpoint address, session, user name, password, etc.
  • Dynamic proxies. In contrast to the static stubs discussed above, the client at runtime creates dynamic proxy stubs using the javax.xml.rpc.Service interface. The client has a priori knowledge of the WSDL and the service it is going to invoke. It uses the ServiceFactory classes to create the service and get the proxy.
  • DII (dynamic invocation interface). This software pattern eliminates the need for clients to know in advance a service's exact name and parameters. A DII client can discover this information at runtime using a service broker that can look up the service's information. This flexibility in service discovery enables the run-time system to use service brokers, which can adopt varying service discovery mechanisms -- ebXML registries, UDDI, etc.

If you're developing for J2EE, you should keep in mind the following J2EE-specific JAX-RPC requirements:

  • The service should implement the javax.naming.referenceable and/or java.io.serlializable interfaces to support registration and lookup.
  • The component provider must declare all the service references in the deployment descriptor.

Conclusions

By now, I have covered most of the JAX-RPC features that you can use to generate interoperable Web services. This introductory series on the standard will enable you to develop Web services with maximum interoperability. As I mentioned earlier, there are different implementations of JAX-RPC run-time engine available, with varying degree of quality of service features (to support J2EE); hence, you should always consult your application container vendor to find out more about its support for JAX-RPC. At the moment, no single JAX-RPC run-time system provides all of the features discussed in this series. I am sure that there will be revisions of this specification to support the latest SOAP and WSDL specifications (both specs are now at version 1.2); JAX-RPC may also adopt JAXB (Java XML Binding, JSR 31) as a standard for interoperable type mapping. Keep an eye on this specification as Web services evolve to support more service profiles and SOAP header extensions.


Resources

About the author

author

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.

Comments (Undergoing maintenance)



Trademarks  |  My developerWorks terms and conditions

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=SOA and Web services
ArticleID=11742
ArticleTitle=A developer's introduction to JAX-RPC, Part 2: Mine the JAX-RPC specification to improve Web service interoperability
publish-date=01012003
author1-email=joshy@us.ibm.com
author1-email-cc=

My developerWorks community

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere).

My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Rate a product. Write a review.

Special offers