How-To: JAX-WS Asynch Client

How to develop a JAX-WS asynchronous client

Date: 05-May-2007
Author:  
Pyounguk Cho


Introduction

One of the pain points when invoking any web service especially over a blocking transport layer such as HTTP has been the lack of ability for the soap client to control over when to fetch the result without necessarily getting blocked in the current thread. Typically the soap client has to wait in a sense indefinitely until the service returns its response message or until the connection times out per the HTTP connection timeout value set by the client or the server.

No more pain on this. The JAX-WS specification defines an asynchronous client side programming model, including standard extensions to generated SEI's to support polling and callback usage patterns. Please, note that this approach is purely asynchronous from the soap client's perspective. In other words, as far as the end point web service, it is still a blocking invocation. Also, JAX-WS asynchronous client, which works over a single transport connect, is different from more commonly referenced "asynchronous messaging" using WS-Addressing where two distinct transport connections get established.

Client Runtime

One can implment a JAX-WS asynchronous client using Dispatch or using Dynamic Proxy. In this how-to, we use a Dynamic Proxy. Asynchronous calls to methods will be done by the corresponding SEI methods.

Server Runtime

There is no extra implementation reqruirement at the server side as this is purely client side feature. The interface that is to be supported at the server side will not have the extra methods for asynchronous messaging support. In other words, it is possible to create a JAX-WS asynchronous client for virtually any web service.

Prerequisites

What you need to know

In order to be able to follow this how-to, you whould be familiar with the following :

  • web services basics(wsdl, soap)
  • standard J2EE application packaging and deployment model

Software Requirements

  • Oracle Containers for Java EE (11.1.1.0.0) Technology Preview, available from OTN
  • Sun's JDK 1.5, available here

Notations

Following notations are used throughout the document.

  • %ORACLE_HOME% - The directory where you installed the Oracle Application Server 10g.
  • %JAVA_HOME% - The directory where your JDK is installed
  • %HOWTO_HOME% - The directory where this how-to example is to be unzipped

Building the Application

The sample application uses a prepakcaged web service that returns quote information.

Understanding JAX-WS classes for asynchronous bahaviors

Per JAX-WS specification, following are the classes used for JAX-WS asynchronous client.
  • javax.xml.ws.Response A generic interface that is used to group the results of an invocation with the response context. Response extends java.util.concurrent. Future<T> to provide asynchronous result polling capabilities.
  • javax.xml.ws.AsyncHandler A generic interface that clients implement to receive results in an asynchronous callback. It defines a single handleResponse method that has Response object as its argument.

Generating asynchronous soap client artifacts

Using Oracle web service ant tasks, client side artifacts are generated out of the wsdl for the service. In order to enable asynchronous behavior, a special attribute, "genAsynchMethods", needs to be set in the genInterface task as follows.

<oracle:genInterface wsdl="http://localhost:8888/quote/rapidservice/request-quote?wsdl"
output = "${src.webservice.client.dir}"
databinding = "jaxb20"
genAsyncMethods = "forAll"
>
<classpath>
<pathelement path="${bld.cli.dir}"/>
<pathelement location="${ORACLE_HOME}/webservices/lib/wsa.jar"/>
</classpath>
</oracle:genInterface>

Using JAX-WS asynchronous client methods

As described above, Response and AsynchHandler are two key classes that provides soap client applications with ways to interact with soap container asynchronously. Below are code snippets for each from the demo.Demo.java in %HOWTO_HOME%/src/client directory.

Using Response class

Response<Quote> respQuote = port.poItemsQuoteAsync(items); quote = respQuote.get();

Using AsynchHandler class

Future<?> future = port.poItemsQuoteAsync(items, new AsyncHandler<Quote>() {
public void handleResponse(Response<Quote> response) {
try {
quote = response.get(); } });

Running the Application

This secion describes how to run the sample application. For most of the part, Apache ant is used to drive building and running the application.

Examining the Sample File Directories

Below is the contents of the how-to ZIP file:

  • ./src/ - contains all Java source code for the example.
    • client/ 
      • demo/Demo.java - Test application client for the asynchronous client example.
  • ./etc/
    • quote2.ear - Deployable J2EE web service application file.
    ./doc/
    • how-to-jaxws-asyinchClient.html - This document.
  • ./
    • build.xml - An Ant build file.
    • env.bat - A batch file to set the environment
    • ant-oracle.properties -Properties required for the proper execution of the sample's build script
    • ant-oracle.xml - Used by build.xml to execute the various Oracle Application Server tasks required for assembly and deployment of the web service and client.

Configuring the Environment

Please check to make sure that the following properties are configured correctly in the env.bat and ant-oracle.properties file located in the root of the sample's distribution (NOTE:  Some of these properties will default to the values of corresponding environment variables as noted below.  If you have these variables setup in your environment you may not have to alter the values in the file).  If necessary, modify these variable to the proper values for you environment:
  • oracle.home - the root directory of oracle installation.  Defaults to ORACLE_HOME environment variable.
  • java.home -  the root directory of JDK installation.  Defaults to JAVA_HOME environment variable.
  • oracleas.host - the hostname of the platform on which the OC4J instance is running.  Defaults to localhost.
  • oracleas.http.port - the port on which the OC4J HTTP listener is listening.  Defaults to 8888.
  • oracleas.admin.port  - the port on which the OC4J administration processor is listening.  Defaults to 23791.
  • oracleas.admin.user - the name of the OC4J administrator.  Defaults to "oc4jadmin".
  • oracleas.admin.password - the password for the OC4J administrator.  Defaults to "welcome".
  • oracleas.binding.module - the name of the HTTP web site to which the deployed application is bound.  Defaults to "default-web-site".
In addition, please make sure that the ant command associated with the OC4J ant distribution is in your execution path (%ORACLE_HOME%/ant/bin).

After setting correct values for the properties, , type the following command from the %HOWTO_HOME% directory:

  • ./env.bat

Starting the OC4J Instance

Start an OC4J 11g Technology Preview instance as follows:
    • Stand Alone Installation: %ORACLE_HOME%/bin/oc4j start
      Note that the oc4j command expects the JAVA_HOME environment variable to point to a full JDK 1.5 installation.

Generating, and Compiling the Application

To deploy the sample web service application under %HOW_TO_HOME%/etc, type the following command from the %HOWTO_HOME% directory:

  • ant deploy

This command would attempt to deploy the application if the build is successful. It will first test whether OC4J is running. Please, check whether deployment successful by accessing the web service application web page at http://localhost:8888/quote/rapidservice/request-quote. You can click the Service Definition link on the page to access the wsdl file of the service.

Running the Application

Once the web service application is available on the target OC4J container, it is time to generate the client artifacts and complie the demo application. Run the following command:

  • ant cli-build

You can run the sample application(demo.Demo class) via the following command:

  • ant cli-run -Dcli-param=1

where cli-param can take a value from 1 to 5 for different calling semantics per the table below.

cli-Param value test scenario
1
synchronous invocation
2
asynchronous invocation followed by a blocking get() for polling
3
asynchronous invocation followed by a nonblocking get() for polling
4
asynchronous invocation with a callback handler
5
asynchronous invocation followed by a cancellation

 

Summary

This how-to describes and demonstrate,
  • what JAX-WS asynchronous client is
  • key JAX-WS client classes and APIs for asynchonous invocation
  • how to generate JAX-WS client artifacts with asynchronous behaviors enabled
  • how to enable polling via javax.xml.ws.Response class
  • how to use a callback mechanism via javax.xml.ws.AsyncHandle class
E-mail this page
Printer View Printer View
Oracle Is The Information Company About Oracle | Oracle RSS Feeds | Careers | Contact Us | Site Maps | Legal Notices | Terms of Use | Privacy