Skip Headers
Oracle® Application Server Web Services Developer's Guide
10g Release 3 (10.1.3)
B14434-01
  Go To Documentation Library
Home
Go To Product List
Solution Area
Go To Table Of Contents
Contents
Go To Index
Index

Previous
Previous
Next
Next
 

8 Assembling Web Services with JMS Destinations

This chapter describes how to expose a JMS destination as a Web service. A JMS endpoint Web service exposes JMS destinations, either queues or topics, as document-literal style operations in the WSDL. The operation can be in either send or receive mode.

A JMS endpoint Web service can be considered to be a special case of the Java endpoint Web service. In a JMS endpoint Web service, the JMS endpoint implements Web service operations by sending and receiving JMS message objects.


Note:

There are differences between a Web service based on queues (or Oracle Streams Advanced Queuing (AQ)) in the database and a Web service based on a JMS destination. The AQ Web service is based on a configuration of queues that reside in the database. The JMS destination Web service is based on the configuration of a JMS provider in the middle tier. The JMS queues reside in a backend data source. This data source could be a database, a file-based system, or some other data repository.

If you want to construct a Web service from a queue or an AQ in the database, see "Exposing an Oracle Streams AQ as a Web Service".


Understanding JMS Endpoint Web Services

OracleAS Web Services enables you to create Web service endpoints that let you put messages on and take messages off JMS destinations. A JMS Web service endpoint is configured to transfer messages to and from a specific JMS destination or pair of destinations.

A JMS endpoint Web service can have the following operations.

A JMS endpoint Web service can be configured so that message-ID, correlation-ID, and reply-to-destination JMS message properties can be transmitted as SOAP headers. With this configuration, the message property headers and their types are explicitly declared on the generated WSDL and schema so that the Web service client can use them.

An individual JMS endpoint Web service can support just the send operation, just the receive operation, or both operations, as determined by the service developer.

JMS endpoint Web services use javax.jms.ObjectMessage as the JMS message type. As content, it can carry an instance of javax.xml.soap.SOAPElement or a String representation of an XML fragment.

The WSDL generated for a send JMS endpoint Web service follows the Web Service-Interoperability (WS-I) Basic Profile 1.0 and should be interoperable.

Figure 8-1 shows an MDB-based JMS endpoint Web service application that, from the JMS endpoint Web service's view, handles both the message send and the message receive operations. The figure also includes an MDB that is configured to listen to a JMS destination.

Figure 8-1 MDB-Based JMS Endpoint Web Service

Description of Figure 8-1 follows
Description of "Figure 8-1 MDB-Based JMS Endpoint Web Service"

The following steps describe how the MDB-based JMS endpoint Web service application illustrated in Figure 8-1 works.

  1. A Web service client sends a SOAP request to invoke the send operation on the JMS endpoint Web service.

  2. The JMS endpoint Web service processes the incoming message and directs it to a JMS destination, JMS Destination 1.

  3. The EJB container invokes the MDB listening on JMS Destination 1.

  4. After processing the message an MDB produces a new message on JMS Destination 2. Producing and consuming messages could involve one or more MDBs. For example, a single MDB could be listing on JMS Destination 1 and the same MDB could also send the message to JMS Destination 2.

  5. (Arrows 5 and 6) A Web service client sends a SOAP request to perform a receive operation on the JMS endpoint Web service to retrieve a message. The JMS endpoint Web service consumes a message from the JMS destination, encloses it in a SOAP response message, and passes the outgoing SOAP response message to the client.

How to Assemble a JMS Endpoint Web Service

The following steps describe how to assemble a JMS Endpoint Web service with the WebServicesAssembler tool.

  1. Generate the Web service EAR file by running the WebServicesAssembler with the jmsAssemble command. The J2EE EAR file produced by this command includes the JMS endpoint Web service configuration information, including the WSDL and the generated web.xml file. For example:

    java -jar wsa.jar -jmsAssemble
         -sendConnectionFactoryLocation jms/ws/mdb/theQueueConnectionFactory
         -sendQueueLocation jms/ws/mdb/theQueue
         -replyToConnectionFactoryLocation jms/ws/mdb/logQueueConnectionFactory
         -replyToQueueLocation jms/ws/mdb/logQueue
         -linkReceiveWithReplyTo true
         -targetNamespace http://oracle.j2ee.ws/jms-doc
         -typeNamespace http://oracle.j2ee.ws/jms-doc/types
         -serviceName JmsService
         -appName jms_service
         -context jms_service
         -input ./build/mdb_service.jar
         -uri JmsService
         -output ./dist
    
    

    For the jmsAssemble command you must specify as a minimum, either a sendConnectionFactoryLocation or replyToConnectionFactoryLocation. For more information on this command, see "jmsAssemble".

    In this example, jms/ws/mdb/theQueueConnectionFactory is the JNDI name of the JMS connection factory used to produce connections to the JMS queue for the JMS send operation.

    • jms/ws/mdb/theQueue—the JNDI name of the JMS queue to which the send operation sends the SOAP message payload.

    • jms/ws/mdb/logQueueConnectionFactory—the JNDI name of the JMS connection factory to be used for the reply-to queue.

    • jms/ws/mdb/logQueue—the JNDI name of the JMS queue that will be set to each send message as the default reply-to destination. Because the linkReceiveWithReplyTo argument is enabled in this example, this reply-to destination is also used by the receive operation of the JMS endpoint Web service to retrieve messages.

  2. Deploy all of the JMS destinations.

  3. Deploy the service and bind the application.

    Deploy the EAR file in the standard manner into a running instance of OC4J. For more information on deploying EAR files, see Chapter 18, "Packaging and Deploying Web Services" and the Oracle Containers for J2EE Deployment Guide. The following is a sample deployment command:

    java -jar <OC4J_HOME>/j2ee/home/admin_client.jar deployer:oc4j:localhost:port <user> <password> 
                -deploy 
                -file dist/jms_service.ear 
                -deploymentName jms_service 
                -bindWebApp default-web-site
    
    

    The following list describes the parameters in this code example.

    • <oc4jHome>—The directory containing the OC4J installation.

    • <user>—The user name for the OC4J instance. The user name is assigned at installation time.

    • <password>—The password for the OC4J instance. The password is assigned at installation time.

    • default-web-site —The Web site to which the application will be bound. This is usually default-web-site. To configure Web sites, see the server.xml file in <OC4J_HOME>/j2ee/home/config.

  4. (Optional) Check that deployment succeeded. OracleAS Web Services provides a Web Service Home Page for each deployed Web service. See "Using the Web Services Home Page" for information on accessing and using the Web Service Home Page.

  5. Generate the client-side code.

    There is no difference between generating a client-side proxy from a JMS endpoint Web service WSDL and any other Web service WSDL. The JMS endpoint Web service WSDL is interoperable, in that it should be consumed by WS-I Basic Profile 1.0-compliant WSDL tools. For example, you can use a .NET WSDL tool to generate C# client stubs to communicate with an Oracle JMS endpoint Web service.

    • For the J2SE environment, generate stubs (client proxies) for a J2SE Web service client by running the WebServicesAssembler tool with the genProxy command. For more information on generating and assembling client-side code for the J2SE environment, see Chapter 14, "Assembling a J2SE Web Service Client".

    • For the J2EE environment, generate a service endpoint interface and a mapping file for a J2EE Web service client by running the WebServicesAssembler tool with the genInterface command. For more information on generating and assembling client-side code, see Chapter 13, "Assembling a J2EE Web Service Client".

    For example, the following command generates stubs that can be used for a J2SE client:

    java -jar wsa.jar -genProxy 
                      -output build/src/client/ 
                      -wsdl http://localhost:8888/hello/JmsService?WSDL 
                      -packageName oracle.demo.jms_service
    
    

    This command generates the client proxies and stores them in the directory build/src/client. The client application uses the stub to invoke operations on a remote service. For more information on the required and optional arguments to genProxy, see "genProxy".

  6. Compile and run the client.

    List the appropriate JARs on the classpath before compiling the client. Table A-2, "Classpath Components for a Client Using a Client-Side Proxy" lists all of the JAR files that can possibly be used on the client classpath. As an alternative to listing individual JARs, you can include the client-side JAR, wsclient_extended.jar on the client classpath. This JAR file contains all the classes necessary to compile and run a Web service client. The classes are from the individual JAR files listed in Table A-2. See "Setting the Web Service Proxy Client Classpath" for more information on wsclient_extended.jar and the client classpath.

Ant Tasks for Generating a Web Service

This release provides Ant tasks for Web service development. The following code sample shows how the jmsAssemble command can be rewritten as an Ant task.

<oracle:jmsAssemble
         linkReceiveWithReplyTo="true"
         targetNamespace="http://oracle.j2ee.ws/jms-doc"
         typeNamespace="http://oracle.j2ee.ws/jms-doc/types"
         serviceName="JmsService"
         appName="jms_service"
         context="jms_service"
         input="./build/mdb_service.jar"
         uri="JmsService"
         output="./dist"
         sendConnectionFactoryLocation="jms/ws/mdb/theQueueConnectionFactory"
         sendQueueLocation="jms/ws/mdb/theQueue"
         replyToConnectionFactoryLocation="jms/ws/mdb/logQueueConnectionFactory"
         replyToQueueLocation="jms/ws/mdb/logQueue"/>

Message Processing and Reply Messages

The JMS endpoint Web service processes an incoming SOAP message and places the payload (the body element of the SOAP message) on a JMS destination. This section covers details that a developer needs to know to consume and process the JMS messages that originate from a JMS endpoint Web service.

The JMS message content associated with a JMS endpoint Web service can be either an instance of javax.xml.soap.SOAPElement (which is also a subclass of org.w3c.dom.Element), or java.lang.String which is the string representation of the XML payload. The JMS endpoint Web service may set certain JMS message header values before it places the message on a JMS destination. Depending on the values of optional configuration arguments specified when the JMS endpoint Web service is assembled, the JMS endpoint Web service sets the following JMS message headers.

JMSType
JMSReplyTo
JMSExpiration
JMSPriority
JMSDeliveryMode

When the JMS endpoint Web service sets the JMSReplyTo header, it uses either the value specified with the replyToTopicLocation or the replyToQueueLocation (only one of these should be configured for any given JMS endpoint Web service). The value specified with the replyToConnectionFactoryLocation argument is set on the message as a standard string property. The property name is OC4J_REPLY_TO_FACTORY_NAME.

Example 8-1 provides a code segment that shows where the onMessage() method gets the reply-to information for a message generated from a JMS endpoint Web service send operation:

Example 8-1 Getting Reply-To Information for a Message Generated by a Send Operation

...
public void onMessage(Message inMessage) {
    // Do some processing
    ObjectMessage msg = null;
    String  factoryName;
    Destination dest;
    Element  el;
    try {
      // Message should be of type objectMessage
      if (inMessage instanceof ObjectMessage) {
        // retrieve the object
        msg = (ObjectMessage) inMessage;
        el = (Element)msg.getObject();
        System.out.println("MessageBean2::onMessage() => Message received: " );
        ((XMLElement)el).print(System.out);  
        processElement(el);
        factoryName = inMessage.getStringProperty("OC4J_REPLY_TO_FACTORY_NAME");
        dest = inMessage.getJMSReplyTo();
...

Limitations

See "Assembling Web Services with JMS Destinations".

Additional Information

For more information on: