Chapter 42. Working with Contexts Abstract JAX-WS uses contexts to pass metadata along the messaging chain. This metadata, depending on its scope, is accessible to implementation level code. It is also accessible to JAX-WS handlers that operate on the message below the implementation level. 42.1. Understanding Contexts Overview In many instances it is necessary to pass information about a message to other parts of an application. Apache CXF does this using a context mechanism. Contexts are maps that hold properties relating to an outgoing or an incoming message. The properties stored in the context are typically metadata about the message, and the underlying transport used to communicate the message. For example, the transport specific headers used in transmitting the message, such as the HTTP response code or the JMS correlation ID, are stored in the JAX-WS contexts. The contexts are available at all levels of a JAX-WS application. However, they differ in subtle ways depending upon where in the message processing stack you are accessing the context. JAX-WS Handler implementations have direct access to the contexts and can access all properties that are set in them. Service implementations access contexts by having them injected, and can only access properties that are set in the APPLICATION scope. Consumer implementations can only access properties that are set in the APPLICATION scope. Figure 42.1, "Message Contexts and Message Processing Path" shows how the context properties pass through Apache CXF. As a message passes through the messaging chain, its associated message context passes along with it. Figure 42.1. Message Contexts and Message Processing Path How properties are stored in a context The message contexts are all implementations of the javax.xml.ws.handler.MessageContext interface. The MessageContext interface extends the java.util.Map<String key, Object value> interface. Map objects store information as key value pairs. In a message context, properties are stored as name/value pairs. A property's key is a String that identifies the property. The value of a property can be any value stored in any Java object. When the value is returned from a message context, the application must know the type to expect and cast accordingly. For example, if a property's value is stored in a UserInfo object it is still returned from a message context as an Object object that must be cast back into a UserInfo object. Properties in a message context also have a scope. The scope determines where a property can be accessed in the message processing chain. Property scopes Properties in a message context are scoped. A property can be in one of the following scopes: APPLICATION Properties scoped as APPLICATION are available to JAX-WS Handler implementations, consumer implementation code, and service provider implementation code. If a handler needs to pass a property to the service provider implementation, it sets the property's scope to APPLICATION . All properties set from either the consumer implementation or the service provider implementation contexts are automatically scoped as APPLICATION . HANDLER Properties scoped as HANDLER are only available to JAX-WS Handler implementations. Properties stored in a message context from a Handler implementation are scoped as HANDLER by default. You can change a property's scope using the message context's setScope() method. Example 42.1, "The MessageContext.setScope() Method" shows the method's signature. Example 42.1. The MessageContext.setScope() Method setScope String key MessageContext.Scope scope java.lang.IllegalArgumentException The first parameter specifies the property's key. The second parameter specifies the new scope for the property. The scope can be either: MessageContext.Scope.APPLICATION MessageContext.Scope.HANDLER Overview of contexts in handlers Classes that implement the JAX-WS Handler interface have direct access to a message's context information. The message's context information is passed into the Handler implementation's handleMessage() , handleFault() , and close() methods. Handler implementations have access to all of the properties stored in the message context, regardless of their scope. In addition, logical handlers use a specialized message context called a LogicalMessageContext . LogicalMessageContext objects have methods that access the contents of the message body. Overview of contexts in service implementations Service implementations can access properties scoped as APPLICATION from the message context. The service provider's implementation object accesses the message context through the WebServiceContext object. For more information see Section 42.2, "Working with Contexts in a Service Implementation" . Overview of contexts in consumer implementations Consumer implementations have indirect access to the contents of the message context. The consumer implementation has two separate message contexts: Request context - holds a copy of the properties used for outgoing requests Response context - holds a copy of the properties from an incoming response The dispatch layer transfers the properties between the consumer implementation's message contexts and the message context used by the Handler implementations. When a request is passed to the dispatch layer from the consumer implementation, the contents of the request context are copied into the message context that is used by the dispatch layer. When the response is returned from the service, the dispatch layer processes the message and sets the appropriate properties into its message context. After the dispatch layer processes a response, it copies all of the properties scoped as APPLICATION in its message context to the consumer implementation's response context. For more information see Section 42.3, "Working with Contexts in a Consumer Implementation" . 42.2. Working with Contexts in a Service Implementation Overview Context information is made available to service implementations using the WebServiceContext interface. From the WebServiceContext object you can obtain a MessageContext object that is populated with the current request's context properties in the application scope. You can manipulate the values of the properties, and they are propagated back through the response chain. Note The MessageContext interface inherits from the java.util.Map interface. Its contents can be manipulated using the Map interface's methods. Obtaining a context To obtain the message context in a service implementation do the following: Declare a variable of type WebServiceContext. Decorate the variable with the javax.annotation.Resource annotation to indicate that the context information is being injected into the variable. Obtain the MessageContext object from the WebServiceContext object using the getMessageContext() method. Important getMessageContext() can only be used in methods that are decorated with the @WebMethod annotation. Example 42.2, "Obtaining a Context Object in a Service Implementation" shows code for obtaining a context object. Example 42.2. Obtaining a Context Object in a Service Implementation Reading a property from a context Once you have obtained the MessageContext object for your implementation, you can access the properties stored there using the get() method shown in Example 42.3, "The MessageContext.get() Method" . Example 42.3. The MessageContext.get() Method V get Object key Note This get() is inherited from the Map interface. The key parameter is the string representing the property you want to retrieve from the context. The get() returns an object that must be cast to the proper type for the property. Table 42.1, "Properties Available in the Service Implementation Context" lists a number of the properties that are available in a service implementation's context. Important Changing the values of the object returned from the context also changes the value of the property in the context. Example 42.4, "Getting a Property from a Service's Message Context" shows code for getting the name of the WSDL operation element that represents the invoked operation. Example 42.4. Getting a Property from a Service's Message Context Setting properties in a context Once you have obtained the MessageContext object for your implementation, you can set properties, and change existing properties, using the put() method shown in Example 42.5, "The MessageContext.put() Method" . Example 42.5. The MessageContext.put() Method V put K key V value ClassCastExceptionIllegalArgumentExceptionNullPointerException If the property being set already exists in the message context, the put() method replaces the existing value with the new value and returns the old value. If the property does not already exist in the message context, the put() method sets the property and returns null . Example 42.6, "Setting a Property in a Service's Message Context" shows code for setting the response code for an HTTP request. Example 42.6. Setting a Property in a Service's Message Context Supported contexts Table 42.1, "Properties Available in the Service Implementation Context" lists the properties accessible through the context in a service implementation object. Table 42.1. Properties Available in the Service Implementation Context Property Name Description org.apache.cxf.message.Message PROTOCOL_HEADERS [a] Specifies the transport specific header information. The value is stored as a java.util.Map<String, List<String>> . RESPONSE_CODE Specifies the response code returned to the consumer. The value is stored as an Integer object. ENDPOINT_ADDRESS Specifies the address of the service provider. The value is stored as a String . HTTP_REQUEST_METHOD Specifies the HTTP verb sent with a request. The value is stored as a String . PATH_INFO Specifies the path of the resource being requested. The value is stored as a String . The path is the portion of the URI after the hostname and before any query string. For example, if an endpoint's URI is http://cxf.apache.org/demo/widgets the path is /demo/widgets . QUERY_STRING Specifies the query, if any, attached to the URI used to invoke the request. The value is stored as a String . Queries appear at the end of the URI after a ? . For example, if a request is made to http://cxf.apache.org/demo/widgets?color the query is color . MTOM_ENABLED Specifies whether or not the service provider can use MTOM for SOAP attachments. The value is stored as a Boolean . SCHEMA_VALIDATION_ENABLED Specifies whether or not the service provider validates messages against a schema. The value is stored as a Boolean . FAULT_STACKTRACE_ENABLED Specifies if the runtime provides a stack trace along with a fault message. The value is stored as a Boolean . CONTENT_TYPE Specifies the MIME type of the message. The value is stored as a String . BASE_PATH Specifies the path of the resource being requested. The value is stored as a java.net.URL . The path is the portion of the URI after the hostname and before any query string. For example, if an endpoint's URL is http://cxf.apache.org/demo/widgets the base path is /demo/widgets . ENCODING Specifies the encoding of the message. The value is stored as a String . FIXED_PARAMETER_ORDER Specifies whether the parameters must appear in the message in a particular order. The value is stored as a Boolean . MAINTAIN_SESSION Specifies if the consumer wants to maintain the current session for future requests. The value is stored as a Boolean . WSDL_DESCRIPTION Specifies the WSDL document that defines the service being implemented. The value is stored as a org.xml.sax.InputSource object. WSDL_SERVICE Specifies the qualified name of the wsdl:service element that defines the service being implemented. The value is stored as a QName . WSDL_PORT Specifies the qualified name of the wsdl:port element that defines the endpoint used to access the service. The value is stored as a QName . WSDL_INTERFACE Specifies the qualified name of the wsdl:portType element that defines the service being implemented. The value is stored as a QName . WSDL_OPERATION Specifies the qualified name of the wsdl:operation element that corresponds to the operation invoked by the consumer. The value is stored as a QName . javax.xml.ws.handler.MessageContext MESSAGE_OUTBOUND_PROPERTY Specifies if a message is outbound. The value is stored as a Boolean . true specifies that a message is outbound. INBOUND_MESSAGE_ATTACHMENTS Contains any attachments included in the request message. The value is stored as a java.util.Map<String, DataHandler> . The key value for the map is the MIME Content-ID for the header. OUTBOUND_MESSAGE_ATTACHMENTS Contains any attachments for the response message. The value is stored as a java.util.Map<String, DataHandler> . The key value for the map is the MIME Content-ID for the header. WSDL_DESCRIPTION Specifies the WSDL document that defines the service being implemented. The value is stored as a org.xml.sax.InputSource object. WSDL_SERVICE Specifies the qualified name of the wsdl:service element that defines the service being implemented. The value is stored as a QName . WSDL_PORT Specifies the qualified name of the wsdl:port element that defines the endpoint used to access the service. The value is stored as a QName . WSDL_INTERFACE Specifies the qualified name of the wsdl:portType element that defines the service being implemented. The value is stored as a QName . WSDL_OPERATION Specifies the qualified name of the wsdl:operation element that corresponds to the operation invoked by the consumer. The value is stored as a QName . HTTP_RESPONSE_CODE Specifies the response code returned to the consumer. The value is stored as an Integer object. HTTP_REQUEST_HEADERS Specifies the HTTP headers on a request. The value is stored as a java.util.Map<String, List<String>> . HTTP_RESPONSE_HEADERS Specifies the HTTP headers for the response. The value is stored as a java.util.Map<String, List<String>> . HTTP_REQUEST_METHOD Specifies the HTTP verb sent with a request. The value is stored as a String . SERVLET_REQUEST Contains the servlet's request object. The value is stored as a javax.servlet.http.HttpServletRequest . SERVLET_RESPONSE Contains the servlet's response object. The value is stored as a javax.servlet.http.HttpResponse . SERVLET_CONTEXT Contains the servlet's context object. The value is stored as a javax.servlet.ServletContext . PATH_INFO Specifies the path of the resource being requested. The value is stored as a String . The path is the portion of the URI after the hostname and before any query string. For example, if an endpoint's URL is http://cxf.apache.org/demo/widgets the path is /demo/widgets . QUERY_STRING Specifies the query, if any, attached to the URI used to invoke the request. The value is stored as a String . Queries appear at the end of the URI after a ? . For example, if a request is made to http://cxf.apache.org/demo/widgets?color the query string is color . REFERENCE_PARAMETERS Specifies the WS-Addressing reference parameters. This includes all of the SOAP headers whose wsa:IsReferenceParameter attribute is set to true . The value is stored as a java.util.List . org.apache.cxf.transport.jms.JMSConstants JMS_SERVER_HEADERS Contains the JMS message headers. For more information see Section 42.4, "Working with JMS Message Properties" . [a] When using HTTP this property is the same as the standard JAX-WS defined property. 42.3. Working with Contexts in a Consumer Implementation Overview Consumer implementations have access to context information through the BindingProvider interface. The BindingProvider instance holds context information in two separate contexts: Request Context The request context enables you to set properties that affect outbound messages. Request context properties are applied to a specific port instance and, once set, the properties affect every subsequent operation invocation made on the port, until such time as a property is explicitly cleared. For example, you might use a request context property to set a connection timeout or to initialize data for sending in a header. Response Context The response context enables you to read the property values set by the response to the last operation invocation made from the current thread. Response context properties are reset after every operation invocation. For example, you might access a response context property to read header information received from the last inbound message. Important Only information that is placed in the application scope of a message context can be accessed by the consumer implementation. Obtaining a context Contexts are obtained using the javax.xml.ws.BindingProvider interface. The BindingProvider interface has two methods for obtaining a context: getRequestContext() The getRequestContext() method, shown in Example 42.7, "The getRequestContext() Method" , returns the request context as a Map object. The returned Map object can be used to directly manipulate the contents of the context. Example 42.7. The getRequestContext() Method Map<String, Object> getRequestContext getResponseContext() The getResponseContext() , shown in Example 42.8, "The getResponseContext() Method" , returns the response context as a Map object. The returned Map object's contents reflect the state of the response context's contents from the most recent successful request on a remote service made in the current thread. Example 42.8. The getResponseContext() Method Map<String, Object> getResponseContext Since proxy objects implement the BindingProvider interface, a BindingProvider object can be obtained by casting a proxy object. The contexts obtained from the BindingProvider object are only valid for operations invoked on the proxy object used to create it. Example 42.9, "Getting a Consumer's Request Context" shows code for obtaining the request context for a proxy. Example 42.9. Getting a Consumer's Request Context Reading a property from a context Consumer contexts are stored in java.util.Map<String, Object> objects. The map has keys that are String objects and values that contain arbitrary objects. Use java.util.Map.get() to access an entry in the map of response context properties. To retrieve a particular context property, ContextPropertyName , use the code shown in Example 42.10, "Reading a Response Context Property" . Example 42.10. Reading a Response Context Property Setting properties in a context Consumer contexts are hash maps stored in java.util.Map<String, Object> objects. The map has keys that are String objects and values that are arbitrary objects. To set a property in a context use the java.util.Map.put() method. While you can set properties in both the request context and the response context, only the changes made to the request context have any impact on message processing. The properties in the response context are reset when each remote invocation is completed on the current thread. The code shown in Example 42.11, "Setting a Request Context Property" changes the address of the target service provider by setting the value of the BindingProvider.ENDPOINT_ADDRESS_PROPERTY. Example 42.11. Setting a Request Context Property Important Once a property is set in the request context its value is used for all subsequent remote invocations. You can change the value and the changed value will then be used. Supported contexts Apache CXF supports the following context properties in consumer implementations: Table 42.2. Consumer Context Properties Property Name Description javax.xml.ws.BindingProvider ENDPOINT_ADDRESS_PROPERTY Specifies the address of the target service. The value is stored as a String . USERNAME_PROPERTY [a] Specifies the username used for HTTP basic authentication. The value is stored as a String . PASSWORD_PROPERTY [b] Specifies the password used for HTTP basic authentication. The value is stored as a String . SESSION_MAINTAIN_PROPERTY [c] Specifies if the client wants to maintain session information. The value is stored as a Boolean object. org.apache.cxf.ws.addressing.JAXWSAConstants CLIENT_ADDRESSING_PROPERTIES Specifies the WS-Addressing information used by the consumer to contact the desired service provider. The value is stored as a org.apache.cxf.ws.addressing.AddressingProperties . org.apache.cxf.transports.jms.context.JMSConstants JMS_CLIENT_REQUEST_HEADERS Contains the JMS headers for the message. For more information see Section 42.4, "Working with JMS Message Properties" . [a] This property is overridden by the username defined in the HTTP security settings. [b] This property is overridden by the password defined in the HTTP security settings. [c] The Apache CXF ignores this property. 42.4. Working with JMS Message Properties Abstract The Apache CXF JMS transport has a context mechanism that can be used to inspect a JMS message's properties. The context mechanism can also be used to set a JMS message's properties. 42.4.1. Inspecting JMS Message Headers Abstract Consumers and services use different context mechanisms to access the JMS message header properties. However, both mechanisms return the header properties as a org.apache.cxf.transports.jms.context.JMSMessageHeadersType object. Getting the JMS Message Headers in a Service To get the JMS message header properties from the WebServiceContext object, do the following: Obtain the context as described in the section called "Obtaining a context" . Get the message headers from the message context using the message context's get() method with the parameter org.apache.cxf.transports.jms.JMSConstants.JMS_SERVER_HEADERS. Example 42.12, "Getting JMS Message Headers in a Service Implementation" shows code for getting the JMS message headers from a service's message context: Example 42.12. Getting JMS Message Headers in a Service Implementation Getting JMS Message Header Properties in a Consumer Once a message is successfully retrieved from the JMS transport you can inspect the JMS header properties using the consumer's response context. In addition, you can set or check the length of time the client will wait for a response before timing out, as described in the section called "Client Receive Timeout" . To get the JMS message headers from a consumer's response context do the following: Get the response context as described in the section called "Obtaining a context" . Get the JMS message header properties from the response context using the context's get() method with org.apache.cxf.transports.jms.JMSConstants.JMS_CLIENT_RESPONSE_HEADERS as the parameter. Example 42.13, "Getting the JMS Headers from a Consumer Response Header" shows code for getting the JMS message header properties from a consumer's response context. Example 42.13. Getting the JMS Headers from a Consumer Response Header The code in Example 42.13, "Getting the JMS Headers from a Consumer Response Header" does the following: Casts the proxy to a BindingProvider. Gets the response context. Retrieves the JMS message headers from the response context. 42.4.2. Inspecting the Message Header Properties Standard JMS Header Properties Table 42.3, "JMS Header Properties" lists the standard properties in the JMS header that you can inspect. Table 42.3. JMS Header Properties Property Name Property Type Getter Method Correlation ID string getJMSCorralationID() Delivery Mode int getJMSDeliveryMode() Message Expiration long getJMSExpiration() Message ID string getJMSMessageID() Priority int getJMSPriority() Redelivered boolean getJMSRedlivered() Time Stamp long getJMSTimeStamp() Type string getJMSType() Time To Live long getTimeToLive() Optional Header Properties In addition, you can inspect any optional properties stored in the JMS header using JMSMessageHeadersType.getProperty() . The optional properties are returned as a List of org.apache.cxf.transports.jms.context.JMSPropertyType . Optional properties are stored as name/value pairs. Example Example 42.14, "Reading the JMS Header Properties" shows code for inspecting some of the JMS properties using the response context. Example 42.14. Reading the JMS Header Properties The code in Example 42.14, "Reading the JMS Header Properties" does the following: Prints the value of the message's correlation ID. Prints the value of the message's priority property. Prints the value of the message's redelivered property. Gets the list of the message's optional header properties. Gets an Iterator to traverse the list of properties. Iterates through the list of optional properties and prints their name and value. 42.4.3. Setting JMS Properties Abstract Using the request context in a consumer endpoint, you can set a number of the JMS message header properties and the consumer endpoint's timeout value. These properties are valid for a single invocation. You must reset them each time you invoke an operation on the service proxy. Note that you cannot set header properties in a service. JMS Header Properties Table 42.4, "Settable JMS Header Properties" lists the properties in the JMS header that can be set using the consumer endpoint's request context. Table 42.4. Settable JMS Header Properties Property Name Property Type Setter Method Correlation ID string setJMSCorralationID() Delivery Mode int setJMSDeliveryMode() Priority int setJMSPriority() Time To Live long setTimeToLive() To set these properties do the following: Create an org.apache.cxf.transports.jms.context.JMSMessageHeadersType object. Populate the values you want to set using the appropriate setter methods described in Table 42.4, "Settable JMS Header Properties" . Set the values to the request context by calling the request context's put() method using org.apache.cxf.transports.jms.JMSConstants.JMS_CLIENT_REQUEST_HEADERS as the first argument, and the new JMSMessageHeadersType object as the second argument. Optional JMS Header Properties You can also set optional properties to the JMS header. Optional JMS header properties are stored in the JMSMessageHeadersType object that is used to set the other JMS header properties. They are stored as a List object containing org.apache.cxf.transports.jms.context.JMSPropertyType objects. To add optional properties to the JMS header do the following: Create a JMSPropertyType object. Set the property's name field using setName() . Set the property's value field using setValue() . Add the property to the JMS message header using JMSMessageHeadersType.getProperty().add(JMSPropertyType) . Repeat the procedure until all of the properties have been added to the message header. Client Receive Timeout In addition to the JMS header properties, you can set the amount of time a consumer endpoint waits for a response before timing out. You set the value by calling the request context's put() method with org.apache.cxf.transports.jms.JMSConstants.JMS_CLIENT_RECEIVE_TIMEOUT as the first argument and a long representing the amount of time in milliseconds that you want the consumer to wait as the second argument. Example Example 42.15, "Setting JMS Properties using the Request Context" shows code for setting some of the JMS properties using the request context. Example 42.15. Setting JMS Properties using the Request Context The code in Example 42.15, "Setting JMS Properties using the Request Context" does the following: Gets the InvocationHandler for the proxy whose JMS properties you want to change. Checks to see if the InvocationHandler is a BindingProvider . Casts the returned InvocationHandler object into a BindingProvider object to retrieve the request context. Gets the request context. Creates a JMSMessageHeadersType object to hold the new message header values. Sets the Correlation ID. Sets the Expiration property to 60 minutes. Creates a new JMSPropertyType object. Sets the values for the optional property. Adds the optional property to the message header. Sets the JMS message header values into the request context. Sets the client receive timeout property to 1 second.

Commands:
import javax.xml.ws.*; import javax.xml.ws.handler.*; import javax.annotation.*; @WebServiceProvider public class WidgetServiceImpl { @Resource WebServiceContext wsc; @WebMethod public String getColor(String itemNum) { MessageContext context = wsc.getMessageContext(); } }
import javax.xml.ws.handler.MessageContext; import org.apache.cxf.message.Message; // MessageContext context retrieved in a previous example QName wsdl_operation = (QName)context.get(Message.WSDL_OPERATION);
import javax.xml.ws.handler.MessageContext; import org.apache.cxf.message.Message; // MessageContext context retrieved in a previous example context.put(Message.RESPONSE_CODE, new Integer(404));
// Proxy widgetProxy obtained previously BindingProvider bp = (BindingProvider)widgetProxy; Map<String, Object> requestContext = bp.getRequestContext();
// Invoke an operation. port.SomeOperation(); // Read response context property. java.util.Map<String, Object> responseContext = ((javax.xml.ws.BindingProvider)port).getResponseContext(); PropertyType propValue = ( PropertyType ) responseContext.get( ContextPropertyName );
// Set request context property. java.util.Map<String, Object> requestContext = ((javax.xml.ws.BindingProvider)port).getRequestContext(); requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "http://localhost:8080/widgets"); // Invoke an operation. port.SomeOperation();
import org.apache.cxf.transport.jms.JMSConstants; import org.apache.cxf.transports.jms.context.JMSMessageHeadersType; @WebService(serviceName = "HelloWorldService", portName = "HelloWorldPort", endpointInterface = "org.apache.cxf.hello_world_jms.HelloWorldPortType", targetNamespace = "http://cxf.apache.org/hello_world_jms") public class GreeterImplTwoWayJMS implements HelloWorldPortType { @Resource protected WebServiceContext wsContext; @WebMethod public String greetMe(String me) { MessageContext mc = wsContext.getMessageContext(); JMSMessageHeadersType headers = (JMSMessageHeadersType) mc.get(JMSConstants.JMS_SERVER_HEADERS); } }
import org.apache.cxf.transports.jms.context.*; // Proxy greeter initialized previously BindingProvider bp = (BindingProvider)greeter; Map<String, Object> responseContext = bp.getResponseContext(); JMSMessageHeadersType responseHdr = (JMSMessageHeadersType) responseContext.get(JMSConstants.JMS_CLIENT_RESPONSE_HEADERS); }
// JMSMessageHeadersType messageHdr retrieved previously System.out.println("Correlation ID: "+messageHdr.getJMSCorrelationID()); System.out.println("Message Priority: "+messageHdr.getJMSPriority()); System.out.println("Redelivered: "+messageHdr.getRedelivered()); JMSPropertyType prop = null; List<JMSPropertyType> optProps = messageHdr.getProperty(); Iterator<JMSPropertyType> iter = optProps.iterator(); while (iter.hasNext()) { prop = iter.next(); System.out.println("Property name: "+prop.getName()); System.out.println("Property value: "+prop.getValue()); }
import org.apache.cxf.transports.jms.context.*; // Proxy greeter initialized previously InvocationHandler handler = Proxy.getInvocationHandler(greeter); BindingProvider bp= null; if (handler instanceof BindingProvider) { bp = (BindingProvider)handler; Map<String, Object> requestContext = bp.getRequestContext(); JMSMessageHeadersType requestHdr = new JMSMessageHeadersType(); requestHdr.setJMSCorrelationID("WithBob"); requestHdr.setJMSExpiration(3600000L); JMSPropertyType prop = new JMSPropertyType; prop.setName("MyProperty"); prop.setValue("Bluebird"); requestHdr.getProperty().add(prop); requestContext.put(JMSConstants.CLIENT_REQUEST_HEADERS, requestHdr); requestContext.put(JMSConstants.CLIENT_RECEIVE_TIMEOUT, new Long(1000)); }