13.2. JMS URIs

Overview

When using SOAP/JMS, a JMS URI is used to specify the endpoint's target destination. The JMS URI can also be used to configure JMS connection by appending one or more options to the URI. These options are detailed in the IETF standard, URI Scheme for Java Message Service 1.0. They can be used to configure the JNDI system, the reply destination, the delivery mode to use, and other JMS properties.

Syntax

As shown in Example 13.4, “Syntax for JMS URI options”, you can append one or more options to the end of a JMS URI by separating them from the destination's address with a question mark(?). Multiple options are separated by an ampersand(&). Example 13.4, “Syntax for JMS URI options” shows the syntax for using multiple options in a JMS URI.

Example 13.4. Syntax for JMS URI options

jms:variant:jmsAddress?option1=value1&option2=value2&...optionN=valueN

JMS properties

Table 13.2, “JMS properties settable as URI options” shows the URI options that affect the JMS transport layer.

Table 13.2. JMS properties settable as URI options

PropertyDefaultDescription
conduitIdSelectorPrefix  [Optional] A string value that is prefixed to all correlation IDs that the conduit creates. The selector can use it to listen for replies.
deliveryMode PERSISTENT Specifies whether to use JMS PERSISTENT or NON_PERSISTENT message semantics. In the case of PERSISTENT delivery mode, the JMS broker stores messages in persistent storage before acknowledging them; whereas NON_PERSISTENT messages are kept in memory only.
durableSubscriptionClientID  [Optional] Specifies the client identifier for the connection. This property is used to associate a connection with a state that the provider maintains on behalf of the client. This enables subsequent subscribers with the same identity to resume the subscription in the state that the preceding subscriber left it.
durableSubscriptionName  [Optional] Specifies the name of the subscription.
messageType byte
Specifies the JMS message type used by CXF. Valid values are:
  • byte
  • text
  • binary
password  [Optional] Specifies the password for creating the connection. Appending this property to the URI is discouraged.
priority 4 Specifies the JMS message priority, which ranges from 0 (lowest) to 9 (highest).
receiveTimout 60000 Specifies the time, in milliseconds, the client will wait for a reply when request/reply exchanges are used.
reconnectOnException true
[Deprecated in CXF 3.0] Specifies whether the transport should reconnect when exceptions occur.
As of 3.0, the transport will always reconnect when an exception occurs.
replyToName  
[Optional] Specifies the reply destination for queue messages. The reply destination appears in the JMSReplyTo header. Setting this property is recommended for applications that have request-reply semantics because the JMS provider will assign a temporary reply queue if one is not specified.
The value of this property is interpreted according to the variant specified in the JMS URI:
  • jndi variant—the name of the destination queue resolved by JNDI
  • queue variant—the name of the destination queue resolved using JMS
sessionTransacted false
Specifies the transaction type. Valid values are:
  • true—resource local transactions
  • false—JTA transactions
timeToLive 0 Specifies the time, in milliseconds, after which the JMS provider will discard the message. A value of 0 indicates an infinite lifetime.
topicReplyToName  
[Optional] Specifies the reply destination for topic messages. The value of this property is interpreted according to the variant specified in the JMS URI:
  • jndi-topic—the name of the destination topic resolved by JNDI
  • topic—the name of the destination topic resolved by JMS
useConduitIdSelector true
Specifies whether the conduit's UUID will be used as the prefix for all correlation IDs.
As all conduits are assigned a unique UUID, setting this property to true enables multiple endpoints to share a JMS queue or topic.
username  [Optional] Specifies the username to use to create the connection.

JNDI properties

Table 13.3, “JNDI properties settable as URI options” shows the URI options that can be used to configure JNDI for this endpoint.

Table 13.3. JNDI properties settable as URI options

PropertyDescription
jndiConnectionFactoryName Specifies the JNDI name of the JMS connection factory.
jndiInitialContextFactory Specifies the fully qualified Java class name of the JNDI provider (which must be of javax.jms.InitialContextFactory type). Equivalent to setting the java.naming.factory.initial Java system property.
jndiTransactionManagerName Specifies the name of the JTA transaction manager that will be searched for in Spring, Blueprint, or JNDI. If a transaction manager is found, JTA transactions will be enabled. See the sessionTransacted JMS property.
jndiURL Specifies the URL that initializes the JNDI provider. Equivalent to setting the java.naming.provider.url Java system property.

Additional JNDI properties

The properties, java.naming.factory.initial and java.naming.provider.url, are standard properties, which are required to initialize any JNDI provider. Sometimes, however, a JNDI provider might support custom properties in addition to the standard ones. In this case, you can set an arbitrary JNDI property by setting a URI option of the form jndi-PropertyName.
For example, if you were using SUN's LDAP implementation of JNDI, you could set the JNDI property, java.naming.factory.control, in a JMS URI as shown in Example 13.5, “Setting a JNDI property in a JMS URI”.

Example 13.5. Setting a JNDI property in a JMS URI

jms:queue:FOO.BAR?jndi-java.naming.factory.control=com.sun.jndi.ldap.ResponseControlFactory

Example

If the JMS provider is not already configured, it is possible to provide the requisite JNDI configuration details in the URI using options (see Table 13.3, “JNDI properties settable as URI options”). For example, to configure an endpoint to use the Apache ActiveMQ JMS provider and connect to the queue called test.cxf.jmstransport.queue, use the URI shown in Example 13.6, “JMS URI that configures a JNDI connection”.

Example 13.6. JMS URI that configures a JNDI connection

jms:jndi:dynamicQueues/test.cxf.jmstransport.queue
?jndiInitialContextFactory=org.apache.activemq.jndi.ActiveMQInitialContextFactory
&jndiConnectionFactoryName=ConnectionFactory
&jndiURL=tcp://localhost:61616

Publishing a service

The JAX-WS standard publish() method cannot be used to publish a SOAP/JMS service. Instead, you must use the Apache CXF's JaxWsServerFactoryBean class as shown in Example 13.7, “Publishing a SOAP/JMS service”.

Example 13.7. Publishing a SOAP/JMS service

1String address = "jms:jndi:dynamicQueues/test.cxf.jmstransport.queue3"
    + "?jndiInitialContextFactory"
    + "=org.apache.activemq.jndi.ActiveMQInitialContextFactory"
    + "&jndiConnectionFactoryName=ConnectionFactory"
    + "&jndiURL=tcp://localhost:61500";
Hello implementor = new HelloImpl();
2JaxWsServerFactoryBean svrFactory = new JaxWsServerFactoryBean();
svrFactory.setServiceClass(Hello.class);
3svrFactory.setAddress(address);
4svrFactory.setTransportId(JMSSpecConstants.SOAP_JMS_SPECIFICIATION_TRANSPORTID);
svrFactory.setServiceBean(implementor);
svrFactory.create();
The code in Example 13.7, “Publishing a SOAP/JMS service” does the following:
1
Creates the JMS URI representing t he endpoint's address.
2
Instantiates a JaxWsServerFactoryBean to publish the service.
3
Sets the address field of the factory bean with the JMS URI of the service.
4
Specifies that the service created by the factory will use the SOAP/JMS transport.

Consuming a service

The standard JAX-WS APIs cannot be used to consume a SOAP/JMS service. Instead, you must use the Apache CXF's JaxWsProxyFactoryBean class as shown in Example 13.8, “Consuming a SOAP/JMS service”.

Example 13.8. Consuming a SOAP/JMS service

// Java
public void invoke() throws Exception {
1    String address = "jms:jndi:dynamicQueues/test.cxf.jmstransport.queue3"
        + "?jndiInitialContextFactory"
        + "=org.apache.activemq.jndi.ActiveMQInitialContextFactory"
        + "&jndiConnectionFactoryName=ConnectionFactory&jndiURL=tcp://localhost:61500";
2    JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
3    factory.setAddress(address);
4    factory.setTransportId(JMSSpecConstants.SOAP_JMS_SPECIFICIATION_TRANSPORTID);
    factory.setServiceClass(Hello.class);
    Hello client = (Hello)factory.create();
    String reply = client.sayHi(" HI");
    System.out.println(reply);
}
The code in Example 13.8, “Consuming a SOAP/JMS service” does the following:
1
Creates the JMS URI representing t he endpoint's address.
2
Instantiates a JaxWsProxyFactoryBean to create the proxy.
3
Sets the address field of the factory bean with the JMS URI of the service.
4
Specifies that the proxy created by the factory will use the SOAP/JMS transport.