Skip navigation.
Downloads | Product Documentation | Support

Programming WebLogic Web Services

# Creating JMS-Implemented WebLogic Web Services

The following sections describe how to create JMS-implemented WebLogic Web Services:

- Designing JMS-Implemented WebLogic Web Services
- Creating JMS-Implemented WebLogic Web Services
- Configuring JMS Components for Message-Style Web Services
- Assembling JMS-Implemented WebLogic Web Services Using servicegen
- Assembling JMS-Implemented WebLogic Web Services Manually
- Deploying JMS-Implemented WebLogic Web Services
- Invoking JMS-Implemented WebLogic Web Services

# Overview of JMS-Implemented WebLogic Web Services

In addition to implementing a Web Service operation with a stateless session EJB or a Java class, you can use a JMS message consumer or producer, such as a message-driven bean.

There are two types of JMS-implemented operations:

- Operations that send data to a JMS destination.

You implement this type of operation with a JMS message consumer. The message consumer consumes the message after a client that invokes the Web Service operation sends data to the JMS destination.

- Operations that receive data from a JMS queue.

You implement this type of operation with a JMS message producer. The message producer puts a message on the specified JMS queue and a client invoking this message-style Web Service component polls and receives the message.

When a client application sends data to a JMS-implemented Web Service operation, WebLogic Server first converts the XML data to its Java representation using either the built-in or custom serializers, depending on whether the data type of the data is built-in or not. WebLogic Server then wraps the resulting Java object in a `javax.jms.ObjectMessage` object and puts it on the JMS destination. You can then write a JMS listener, such as a message-driven bean, to take the `ObjectMessage` and process it. Similar steps happen in reverse when a client application invokes a Web Service to receive data from a JMS queue.

If you are using non-built-in data types, you must update the `web-services.xml` deployment descriptor file with the correct data type mapping information. If the Web Service cannot find data type mapping information for the data, then it converts the data to a `javax.xml.soap.SOAPElement` data type, defined by the SOAP With Attachments API For Java (SAAJ) specification.

Note: Input and return parameters to a Web Service operation implemented with a JMS consumer or producer must implement the `java.io.Serializable` interface.

For detailed information about programming message-driven beans, see Programming WebLogic Enterprise JavaBeans.

# Designing JMS-Implemented WebLogic Web Services

This section describes the relationship between JMS and WebLogic Web Services operations implemented with a JMS consumer or producer, and design considerations for developing these types of Web Services.

## Retrieving and Processing Messages

After you decide what type of JMS destination you are going to use, you must decide what type of J2EE component will retrieve the message from the JMS destination and process it. Typically this will be a message-driven bean. This message-driven bean can do all the message-processing work, or it can parcel out some or all of the work to other EJBs. Once the message-driven bean finishes processing the message, the execution of the Web Service is complete.

Because a single Web Service operation cannot both send and receive data, you must create two Web Service operations if you want a client application to be able to both send data and receive data. The sending Web Service operation is related to the receiving one because the original message-driven bean that processed the message puts the response on the JMS destination corresponding to the receiving Web Service operation.

## Example of Using JMS Components

Figure 16-1 shows two separate Web Service operations, one for receiving a message from a client and one for sending a message back to the client. The two Web Service operations have their own JMS destinations. The message-driven bean gets messages from the first JMS destination, processes the information, then puts a message back onto the second JMS destination. The client invokes the first Web Service operation to send the message to WebLogic Server and then invokes the second Web Service operation to receive a message back from WebLogic Server.

Figure 16-1 Data Flow Between JMS-Implemented Web Service Operations and JMS

# Creating JMS-Implemented WebLogic Web Services

To create a Web Service implemented with a JMS message producer or consumer, follow these steps:

1. Write the Java code for the J2EE component (typically a message-driven bean) that will consume or produce the message from or on the JMS destination.

For detailed information, see Programming WebLogic Enterprise JavaBeans.

2. Use the Administration Console to configure the following JMS components of WebLogic Server:

- The JMS queue that will either receive the XML data from a client or send XML data to a client. Later, when you assemble the Web Service as described in Assembling WebLogic Web Services Using Ant Tasks, you will use the name of this JMS destination.
- The JMS Connection factory that the WebLogic Web Service uses to create JMS connections.

For more information on this step, see Configuring JMS Components for Message-Style Web Services.

# Configuring JMS Components for Message-Style Web Services

In this section it is assumed that you have already configured a JMS server. For information about configuring JMS servers, and general information about JMS, see JMS: Configuring and Programming WebLogic JMS.

To configure a JMS queue and JMS Connection Factory, follow these steps:

1. Invoke the Administration Console in your browser. For details, see Overview of Administering WebLogic Web Services.
2. In the left pane, open Services—>JMS.
3. Right-click the Connection Factories node and choose Configure a new JMSConnectionFactory from the drop-down list.
4. Enter a name for the Connection Factory in the Name field.
5. Enter the JNDI name of the Connection Factory in the JNDIName field.
6. Enter values in the remaining fields as appropriate. For information on these fields, see JMS: Configuring.
7. Click Create.
8. Select the servers or clusters on which you would like to deploy this JMS connection factory.
9. Click Apply.
10. In the left pane, open Services—>JMS—>Servers.
11. Select the JMS server for which you want to create a JMS destination.
12. Right-click the Destinations node and choose from the drop-down list Configure a new JMSQueue to create a queue.
13. Enter the name of the JMS destination in the Name text field.
14. Enter the JNDI name of the destination in the JNDIName text field.
15. Enter values in the remaining fields as appropriate. For information on these fields, see JMS: Configuring.
16. Click Create.

# Assembling JMS-Implemented WebLogic Web Services Using servicegen

You can use the `servicegen` Ant task to assemble a JMS-implemented Web Service automatically. The Ant task creates a `web-services.xml` deployment descriptor file based on the attributes of the `build.xml` file, optionally creates the non-built-in data type components (such as serialization class), optionally creates a client JAR file used to invoke the Web Service, and packages everything into a deployable EAR file.

To automatically assemble a Web Service using the `servicegen` Ant task:

1. Create a staging directory to hold the components of your Web Service.
2. Package your JMS message consumers and producers (such as message-driven beans) into a JAR file.

For detailed information on this step, refer to Developing WebLogic Server Applications.

3. Copy the JAR file to the staging directory.
4. Set your environment.

On Windows NT, execute the `setEnv.cmd` command, located in your domain directory. The default location of WebLogic Server domains is `BEA_HOME``\user_projects\domains\domainName`, where `BEA_HOME` is the top-level installation directory of the BEA products and `domainName` is the name of your domain.

On UNIX, execute the `setEnv.sh` command, located in your domain directory. The default location of WebLogic Server domains is `BEA_HOME``/user_projects/domains/domainName`, where `BEA_HOME` is the top-level installation directory of the BEA products and `domainName` is the name of your domain.

5. In the staging directory, create the Ant build file (called `build.xml` by default) that contains a call to the `servicegen` Ant task.

For details about specifying the `servicegen` Ant task, see Listing 16-1.

For general information about creating Ant build files, see http://jakarta.apache.org/ant/manual/.

Note: The Apache Jakarta Web site publishes online documentation for only the most current version of Ant, which might be different from the version of Ant that is bundled with WebLogic Server. To determine the version of Ant that is bundled with WebLogic Server, run the following command after setting your WebLogic environment:

>     prompt> ant -version

To view the documentation for a specific version of Ant, download the Ant zip file from http://archive.apache.org/dist/ant/binaries/ and extract the documentation.

6. Execute the Ant task or tasks specified in the `build.xml` file by typing `ant` in the staging directory, optionally passing the command a target argument:

>     prompt> ant

The Ant task generates the Web Services EAR file in the staging directory which you can then deploy on WebLogic Server.

The following sample `build.xml` file contains a call to the `servicegen` Ant task.

Listing 16-1 Sample build.xml File

>     <project name="buildWebservice" default="ear">
>       <target name="ear">
>         <servicegen
>            destEar="jms_send_queue.ear"
>            contextURI="WebServices" >
>            <service
>                JMSDestination="jms.destination.queue1"
>                JMSAction="send"
>                JMSDestinationType="queue"
>                JMSConnectionFactory="jms.connectionFactory.queue"
>                JMSOperationName="sendName"
>                JMSMessageType="types.myType"
>                generateTypes="True"
>                targetNamespace="http://tempuri.org"
>                serviceName="jmsSendQueueService"
>                serviceURI="/jmsSendQueue"
>                expandMethods="True">
>            </service>
>          </servicegen>
>       </target>
>     </project>

When you run the `servicegen` Ant task using the preceding `build.xml` file, the Ant task creates a single Web Service called `jmsSendQueueService`. The URI to identify this Web Service is`/jmsSendQueue`; the full URL to access the Web Service is

>     http://host:port/WebServices/jmsSendQueue

The `servicegen` Ant task packages the Web Service in an EAR file called jms_send_queue.ear. The EAR file contains a WAR file called `web-services.war` (default name) that contains all the Web Service components, such as the `web-services.xml` deployment descriptor file.

The Web Service exposes a single operation called `sendName`. Client applications that invoke this Web Service operation send messages to a JMS queue whose JNDI name is jms.destination.queue1. The JMS `ConnectionFactory` used to create the connection to this queue is jms.connectionFactory.queue. The data type of the single parameter of the `sendName` operation is `types.myType`. Because the `generateTypes` attribute is set to `True`, the `servicegen` Ant task generates the non-built-in data type components for this data type, such as the serialization class.

Note: The `types.myType` Java class must be in `servicegen`'s CLASSPATH so that `servicegen` can generate appropriate components.

# Assembling JMS-Implemented WebLogic Web Services Manually

To assemble a JMS-implemented WebLogic Web Service manually:

1. Package the JMS message consumers and producers into a JAR file. See Packaging the JMS Message Consumers and Producers.
2. Update the `web-services.xml` file with component information. See Updating the web-services.xml File With Component Information.
3. Follow the steps described in Assembling WebLogic Web Services Using Individual Ant Tasks, using the JMS-specific information where appropriate.

The following sections describe JMS-specific information about assembling Web Services manually.

## Packaging the JMS Message Consumers and Producers

Package your JMS message consumers and producers (such as message-driven beans) into a JAR file.

When you create the EAR file that contains the entire Web Service, put this JAR file in the top-level directory, in the same location as EJB JAR files.

## Updating the web-services.xml File With Component Information

Use the `<components>` child element of the `<web-service>` element to list and describe the JMS back-end components that implement the operations of the Web Service. Each back-end component has a `name` attribute that you later use when describing the operation that the component implements.

See Sample web-services.xml File for JMS Component Web Service for an example.

You list the following types of back-end components for JMS-implemented Web Services:

- `<jms-send-destination>`

This element describes a JMS back-end component to which client applications send data. The component puts the sent data on to a JMS destination. Use the `connection-factory` attribute of this element to specify the JMS Connection factory that WebLogic Server uses to create a JMS Connection object. Use the `<jndi-name>` child element to specify the JNDI name of the destination, as shown in the following example:

>     <components>
>        <jms-send-destination name="inqueue"
>                              connection-factory="myapp.myqueueCF">
>            <jndi-name path="myapp.myqueueIN" />
>        </jms-send-destination>
>     </components>

- `<jms-receive-queue>`

This element describes the JMS back-end component in which client applications receive data, in particular from a JMS queue. Use the `connection-factory` attribute to specify the JMS Connection factory that WebLogic Server users to create a JMS Connection object. Use the `<jndi-name>` child element to specify the JNDI name of the queue, as shown in the following example:

>     <components>
>        <jms-receive-queue name="outqueue"
>                           connection-factory="myapp.myqueueCF">
>            <jndi-name path="myapp.myqueueOUT" />
>        </jms-receive-queue>
>     </components>

## Sample web-services.xml File for JMS Component Web Service

The following sample `web-services.xml` file describes a Web Service that is implemented with a JMS message consumer or producer:

>     <web-services>
>          <web-service targetNamespace="http://example.com"
>                        name="myMessageService" uri="MessageService">

>              <components>
>                 <jms-send-destination name="inqueue"
>                                       connection-factory="myapp.myqueuecf">
>                      <jndi-name path="myapp.myinputqueue" />
>                 </jms-send-destination>
>                 <jms-receive-queue name="outqueue"
>                                    connection-factory="myapp.myqueuecf">
>                      <jndi-name path="myapp.myoutputqueue" />
>                 </jms-receive-queue>
>              </components>

>              <operations xmlns:xsd="http://www.w3.org/2001/XMLSchema">
>                   <operation invocation-style="one-way" name="enqueue"
>                              component="inqueue" />
>                      <params>
>                        <param name="input_payload" style="in" type="xsd:anyType" />
>                      </params>
>                   </operation>
>                   <operation invocation-style="request-response" name="dequeue"
>                              component="outqueue" >
>                      <params>
>                        <return-param name="output_payload" type="xsd:anyType"/>
>                      </params>
>                   </operation>
>              </operations>
>          </web-service>
>     </web-services>

The example shows two JMS back-end components, one called `inqueue` in which a client application sends data to a JMS destination, and one called `outqueue` in which a client application receives data from a JMS queue.

Two corresponding Web Service operations, `enqueue` and `dequeue`, are implemented with these back-end components.

The `enqueue` operation is implemented with the `inqueue` component. This operation is defined to be asynchronous one-way, which means that the client application, after sending the data to the JMS destination, does not receive a SOAP response (not even an exception.) The data sent by the client is contained in the `input_payload` parameter.

The `dequeue` operation is implemented with the `outqueue` component. The `dequeue` operation is defined as synchronous request-response because the client application invokes the operation to receive data from the JMS queue. The response data is contained in the output parameter `output_payload`.

# Deploying JMS-Implemented WebLogic Web Services

Deploying a WebLogic Web Service refers to making it available to remote clients. Because WebLogic Web Services are packaged as standard J2EE Enterprise applications, deploying a Web Service is the same as deploying an Enterprise application.

For detailed information on deploying Enterprise applications, see Deploying WebLogic Server Applications.

# Invoking JMS-Implemented WebLogic Web Services

This section shows two sample client applications that invoke JMS-implemented WebLogic Web Services: a client application that sends data to a service operation, and a client application that receives data from another operation within the same Web Service. The first operation is implemented with a JMS destination, the second with a JMS queue, as shown in the following `web-services.xml` file that describes the Web Service:

>     <web-services xmlns:xsd="http://www.w3.org/2001/XMLSchema" >

>       <web-service
>         name="BounceService"
>         targetNamespace="http://www.foobar.com/echo"
>         uri="/BounceService">

>           <components>

>              <jms-send-destination name="inqueue"
>                            connection-factory="weblogic.jms.ConnectionFactory">
>                   <jndi-name path="weblogic.jms.inqueue" />
>             </jms-send-destination>
>             <jms-receive-queue name="outqueue"
>                           connection-factory="weblogic.jms.ConnectionFactory">
>                  <jndi-name path="weblogic.jms.outqueue" />
>             </jms-receive-queue>
>        </components>

>        <operations xmlns:xsd="http://www.w3.org/2001/XMLSchema">
>           <operation invocation-style="one-way" name="submit" component="inqueue" >
>           </operation>

>           <operation invocation-style="request-response"
>                      name="query" component="outqueue" >
>              <params>
>                  <return-param name="output_payload" type="xsd:string"/>
>             </params>
>           </operation>
>        </operations>

>      </web-service>

>     </web-services>

### Invoking an Asynchronous Web Service Operation to Send Data

The following example shows a dynamic client application that invokes the `submit` operation, described in the `web-services.xml` file in the preceding section. The `submit` operation sends data from the client application to the weblogic.jms.inqueue JMS destination. Because the operation is defined as `one-way`, it is asynchronous and does not return any value to the client application that invoked it.

>     import java.io.BufferedReader;
>     import java.io.InputStream;
>     import java.io.InputStreamReader;
>     import javax.xml.rpc.ServiceFactory;
>     import javax.xml.rpc.Service;
>     import javax.xml.rpc.Call;
>     import javax.xml.rpc.ParameterMode;

>     import javax.xml.namespace.QName;

>     /**
>      * @author Copyright (c) 2002 by BEA Systems, Inc. All Rights Reserved.
>      */

>     /**
>      * send2WS - this module sends to a specific Web Service connected JMS queue
>      * If the message is 'quit' then the module exits.
>      *
>      * @returns
>      * @throws Exception
>      */

>     public class send2WS{

>       public static void main( String[] args ) throws Exception {

>       // Setup the global JAX-RPC service factory
>       System.setProperty( "javax.xml.rpc.ServiceFactory",
>         "weblogic.webservice.core.rpc.ServiceFactoryImpl");

>       ServiceFactory factory = ServiceFactory.newInstance();

>       //define qnames
>       String targetNamespace = "http://www.foobar.com/echo";

>       QName serviceName = new QName( targetNamespace, "BounceService" );
>       QName portName = new QName( targetNamespace, "BounceServicePort" );

>       //create service
>       Service service = factory.createService( serviceName );

>       //create outbound call
>       Call Ws2JmsCall = service.createCall();

>       QName operationName = new QName( targetNamespace, "submit" );

>       //set port and operation name
>       Ws2JmsCall.setPortTypeName( portName );
>       Ws2JmsCall.setOperationName( operationName );

>       //add parameters
>       Ws2JmsCall.addParameter( "param",
>             new QName( "http://www.w3.org/2001/XMLSchema", "string" ), ParameterMode.IN

>     );
>       //set end point address
>       Ws2JmsCall.setTargetEndpointAddress(
>             "http://localhost:7001/BounceBean/BounceService" );

>       // get message from user
>       BufferedReader msgStream =
>           new BufferedReader(new InputStreamReader(System.in));
>       String line = null;
>       boolean quit = false;
>       while (!quit) {
>         System.out.print("Enter message (\"quit\" to quit): ");
>         line = msgStream.readLine();
>         if (line != null && line.trim().length() != 0) {
>               String result = (String)Ws2JmsCall.invoke( new Object[]{ line } );
>           if(line.equalsIgnoreCase("quit")) {
>                 quit = true;
>                 System.out.print("Done!");
>             }
>           }
>         }
>       }
>     }

### Invoking a Synchronous Web Service Operation to Send Data

The following example shows a dynamic client application that invokes the `query` operation, described in the `web-services.xml` file in Invoking JMS-Implemented WebLogic Web Services. The client application invoking the `query` operation receives data from the weblogic.jms.outqueue JMS queue. Because the operation is defined as `request-response`, it is synchronous and returns the data from the JMS queue to the client application.

>     import javax.xml.rpc.ServiceFactory;
>     import javax.xml.rpc.Service;
>     import javax.xml.rpc.Call;
>     import javax.xml.rpc.ParameterMode;

>     import javax.xml.namespace.QName;

>     /**
>      * @author Copyright (c) 2002 by BEA Systems, Inc. All Rights Reserved.
>      */

>     /**
>      * fromWS - this module receives from a Web Service associated JMS queue
>      * If the message is 'quit' then the module exits.
>      *
>      * @returns
>      * @throws Exception
>      */

>     public class fromWS {

>       public static void main( String[] args ) throws Exception {

>       boolean quit = false;
>       // Setup the global JAX-RPC service factory
>       System.setProperty( "javax.xml.rpc.ServiceFactory",
>           "weblogic.webservice.core.rpc.ServiceFactoryImpl");

>       ServiceFactory factory = ServiceFactory.newInstance();

>       //define qnames
>       String targetNamespace = "http://www.foobar.com/echo";

>       QName serviceName = new QName( targetNamespace, "BounceService" );
>       QName portName = new QName( targetNamespace, "BounceServicePort" );

>       //create service
>       Service service = factory.createService( serviceName );

>       //create outbound call
>       Call Ws2JmsCall = service.createCall();

>       QName operationName = new QName( targetNamespace, "query" );

>       //set port and operation name
>       Ws2JmsCall.setPortTypeName( portName );
>       Ws2JmsCall.setOperationName( operationName );

>       //add parameters
>       Ws2JmsCall.addParameter( "output_payload",
>             new QName( "http://www.w3.org/2001/XMLSchema", "string" ),
>                          ParameterMode.OUT );
>       //set end point address
>       Ws2JmsCall.setTargetEndpointAddress(
>             "http://localhost:7001/BounceBean/BounceService" );

>       System.out.println("Setup complete.  Waiting for a message...");

>       while (!quit) {
>             String result = (String)Ws2JmsCall.invoke( new Object[] {} );
>             if(result != null) {
>               System.out.println("TextMessage:" + result);
>           if (result.equalsIgnoreCase("quit")) {
>                 quit = true;
>             System.out.println("Done!");
>               }
>             continue;
>             }
>         try {Thread.sleep(2000);} catch (Exception ignore) {}
>       }
>      }
>     }