Skip Headers
Oracle® Fusion Middleware Programming Advanced Features of JAX-RPC Web Services for Oracle WebLogic Server
11g Release 1 (10.3.4)

Part Number E13735-03
Go to Documentation Home
Home
Go to Book List
Book List
Go to Table of Contents
Contents
Go to Master Index
Master Index
Go to Feedback page
Contact Us

Go to previous page
Previous
Go to next page
Next
View PDF

4 Creating Conversational Web Services

The following sections describe how to create a conversational Web service:

Overview of Conversational Web Services

A Web service and the client application that invokes it may communicate multiple times to complete a single task. Also, multiple client applications might communicate with the same Web service at the same time. Conversations provide a straightforward way to keep track of data between calls and to ensure that the Web service always responds to the correct client.

Conversations meet two challenges inherent in persisting data across multiple communications:

WebLogic Server manages this unique ID and state by creating a conversation context each time a client application initiates a new conversation. The Web service then uses the context to correlate calls to and from the service and to persist its state-related data.

Conversations between a client application and a Web service have three distinct phases:

Conversations typically occur between two WebLogic Web services: one is marked conversational and defines the start, continue, and finish operations and the other Web service uses the @ServiceClient annotation to specify that it is a client of the conversational Web service. You can also invoke a conversational Web service from a stand-alone Java client, although there are restrictions.

As with other WebLogic Web service features, you use JWS annotations to specify that a Web service is conversational.

Note:

The client Web service that invokes a conversational Web service is not required to also be conversational. However, if the client is not conversational, there is a danger of multiple instances of this client accessing the same conversational Web service stub and possibly corrupting the saved conversational state. If you believe this might true in your case, then specify that the client Web service also be conversational. In this case you cannot use a stand-alone Java client, because there is no way to mark it as conversational using the WebLogic APIs.

A conversational Web service on its own does not guarantee message delivery or that the messages are delivered in order, exactly once. If you require this kind of message delivery guarantee, you must also specify that the Web service be reliable. See Using Web Service Reliable Messaging: Main Steps and Using the Asynchronous Features Together.

Creating a Conversational Web Service: Main Steps

The following procedure describes how to create a conversational Web service, as well as a client Web service and stand-alone Java client application, both of which initiate and conduct a conversation. The procedure shows how to create the JWS files that implement the two Web services from scratch. If you want to update existing JWS files, you can also use this procedure as a guide.

It is assumed that you have set up an Ant-based development environment and that you have a working build.xml file to which you can add targets for running the jwsc Ant task and deploying the generated conversational Web service. It is further assumed that you have a similar setup for the WebLogic Server instance that hosts the client Web service that initiates the conversation. For more information, see the following sections in Getting Started With JAX-RPC Web Services for Oracle WebLogic Server:

Table 4-1 Steps to Create a Conversational Web Service

#
Step Description

1

Create a new JWS file, or update an existing one, that implements the conversational Web service.

Use your favorite IDE or text editor. See Programming Guidelines for the Conversational JWS File.

2

Update your build.xml file to include a call to the jwsc Ant task to compile the conversational JWS file into a Web service.

See "Running the jwsc WebLogic Web Services Ant Task" in Getting Started With JAX-RPC Web Services for Oracle WebLogic Server.

3

Run the Ant target to build the conversational Web service.

For example:

prompt> ant build-mainService

4

Deploy the target Web service as usual.

See "Deploying and Undeploying WebLogic Web Services" in Getting Started With JAX-RPC Web Services for Oracle WebLogic Server.

5

Create a new JWS file, or update an existing one, that implements the client Web service.

If the client application is a stand-alone Java client, see Updating a Stand-Alone Java Client to Invoke a Conversational Web Service. Skip Steps 6-9.

If the client application is itself a Web service, follow Steps 6-9.

6

Create a new JWS file, or update an existing one, that initiates and conducts the conversation with the conversational Web service.

Use your favorite IDE or text editor. It is assumed that the client Web service is deployed to a different WebLogic Server instance form the one that hosts the conversational Web service. See Programming Guidelines for the JWS File That Invokes a Conversational Web Service.

7

Update the build.xml file that builds the client Web service.

See Updating the build.xml File for a Client of a Conversational Web Service.

8

Run the Ant target to build the client Web services.

For example:

prompt> ant build-clientService

9

Deploy the client Web service as usual.

See "Deploying and Undeploying WebLogic Web Services" in Getting Started With JAX-RPC Web Services for Oracle WebLogic Server.


Programming Guidelines for the Conversational JWS File

The following example shows a simple JWS file that implements a conversational Web service; see the explanation after the example for coding guidelines that correspond to the Java code in bold.

package examples.webservices.conversation;

import java.io.Serializable; 

import weblogic.jws.WLHttpTransport;
import weblogic.jws.Conversation; 
import weblogic.jws.Conversational; 
import weblogic.jws.Context; 
import weblogic.wsee.jws.JwsContext; 
import weblogic.wsee.jws.ServiceHandle; 

import javax.jws.WebService;
import javax.jws.WebMethod;
@Conversational(maxIdleTime="10 minutes", 
                maxAge="1 day", 
                runAsStartUser=false, 
                singlePrincipal=false ) 
@WebService(name="ConversationalPortType",
            serviceName="ConversationalService",
            targetNamespace="http://examples.org/")

@WLHttpTransport(contextPath="conv",
                 serviceUri="ConversationalService",
                 portName="ConversationalServicePort")

/**
 * Conversational Web service.
 */

public class ConversationalServiceImpl implements Serializable { 

  @Context 
  private JwsContext ctx; 
  public String status = "undefined"; 

  @WebMethod
  @Conversation (Conversation.Phase.START) 
  public String start() {

    ServiceHandle handle = ctx.getService(); 
    String convID = handle.getConversationID(); 

    status = "start";
    return "Starting conversation, with ID " + convID + " and status equal to " + status;

  }

  @WebMethod
  @Conversation (Conversation.Phase.CONTINUE) 
  public String middle(String message) {

    status = "middle";
    return "Middle of conversation; the message is: " + message + " and status is " + status;

  }

  @WebMethod
  @Conversation (Conversation.Phase.FINISH) 
  public String finish(String message ) {

    status = "finish";
    return "End of conversation; the message is: " + message + " and status is " + status;

  }

}

Follow these guidelines when programming the JWS file that implements a conversational Web service. Code snippets of the guidelines are shown in bold in the preceding example.

Programming Guidelines for the JWS File That Invokes a Conversational Web Service

The following example shows a simple JWS file for a Web service that invokes the conversational Web service described in Programming Guidelines for the Conversational JWS File; see the explanation after the example for coding guidelines that correspond to the Java code in bold.

package examples.webservices.conversation;

import weblogic.jws.WLHttpTransport;
import weblogic.jws.ServiceClient; 

import weblogic.wsee.conversation.ConversationUtils; 

import javax.jws.WebService;
import javax.jws.WebMethod;

import javax.xml.rpc.Stub;

import examples.webservices.conversation.ConversationalPortType; 

import java.rmi.RemoteException;

@WebService(name="ConversationalClientPortType",
            serviceName="ConversationalClientService",
            targetNamespace="http://examples.org/")

@WLHttpTransport(contextPath="convClient",
                 serviceUri="ConversationalClient",
                 portName="ConversationalClientPort")

/**
 *  client that has a conversation with the ConversationalService.
 */

public class ConversationalClientImpl {

  @ServiceClient( 
     wsdlLocation="http://localhost:7001/conv/ConversationalService?WSDL", 
     serviceName="ConversationalService", 
     portName="ConversationalServicePort") 
 
  private ConversationalPortType port; 

  @WebMethod
  public void runConversation(String message) {

    try {

      // Invoke start operation
      String result = port.start(); 
      System.out.println("start method executed.");
      System.out.println("The message is: " + result);

      // Invoke continue operation
      result = port.middle(message ); 
      System.out.println("middle method executed.");
      System.out.println("The message is: " + result);

      // Invoke finish operation
      result = port.finish(message ); 
      System.out.println("finish method executed.");
      System.out.println("The message is: " + result);
      ConversationUtils.renewStub((Stub)port); 

    }
    catch (RemoteException e) {
      e.printStackTrace();
    }

  }

}

Follow these guidelines when programming the JWS file that invokes a conversational Web service; code snippets of the guidelines are shown in bold in the preceding example:

ConversationUtils Utility Class

WebLogic Server provides a utility class for use with the conversation feature. Use this class to perform common tasks such as getting and setting the conversation ID and setting configuration options. Some of these tasks are performed in the conversational Web service, some are performed in the client that invokes the conversational Web service. See Programming Guidelines for the JWS File That Invokes a Conversational Web Service for an example of using this class.

See "weblogic.wsee.conversation.ConversationUtils" in Oracle WebLogic Server API Reference for details.

Updating the build.xml File for a Client of a Conversational Web Service

You update a build.xml file to generate the JWS file that invokes a conversational Web service by adding taskdefs and a build-clientService target that looks something like the following example. See the description after the example for details.

<taskdef name="jwsc"
    classname="weblogic.wsee.tools.anttasks.JwscTask" />

  <target name="build-clientService">

    <jwsc
        enableAsyncService="true"
        srcdir="src"
        destdir="${clientService-ear-dir}" >

        <jws file="examples/webservices/conversation/ConversationalClientImpl.java" >
          <clientgen 
            wsdl="http://${wls.hostname}:${wls.port}/conv/ConversationalService?WSDL" 
            packageName="examples.webservices.conversation"/> 

        </jws>

    </jwsc>

  </target>

Use the taskdef Ant task to define the full classname of the jwsc Ant tasks.

Update the jwsc Ant task that compiles the client Web service to include a <clientgen> child element of the <jws> element so as to generate and compile the JAX-RPC stubs for the deployed ConversationalService Web service. The jwsc Ant task automatically packages them in the generated WAR file so that the client Web service can immediately access the stubs. You do this because the ConversationalClientImpl JWS file imports and uses one of the generated classes.

Updating a Stand-Alone Java Client to Invoke a Conversational Web Service

The following example shows a simple stand-alone Java client that invokes the conversational Web service described in Programming Guidelines for the Conversational JWS File. See the explanation after the example for coding guidelines that correspond to the Java code in bold.

package examples.webservices.conv_standalone.client;

import java.rmi.RemoteException;

import javax.xml.rpc.ServiceException;
import javax.xml.rpc.Stub;
import weblogic.wsee.jaxrpc.WLStub; 

/**
 * stand-alone client that invokes and converses with ConversationlService.
 */

public class Main {

  public static void main(String[] args)
      throws ServiceException, RemoteException{

      ConversationalService service = new ConversationalService_Impl(args[0] + "?WSDL");
      ConversationalPortType port = service.getConversationalServicePort();

      // Set property on stub to specify that client is invoking a Web service
      // that uses advanced features; this property is automatically set if
      // the client runs in a WebLogic Server instance.

      Stub stub = (Stub)port; 
      stub._setProperty(WLStub.COMPLEX,  "true"); 

      // Invoke start operation to begin the conversation
      String result = port.start(); 
      System.out.println("start method executed.");
      System.out.println("The message is: " + result);

      // Invoke continue operation
      result = port.middle("middle" ); 
      System.out.println("middle method executed.");
      System.out.println("The message is: " + result);

      // Invoke finish operation
      result = port.finish("finish" ); 
      System.out.println("finish method executed.");
      System.out.println("The message is: " + result);

  }

}

Follow these guidelines when programming the stand-alone Java client that invokes a conversational Web service. Code snippets of the guidelines are shown in bold in the preceding example.

Example Conversational Web Service .NET Client

This section demonstrates how to create a .NET WSE3.0 client for a WebLogic conversational Web service. The example includes the following files:

These files are described in detail in the sections that follow.

ConversationService.java File

The example ConversationService.java file is shown in Example 4-1. The example includes extensive comments that describe its function.

Example 4-1 ConversationService.java File

package conv;
 
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.Oneway;
 
import weblogic.jws.Conversation;
import weblogic.jws.Callback;
import weblogic.jws.CallbackService;
 
import java.io.Serializable;
 
/**
 * Demonstrates use of the @Conversation annotation to manage the lifetime of the service
 * and provide data persistence and message correlation.
 * 
 * Remember that multiple clients might invoke a web service simultaneously.  When the
 * web service stores data relevant to the client or calls additional services
 * in order to process a client's request, the service must be able to process returned
 * data from the external services in the context of the specific client it relates
 * to.  This is all automatic when conversations are used.
 * 
 * Remember that not all clients are capable of accepting callbacks.  Specifically,
 * clients operating from behind firewalls may not be able to receive asynchronous
 * callbacks.  You may wish to provide a synchronous interface, like this one,
 * for such clients.  If a client can accept callbacks, it must send a callback endpoint refrence
 * as part of any "start conversation" method invocation.
 * 
 * To see the behavior in the Test View, invoke startRequest and then getRequestStatus
 * several times quickly.
 */
@WebService(serviceName = "ConversationService", portName = "conversation", targetNamespace = "http://www.openuri.org/")
public class ConversationService implements Serializable {
 
  @Callback
  public CallbackInterface callback;
  private boolean useCallbacks;
  private int num;
 
  /**
   * Starts the conversation
   */
  @Conversation(Conversation.Phase.START)
  @WebMethod
  public void startRequest(boolean useCallbacks) {
    this.useCallbacks = useCallbacks;
  }
 
  @WebMethod
  @Conversation(Conversation.Phase.CONTINUE)
  public String getRequestStatus() {
 
    num++;
    if (num == 1)
      return "This is the first time you call getRequestStatus method.";
    if (num == 2 && useCallbacks) {
      callback.onResultReady("finished");
      return "This is the second time you call  getRequestStatus method, the conversation has been terminated automtically when the onResultReady callback method is invoked.";
    } else
      return "You have called getRequestStatus method " + num + " times";
 
  }
 
  /**
   * Used to tell Conversation.jws that the current conversation is
   * no longer needed.
   */
  @WebMethod
  @Conversation(Conversation.Phase.FINISH)
  public void terminateRequest() {
 
  }
 
  @CallbackService(serviceName = "ConversationCallbackService")
  public interface CallbackInterface {
 
    /**
     * Callback to invoke on the client when the external service
     * returns its result. Will only be called it the client can
     * accept callbacks and told us where to send them.
     * <p/>
     * If this callback is used, it implicitly terminates the
     * conversation with no action required on the part of the
     * client.
     */
    @WebMethod
    @Oneway
    @Conversation(Conversation.Phase.FINISH)
    public void onResultReady(String result);
  }
 
}

Service.cs File

The example Service.cs file is shown in Example 4-2.

This conversation proxy file was created using the Microsoft WSDL to Proxy Class tool WseWsdl3.exe (see http://msdn.microsoft.com/en-us/library/aa529578.aspx) and the ConversationService Web service's WSDL file.

The example includes extensive comments that describe its function.

Example 4-2 Service.cs File

using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Diagnostics;
using System.IO;
using System.Xml;
using Microsoft.Web.Services3.Addressing;
using Microsoft.Web.Services3;
using System.Collections.Generic;
using Microsoft.Web.Services3.Design;
 
 
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class Service : System.Web.Services.WebService
{
    
    public Service () {
 
        //Uncomment the following line if using designed components 
        //InitializeComponent(); 
    }
 
    /*
    * start invokes the Conversation web service's startRequest
    * operation.
    * 
    * Since the Conversation web service is conversational,
    * we must also persist the ReplyTo endpoint reference SOAP header
    * for subsequent calls.
    * 
    * Since the Conversation web service can optionally communicate
    * the result of it's work via a callback, we must prepare a
    * second SOAP header CallbackTo SOAP header, which is the endpoint reference 
    * of the recipient to which callbacks should be sent.
    */
    [WebMethod(EnableSession = true)]
    public void start(Boolean useCallbacks, Boolean useIPAddress)
    {
        /*
         * The Conversation proxy was created using .NET WSE3.0's WseWsdl3.exe
         * application and the Conversation.jws's WSDL file.  The WSDL
         * file for any WLS web service may be obtained
         * by hitting the web service's URL with "?WSDL" appended to
         * the end.  For example:
         * 
         * http://somehost:7001/samples/async/Conversation.jws?WSDL
         * 
         * WseWsdl3.exe produces a C# proxy class.  Place the resulting
         * ConversationService.cs file in your .NET project, then use Visual
         * Studio's Project->Add Existing Item menu action to "import"
         * the class into the project.
         */
        ConversationServiceSoapBinding conv;
        String callbackLocation;
        int asmxIndex;
 
        /*
         * Construct the callback URL from various pieces of
         * server and HttpRequest info.
         */
        Uri requestUrl = Context.Request.Url;
 
        if (useIPAddress)
        {
            /*
             * if useIPAddress is true, construct the callback address
             * with the IP address of this host.
             */
            callbackLocation = requestUrl.Scheme + "://" + System.Net.Dns.GetHostByName(requestUrl.Host).AddressList[0] +
                ":" + requestUrl.Port + requestUrl.AbsolutePath;
        }
        else
        {
            /*
             * if useIPAddress is false, construct the callback address
             * with the hostname of this host.
             */
            callbackLocation = requestUrl.Scheme + "://" + requestUrl.Host +
                ":" + requestUrl.Port + requestUrl.AbsolutePath;
        }
 
        // Remove everything after ".asmx"
        asmxIndex = callbackLocation.IndexOf(".asmx") + 5;
        callbackLocation = callbackLocation.Remove(asmxIndex,
                                 callbackLocation.Length - asmxIndex);
 
        /*
         * Create an instance of the proxy for the Conversation
         * web service.
         * 
         */
        conv = new ConversationServiceSoapBinding();
 
        
        /*
         * When callback is enabled, a custom callback header should be added into 
         * the outbound soap message. 
         * 
         */
        if (useCallbacks)
            enableSoapFilterToAddCallbackHeader(conv, callbackLocation);
        
    
        /*
         * Invoke the startRequest method of the web service. The
         * single boolean parameter determines whether the Conversation
         * web service will use callbacks to communicate the result
         * back to this client.
         * 
         * If the argument is true, an onResultReady callback will
         * be sent when the result is ready.  This client must implement
         * a method with that name that expects the message shape defined
         * by the target web service (returns void and accepts a single
         * string argument).  See the onResultReady method below.
         * 
         * If the argument to startRequest is false, callbacks will not
         * be used and this client must use the getRequestStatus method
         * to poll the Conversation web service for the result.
         */
        conv.startRequest(useCallbacks);
        /*
         * Persist the ReplyTo header  in session state so that it can
         * be used in other methods that take part in the conversation.
         * 
         * This is not safe since one session could start multiple
         * conversations, but there is no other apparent way to persist
         * this information.  Member variables of WebService classes
         * are not persisted across method invocations.
         */
        Session["ConversationReplyTo"] = conv.ResponseSoapContext.Addressing.ReplyTo;
 
 
    }
 
    /* the CallbackTo header defintion isn't exposed by WLS9x/WLS10x callback service. 
     * So we need to use SOAPFilter to add the CallbackTo header. 
     * 
     */
    private static void enableSoapFilterToAddCallbackHeader(ConversationServiceSoapBinding conv, String callbackLocation)
    {
        //Create a custom policy.
        Policy myPolicy = new Policy();
        // Create a new policy assertion
        MyPolicyAssertion myAssertion = new MyPolicyAssertion(callbackLocation);
        // Add the assertion to the policy
        myPolicy.Assertions.Add(myAssertion);
        //Set the custom policy you have created on the client proxy 
        conv.SetPolicy(myPolicy);
    }
 
     /*
     * getStatus invokes Conversation's getRequestStatus method.
     * getRequestStatus is a polling method that is an alternative
     * for web services that cannot recieve callbacks.
     * 
     * Note that a conversation must be started with startRequest before
     * this method may be invoked.  If not, or if this method is invoked
     * outside of a conversation for any reason, it will get back a SOAP
     * fault indicating that the conversation does not exist.
     */
    [WebMethod(EnableSession = true)]
    public String getStatus()
    {
        String result;
 
        /*
         * Create an instance of the proxy for the Conversation
         * web service.  We could probably persist the proxy instance
         * in session state, but chose not to.
         */
        ConversationServiceSoapBinding conv = new ConversationServiceSoapBinding();
 
        /*
         * change the destination to the ReplyTo endpoint reference we cached on session state in
         * the start method.
         */
        conv.RequestSoapContext.Addressing.Destination = (EndpointReference)Session["ConversationReplyTo"];
        /* 
         * Invoke the getRequestStatus method of the web service.
         */
        result = conv.getRequestStatus();
        return result;
    }
 
    /*
     * finish invokes Conversation's terminateRequest method, which
     * terminates the current conversation.
     * 
     * Note that a conversation must be started with startRequest before
     * this method may be invoked.  If not, or if this method is invoked
     * outside of a conversation for any reason, it will get back a SOAP
     * fault indicating that the conversation does not exist.
     */
    [WebMethod(EnableSession = true)]
    public void finish()
    {
        /*
         * Create an instance of the proxy for the Conversation
         * web service.  We could probably persist the proxy instance
         * in session state, but chose not to.
         */
        ConversationServiceSoapBinding conv = new ConversationServiceSoapBinding();
 
        /*
         * change the destination to the ReplyTo endpoint reference we cached on session state in
         * the start method. Both "continue" and "finish" methods use the same destination.
         */
        conv.RequestSoapContext.Addressing.Destination = (EndpointReference)Session["ConversationReplyTo"];
        /* 
         * Invoke the terminateRequest method of the web service.
         */
        conv.terminateRequest();
    }
 
    /*
     * onResultReady is a callback handler for the onResultReady
     * callback that Conversation.jws can optionally use to return
     * its results.
     * 
     * .NET WSE3.0 does not support callbacks directly, but a callback is just
     * a method invocation message.  So if you construct a WebMethod with
     * the same signature as the callback and set the XML namespace
     * properly, it serves as a callback handler.
     * 
     */
    [WebMethod]
    [SoapDocumentMethod(OneWay = true, 
        Action = "http://www.openuri.org/ConversationService_CallbackInterface/onResultReady", 
        RequestElementName = "http://www.openuri.org/", 
        ResponseNamespace = "http://www.openuri.org/"
        )]
    public void onResultReady(String result)
    {
        /*
         * When the callback is invoked, log a message to the
         * hardcoded file c:\temp\ConversationClient.log.
         * 
         * Note: if c:\temp does not exist on this server, an
         * Exception will be raised.  Since it is not handled here,
         * it will be returned as a SOAP fault to the Conversation
         * web service.
         */
        TextWriter output;
        output = File.AppendText("c:\\temp\\ConversationClient.log");
        String msg = "[" + DateTime.Now.ToString() + "] callback received";
        output.WriteLine(msg);
        output.Flush();
        output.Close();
    }
 
    
}
 
public class MyFilter : Microsoft.Web.Services3.SoapFilter
{
    private String callbackLocation;
 
    public MyFilter(String callbackLocation)
    {
        this.callbackLocation = callbackLocation;
    }
    
    public override SoapFilterResult ProcessMessage(SoapEnvelope envelope)
    {
 
       //create the CallbackTo soap element.
       XmlDocument xmldoc = new XmlDocument();
       XmlElement xmlEle = xmldoc.CreateElement("callback", "CallbackTo", "http://www.openuri.org/2006/03/callback");
       
       //create the CallbackTo endpoint reference.
       Address callbacto = new Address(new Uri(callbackLocation));      
       XmlElement xmlEle2 =new EndpointReference(callbacto).GetXml(xmldoc);
       //add the CallbackTo endpoint reference into CallbackTo SOAP element.
       xmlEle.AppendChild(xmlEle2.FirstChild);
       //add the whole CallbackTo SOAP element into SOAP header. 
       XmlNode callbackheader = envelope.ImportNode(xmlEle, true);
       envelope.DocumentElement.FirstChild.AppendChild(callbackheader);
       return SoapFilterResult.Continue;
 
    }
}
 
public class MyPolicyAssertion : Microsoft.Web.Services3.Design.PolicyAssertion
{
    private String callbackLocation;
 
    public MyPolicyAssertion(String callbackLocation)
    {
        this.callbackLocation = callbackLocation;
    }
    
    public override  SoapFilter CreateClientInputFilter(FilterCreationContext context)
    {
        return null;
    }
 
 
    public override  SoapFilter CreateClientOutputFilter(FilterCreationContext context)
    {
        //use MyFilter to add the CallbackTo header in the outbound soap message. 
        return new MyFilter(callbackLocation);
    }
    
    public override  SoapFilter CreateServiceInputFilter(FilterCreationContext context)
    {
        return null;
    }
    
    public override  SoapFilter CreateServiceOutputFilter(FilterCreationContext context)
    {
        return null;
    }
 
}

build.xml File

The example build.xml file is shown in Example 4-3.

build.xml assumes that you copy the example source files to a new directory WL_HOME\samples\server\examples\src\examples\webservices\conv, where WL_HOME is the directory containing your WebLogic Server installation.

build.xml also requires that you first set your examples environment correctly via WL_HOME\samples\domains\wl_server>setExamplesEnv.cmd(sh and that the examples server is already started.

The example includes comments that describe the build file function and targets.

Example 4-3 build.xml File

<?xml version="1.0" encoding="ISO-8859-1"?>
<project name="webservices.conversation" default="all" basedir=".">
 
  <!-- set global properties for this build -->
  <property file="../../../examples.properties"/>
 
  <property name="client.dir" value="${client.classes.dir}/webservices_conversation" />
  <property name="package.dir" value="examples/webservices/conv"/>
  <property name="package" value="examples.webservices.conv"/>
  <property name="ear.dir" value="${examples.build.dir}/webservicesConversationEar" />
 
  <path id="client.class.path">
    <pathelement path="${java.class.path}"/>
  </path>
 
  <!-- Web service WLS Ant task definitions -->
  <taskdef name="jwsc"
    classname="weblogic.wsee.tools.anttasks.JwscTask" />
  <taskdef name="clientgen"
      classname="weblogic.wsee.tools.anttasks.ClientGenTask" />
 
  <target name="all" depends="build, deploy"/>
 
 
  <target name="clean">
    <delete dir="${ear.dir}"/>
  </target>
 
  <!-- Target that builds the conversational  Web service -->
  <target name="build" description="Target that builds the MTOM Web service">
    <jwsc
      srcdir="${examples.src.dir}/${package.dir}"
      sourcepath="${examples.src.dir}"
      destdir="${ear.dir}"
      classpath="${java.class.path}"
      keepGenerated="true"
      deprecation="${deprecation}"
      debug="${debug}">
        <jws file="ConversationService.java">
                <WLHttpTransport contextPath="/samples/async" serviceURI="conversation.jws"/>
                </jws>
    </jwsc>
  </target>
 
  
 
  <!-- Target that deploys the conversational Web service -->
  <target name="deploy" description="Target that deploys the conversational Web service">
    <wldeploy
      action="deploy"
      source="${ear.dir}"
      user="${wls.username}"
      password="${wls.password}"
      verbose="true"
      adminurl="t3://${wls.hostname}:${wls.port}"
      targets="${wls.server.name}"
      failonerror="${failondeploy}"/>
  </target>
 
  <!-- Target that undeploys the conversational Web service -->
  <target name="undeploy" description="Target that deploys the conversational Web service">
    <wldeploy
      action="undeploy"
      name="webservicesConversationEar"
      user="${wls.username}"
      password="${wls.password}"
      verbose="true"
      adminurl="t3://${wls.hostname}:${wls.port}"
      targets="${wls.server.name}"
      failonerror="${failondeploy}"/>
  </target>
 
</project>

Client Considerations When Redeploying a Conversational Web Service

WebLogic Server supports production redeployment, which means that you can deploy a new version of an updated conversational WebLogic Web service alongside an older version of the same Web service.

WebLogic Server automatically manages client connections so that only new client requests are directed to the new version. Clients already connected to the Web service during the redeployment continue to use the older version of the service until they complete their work, at which point WebLogic Server automatically retires the older Web service. If the client is connected to a conversational Web service, its work is considered complete when the existing conversation is explicitly ended by the client or because of a timeout.

For additional information about production redployment and Web service clients, see "Client Considerations When Redeploying a Web service" in Getting Started With JAX-RPC Web Services for Oracle WebLogic Server.