Chapter 7. Using JMS connection factories


This chapter describes how to use JMS connection factories in OSGi. Fundamentally, you do it by using:

org.osgi.framework.BundleContext.registerService(javax.jms.ConnectionFactory.class,
                                                 connectionFactoryObject,
                                                 properties);
org.osgi.framework.BundleContext.registerService(javax.jms.XAConnectionFactory.class,
                                                 xaConnectionFactoryObject,
                                                 properties);

There are two different methods to register such services:

  • Publishing connection factories by using the jms:create Karaf console command. This is the configuration method.
  • Publishing connection factories by using methods such as Blueprint, OSGi Declarative Services (SCR) or just a BundleContext.registerService() API call. This method requires a dedicated OSGi bundle that contains the code and/or metadata. This is the deployment method.

Details are in the following topics:

7.1. About the OSGi JMS service

The OSGi way of handling JDBC data sources is related to two interfaces:

  • standard org.osgi.service.jdbc.DataSourceFactory
  • proprietary org.ops4j.pax.jdbc.pool.common.PooledDataSourceFactory

For JMS, consider these analogies:

  • proprietary org.ops4j.pax.jms.service.ConnectionFactoryFactory with the same purpose as standard OSGi JDBC org.osgi.service.jdbc.DataSourceFactory
  • proprietary org.ops4j.pax.jms.service.PooledConnectionFactoryFactory with the same purpose as proprietary pax-jdbc org.ops4j.pax.jdbc.pool.common.PooledDataSourceFactory

For the dedicated, broker-specific, org.ops4j.pax.jms.service.ConnectionFactoryFactory implementations, there are bundles such as:

  • mvn:org.ops4j.pax.jms/pax-jms-artemis/1.0.0
  • mvn:org.ops4j.pax.jms/pax-jms-ibmmq/1.0.0
  • mvn:org.ops4j.pax.jms/pax-jms-activemq/1.0.0

These bundles register broker-specific org.ops4j.pax.jms.service.ConnectionFactoryFactory services that can return JMS factories such as javax.jms.ConnectionFactory and javax.jms.XAConnectionFactory. For example:

karaf@root()> feature:install pax-jms-artemis

karaf@root()> bundle:services -p org.ops4j.pax.jms.pax-jms-config

OPS4J Pax JMS Config (248) provides:
------------------------------------
objectClass = [org.osgi.service.cm.ManagedServiceFactory]
service.bundleid = 248
service.id = 328
service.pid = org.ops4j.connectionfactory
service.scope = singleton

karaf@root()> bundle:services -p org.ops4j.pax.jms.pax-jms-artemis

OPS4J Pax JMS Artemis Support (247) provides:
---------------------------------------------
objectClass = [org.ops4j.pax.jms.service.ConnectionFactoryFactory]
service.bundleid = 247
service.id = 327
service.scope = singleton
type = artemis

7.2. About the PAX-JMS configuration service

The mvn:org.ops4j.pax.jms/pax-jms-config/1.0.0 bundle provides a Managed Service Factory that does three things:

  • Tracks org.ops4j.pax.jms.service.ConnectionFactoryFactory OSGi services to invoke its methods:

    public ConnectionFactory createConnectionFactory(Map<String, Object> properties);
    
    public XAConnectionFactory createXAConnectionFactory(Map<String, Object> properties);
  • Tracks org.ops4j.connectionfactory factory PIDs to collect properties that are required by the above methods. If you create a factory configuration by using any method available for Configuration Admin service, for example, by creating a ${karaf.etc}/org.ops4j.connectionfactory-artemis.cfg file, you can perform the final step to expose a broker-specific connection factory.
  • Tracks javax.jms.ConnectionFactory and javax.jms.XAConnectionFactory services to wrap them inside pooling JMS connection factories.

Details are in the following topics:

7.2.1. Creating a connection factory for AMQ 7.1

Following is the detailed, canonical, step-by-step guide for creating a connection factor for an Artemis broker.

  1. Install the Artemis driver by using the pax-jms-artemis feature and the pax-jms-config feature:

    karaf@root()> feature:install pax-jms-artemis
    
    karaf@root()> bundle:services -p org.ops4j.pax.jms.pax-jms-config
    
    OPS4J Pax JMS Config (248) provides:
    ------------------------------------
    objectClass = [org.osgi.service.cm.ManagedServiceFactory]
    service.bundleid = 248
    service.id = 328
    service.pid = org.ops4j.connectionfactory
    service.scope = singleton
    
    karaf@root()> bundle:services -p org.ops4j.pax.jms.pax-jms-artemis
    
    OPS4J Pax JMS Artemis Support (247) provides:
    ---------------------------------------------
    objectClass = [org.ops4j.pax.jms.service.ConnectionFactoryFactory]
    service.bundleid = 247
    service.id = 327
    service.scope = singleton
    type = artemis
  2. Create a factory configuration:

    karaf@root()> config:edit --factory --alias artemis org.ops4j.connectionfactory
    karaf@root()> config:property-set type artemis
    karaf@root()> config:property-set osgi.jndi.service.name jms/artemis # "name" property may be used too
    karaf@root()> config:property-set connectionFactoryType ConnectionFactory # or XAConnectionFactory
    karaf@root()> config:property-set jms.url tcp://localhost:61616
    karaf@root()> config:property-set jms.user admin
    karaf@root()> config:property-set jms.password admin
    karaf@root()> config:property-set jms.consumerMaxRate 1234
    karaf@root()> config:update
    
    karaf@root()> config:list '(service.factoryPid=org.ops4j.connectionfactory)'
    ----------------------------------------------------------------
    Pid:            org.ops4j.connectionfactory.965d4eac-f5a7-4f65-ba1a-15caa4c72703
    FactoryPid:     org.ops4j.connectionfactory
    BundleLocation: ?
    Properties:
       connectionFactoryType = ConnectionFactory
       felix.fileinstall.filename = file:${karar.etc}/org.ops4j.connectionfactory-artemis.cfg
       jms.consumerMaxRate = 1234
       jms.password = admin
       jms.url = tcp://localhost:61616
       jms.user = admin
       osgi.jndi.service.name = jms/artemis
       service.factoryPid = org.ops4j.connectionfactory
       service.pid = org.ops4j.connectionfactory.965d4eac-f5a7-4f65-ba1a-15caa4c72703
       type = artemis
  3. Check if pax-jms-config processed the configuration into the javax.jms.ConnectionFactory service:

    karaf@root()> service:list javax.jms.ConnectionFactory
    [javax.jms.ConnectionFactory]
    -----------------------------
     connectionFactoryType = ConnectionFactory
     felix.fileinstall.filename = file:${karaf.etc}/org.ops4j.connectionfactory-artemis.cfg
     jms.consumerMaxRate = 1234
     jms.password = admin
     jms.url = tcp://localhost:61616
     jms.user = admin
     osgi.jndi.service.name = jms/artemis
     pax.jms.managed = true
     service.bundleid = 248
     service.factoryPid = org.ops4j.connectionfactory
     service.id = 342
     service.pid = org.ops4j.connectionfactory.965d4eac-f5a7-4f65-ba1a-15caa4c72703
     service.scope = singleton
     type = artemis
    Provided by :
     OPS4J Pax JMS Config (248)
    Note

    If you specify additional Artemis configuration, specifically protocol=amqp, the QPID JMS library would be used instead of the Artemis JMS client. The amqp:// protocol has to be used then for jms.url property.

  4. Test the connection.

You now have a broker-specific (no pooling yet) connection factory that you can inject where needed. For example, you can use Karaf commands from the jms feature:

karaf@root()> feature:install -v jms
Adding features: jms/[4.2.0.fuse-000237-redhat-1,4.2.0.fuse-000237-redhat-1]
...
karaf@root()> jms:connectionfactories
JMS Connection Factory
──────────────────────
jms/artemis

karaf@root()> jms:info -u admin -p admin jms/artemis
Property │ Value
─────────┼──────────────────────────
product  │ ActiveMQ
version  │ 2.4.0.amq-711002-redhat-1

karaf@root()> jms:send -u admin -p admin jms/artemis DEV.QUEUE.1 "Hello Artemis"

karaf@root()> jms:browse -u admin -p admin jms/artemis DEV.QUEUE.1
Message ID                              │ Content       │ Charset │ Type │ Correlation ID │ Delivery Mode │ Destination                │ Expiration │ Priority │ Redelivered │ ReplyTo │ Timestamp
────────────────────────────────────────┼───────────────┼─────────┼──────┼────────────────┼───────────────┼────────────────────────────┼────────────┼──────────┼─────────────┼─────────┼──────────────────────────────
ID:2b6ea56d-574d-11e8-971a-7ee9ecc029d4 │ Hello Artemis │ UTF-8   │      │                │ Persistent    │ ActiveMQQueue[DEV.QUEUE.1] │ Never      │ 4        │ false       │         │ Mon May 14 10:02:38 CEST 2018

The following listing shows what happens when you switch the protocol:

karaf@root()> config:list '(service.factoryPid=org.ops4j.connectionfactory)'
----------------------------------------------------------------
Pid:            org.ops4j.connectionfactory.965d4eac-f5a7-4f65-ba1a-15caa4c72703
FactoryPid:     org.ops4j.connectionfactory
BundleLocation: ?
Properties:
   connectionFactoryType = ConnectionFactory
   felix.fileinstall.filename = file:${karaf.etc}/org.ops4j.connectionfactory-artemis.cfg
   jms.consumerMaxRate = 1234
   jms.password = fuse
   jms.url = tcp://localhost:61616
   jms.user = fuse
   osgi.jndi.service.name = jms/artemis
   service.factoryPid = org.ops4j.connectionfactory
   service.pid = org.ops4j.connectionfactory.965d4eac-f5a7-4f65-ba1a-15caa4c72703
   type = artemis

karaf@root()> config:edit org.ops4j.connectionfactory.312eb09a-d686-4229-b7e1-2ea38a77bb0f
karaf@root()> config:property-set protocol amqp
karaf@root()> config:property-delete user
karaf@root()> config:property-set username admin # mind the difference between artemis-jms-client and qpid-jms-client
karaf@root()> config:property-set jms.url amqp://localhost:61616
karaf@root()> config:update

karaf@root()> jms:info -u admin -p admin jms/artemis
Property │ Value
─────────┼────────────────
product  │ QpidJMS
version  │ 0.30.0.redhat-1

karaf@root()> jms:browse -u admin -p admin jms/artemis DEV.QUEUE.1
Message ID │ Content       │ Charset │ Type │ Correlation ID │ Delivery Mode │ Destination │ Expiration │ Priority │ Redelivered │ ReplyTo │ Timestamp
───────────┼───────────────┼─────────┼──────┼────────────────┼───────────────┼─────────────┼────────────┼──────────┼─────────────┼─────────┼──────────────────────────────
           │ Hello Artemis │ UTF-8   │      │                │ Persistent    │ DEV.QUEUE.1 │ Never      │ 4        │ false       │         │ Mon May 14 10:02:38 CEST 2018

7.2.2. Creating a connection factory for IBM MQ 9

This section shows how to connect to IBM MQ 9. Even if pax-jms-ibmmq installs the relevant pax-jms bundles, the IBM MQ driver is not installed due to licensing reasons.

Following is the list of libraries that should be used with IBM MQ 9. But first, to obtain everything you need:

  1. Go to https://developer.ibm.com/messaging/mq-downloads/
  2. Log in.
  3. Click IBM MQ 9.0 Client.
  4. Download the 9.0.5.0-IBM-MQC-Redist-Java package. This package does not contain everything that you need.
  5. Click in the Product selector box but do not change anything. Accept the existing WebSphere MQ specification.

    Although you do not change the product name, there is a change in the lower box from Upgrades to version to Applies to version.

  6. Select 9.0.4, Platform = all and click Submit.
  7. Find and download the official client library package: 9.0.5.0-IBM-MQ-Install-Java-All.jar.

To be precise, here are the checksums:

$ sha1sum 9.0.5.0-IBM*
4e6548956756c87c579d17a739416c59b736c145  9.0.5.0-IBM-MQC-Redist-Java.zip
c38a55118059221677240d507ae6c9b3b6923439  9.0.5.0-IBM-MQ-Install-Java-All.jar

Download the developer version of IBM MQ 9 (mqadv_dev905_linux_x86-64.tar.gz) from https://developer.ibm.com/messaging/mq-downloads After downloading the developer version, you can find these additional library packages:

  • MQSeriesJava-9.0.5-0.x86_64.rpm
  • MQSeriesJava-9.0.5-0.x86_64.cpio.lzma
  • MQSeriesJava-9.0.5-0.x86_64.cpio

After unpacking the cpio package, you can see a more complete set of libraries.

Even if it seems that the 9.0.5.0-IBM-MQ-Install-Java-All package should be used there are some OSGi issues. There are three subdirectories in this package:

  • JavaEE contains a resource adapter archive (wmq.jmsra.rar).
  • JavaSE contains the com.ibm.mq.allclient.jar library and dependencies.
  • OSGi contains respective com.ibm.mq.osgi.allclient_9.0.5.0.jar and dependencies.

MQSeriesJava-9.0.5-0.x86_64.cpio contains:

  • com.ibm.mq.osgi.allclientprereqs_9.0.5.0.jar - should not be used
  • com.ibm.mq.osgi.allclient_9.0.5.0.jar - depends on the above, so should not be used
  • com.ibm.mq.osgi.java_9.0.5.0.jar
  • com.ibm.msg.client.osgi.commonservices.j2se_9.0.5.0.jar
  • com.ibm.msg.client.osgi.jms_9.0.5.0.jar - should not be used
  • com.ibm.msg.client.osgi.jms.prereq_9.0.5.0.jar
  • com.ibm.msg.client.osgi.nls_9.0.5.0.jar
  • com.ibm.msg.client.osgi.wmq_9.0.5.0.jar
  • com.ibm.msg.client.osgi.wmq.nls_9.0.5.0.jar
  • com.ibm.msg.client.osgi.wmq.prereq_9.0.5.0.jar

The OSGi directory of the 9.0.5.0-IBM-MQ-Install-Java-All.jar package contains only two bundles:

  • com.ibm.mq.osgi.allclient_9.0.5.0.jar - actual driver
  • com.ibm.mq.osgi.allclientprereqs_9.0.5.0.jar - prerequisites

While the prerequisites JAR contains the required fscontext.jar and providerutil.jar libraries, it also contains:

  • bcprov-jdk15on-157.jar and bcpkix-jdk15on-157.jar. Fuse ships those (in newer version) in $FUSE_HOME/lib/ext.
  • jms.jar, which is exactly the same jar that is available by using mvn:javax.jms/javax.jms-api/2.0.

You cannot rely on the embedded jms.jar. If you do, you get ClassCastException when working with this driver. Fuse has its own version of the JMS API from mvn:javax.jms/javax.jms-api/2.0.1.

Unfortunately, the com.ibm.mq.osgi.allclient_9.0.5.0.jar bundle contains this manifest header:

Require-Bundle =
	com.ibm.mq.osgi.allclientprereqs;visibility:=reexport

Consequently, you cannot use the com.ibm.mq.osgi.allclient_9.0.5.0.jar bundle unless you install an empty bundle whose symbolic name is com.ibm.mq.osgi.allclientprereqs. To work around this:

  • Unpack fscontext.jar and providerutil.jar from com.ibm.mq.osgi.allclientprereqs_9.0.5.0.jar, or copy them from 9.0.5.0-IBM-MQ-Install-Java-All/JavaSE.
  • Copy these two libraries to $FUSE_HOME/lib/ext. $FUSE_HOME/etc/config.properties already has the correct configuration of the packages from these libraries in the org.osgi.framework.system.packages.extra property.
  • Install 6 bundles from the MQSeriesJava-9.0.5-0.x86_64.cpio package:

    karaf@root()> install 'file:///data/downloads/ibm.com/IBM%20MQ/MQSeriesJava-9.0.5-0.x86_64/java/lib/OSGi/com.ibm.msg.client.osgi.commonservices.j2se_9.0.5.0.jar'
    Bundle ID: 223
    karaf@root()> install 'file:///data/downloads/ibm.com/IBM%20MQ/MQSeriesJava-9.0.5-0.x86_64/java/lib/OSGi/com.ibm.msg.client.osgi.jms_9.0.5.0.jar'
    Bundle ID: 224
    karaf@root()> install 'file:///data/downloads/ibm.com/IBM%20MQ/MQSeriesJava-9.0.5-0.x86_64/java/lib/OSGi/com.ibm.msg.client.osgi.nls_9.0.5.0.jar'
    Bundle ID: 225
    karaf@root()> install 'file:///data/downloads/ibm.com/IBM%20MQ/MQSeriesJava-9.0.5-0.x86_64/java/lib/OSGi/com.ibm.msg.client.osgi.wmq.nls_9.0.5.0.jar'
    Bundle ID: 226
    karaf@root()> install 'file:///data/downloads/ibm.com/IBM%20MQ/MQSeriesJava-9.0.5-0.x86_64/java/lib/OSGi/com.ibm.msg.client.osgi.wmq.prereq_9.0.5.0.jar'
    Bundle ID: 227
    karaf@root()> install 'file:///data/downloads/ibm.com/IBM%20MQ/MQSeriesJava-9.0.5-0.x86_64/java/lib/OSGi/com.ibm.msg.client.osgi.wmq_9.0.5.0.jar'
    Bundle ID: 228
    
    karaf@root()> resolve
    
    karaf@root()> feature:install jms
    
    karaf@root()> start 223 224 225 227 228 # start non-fragment bundles:
    
    karaf@root()> la -l|grep ibm.msg
    223 │ Active   │  80 │ 9.0.5.0                     │ file:///.../com.ibm.msg.client.osgi.commonservices.j2se_9.0.5.0.jar
    224 │ Active   │  80 │ 9.0.5.0                     │ file:///.../com.ibm.msg.client.osgi.jms_9.0.5.0.jar
    225 │ Active   │  80 │ 9.0.5.0                     │ file:///.../com.ibm.msg.client.osgi.nls_9.0.5.0.jar
    226 │ Resolved │  80 │ 9.0.5.0                     │ file:///.../com.ibm.msg.client.osgi.wmq.nls_9.0.5.0.jar
    227 │ Active   │  80 │ 9.0.5.0                     │ file:///.../com.ibm.msg.client.osgi.wmq.prereq_9.0.5.0.jar
    228 │ Active   │  80 │ 9.0.5.0                     │ file:///.../com.ibm.msg.client.osgi.wmq_9.0.5.0.jar

    These bundles could also be put into a custom feature and installed by using the feature:install command.

You are now ready to create the connection factory:

  1. Install pax-jms-ibmmq:

    karaf@root()> feature:install pax-jms-ibmmq
    
    karaf@root()> bundle:services -p org.ops4j.pax.jms.pax-jms-ibmmq
    
    OPS4J Pax JMS IBM MQ Support (239) provides:
    --------------------------------------------
    objectClass = [org.ops4j.pax.jms.service.ConnectionFactoryFactory]
    service.bundleid = 239
    service.id = 346
    service.scope = singleton
    type = ibmmq
  2. Create factory configuration:

    karaf@root()> config:edit --factory --alias ibmmq org.ops4j.connectionfactory
    karaf@root()> config:property-set type ibmmq
    karaf@root()> config:property-set osgi.jndi.service.name jms/mq9 # "name" property may be used too
    karaf@root()> config:property-set connectionFactoryType ConnectionFactory # or XAConnectionFactory
    karaf@root()> config:property-set jms.queueManager FUSEQM
    karaf@root()> config:property-set jms.hostName localhost
    karaf@root()> config:property-set jms.port 1414
    karaf@root()> config:property-set jms.transportType 1 # com.ibm.msg.client.wmq.WMQConstants.WMQ_CM_CLIENT
    karaf@root()> config:property-set jms.channel DEV.APP.SVRCONN
    karaf@root()> config:property-set jms.CCSID 1208 # com.ibm.msg.client.jms.JmsConstants.CCSID_UTF8
    karaf@root()> config:update
    
    karaf@root()> config:list '(service.factoryPid=org.ops4j.connectionfactory)'
    ----------------------------------------------------------------
    Pid:            org.ops4j.connectionfactory.eee4a757-a95d-46b8-b8b6-19aa3977d863
    FactoryPid:     org.ops4j.connectionfactory
    BundleLocation: ?
    Properties:
       connectionFactoryType = ConnectionFactory
       felix.fileinstall.filename = file:${karaf.etc}/org.ops4j.connectionfactory-ibmmq.cfg
       jms.CCSID = 1208
       jms.channel = DEV.APP.SVRCONN
       jms.hostName = localhost
       jms.port = 1414
       jms.queueManager = FUSEQM
       jms.transportType = 1
       osgi.jndi.service.name = jms/mq9
       service.factoryPid = org.ops4j.connectionfactory
       service.pid = org.ops4j.connectionfactory.eee4a757-a95d-46b8-b8b6-19aa3977d863
       type = ibmmq
  3. Check if pax-jms-config processed the configuration into javax.jms.ConnectionFactory service:

    karaf@root()> service:list javax.jms.ConnectionFactory
    [javax.jms.ConnectionFactory]
    -----------------------------
     connectionFactoryType = ConnectionFactory
     felix.fileinstall.filename = file:/data/servers/fuse-karaf-7.0.0.fuse-000191-redhat-1/etc/org.ops4j.connectionfactory-ibmmq.cfg
     jms.CCSID = 1208
     jms.channel = DEV.APP.SVRCONN
     jms.hostName = localhost
     jms.port = 1414
     jms.queueManager = FUSEQM
     jms.transportType = 1
     osgi.jndi.service.name = jms/mq9
     pax.jms.managed = true
     service.bundleid = 237
     service.factoryPid = org.ops4j.connectionfactory
     service.id = 347
     service.pid = org.ops4j.connectionfactory.eee4a757-a95d-46b8-b8b6-19aa3977d863
     service.scope = singleton
     type = ibmmq
    Provided by :
     OPS4J Pax JMS Config (237)
  4. Test the connection:

    karaf@root()> feature:install -v jms
    Adding features: jms/[4.2.0.fuse-000237-redhat-1,4.2.0.fuse-000237-redhat-1]
    ...
    karaf@root()> jms:connectionfactories
    JMS Connection Factory
    ──────────────────────
    jms/mq9
    
    karaf@root()> jms:info -u app -p fuse jms/mq9
    Property │ Value
    ─────────┼────────────────────
    product  │ IBM MQ JMS Provider
    version  │ 8.0.0.0
    
    karaf@root()> jms:send -u app -p fuse jms/mq9 DEV.QUEUE.1 "Hello IBM MQ 9"
    
    karaf@root()> jms:browse -u app -p fuse jms/mq9 DEV.QUEUE.1
    Message ID                                          │ Content                     │ Charset │ Type │ Correlation ID │ Delivery Mode │ Destination          │ Expiration │ Priority │ Redelivered │ ReplyTo │ Timestamp
    ────────────────────────────────────────────────────┼─────────────────────────────┼─────────┼──────┼────────────────┼───────────────┼──────────────────────┼────────────┼──────────┼─────────────┼─────────┼──────────────────────────────
    ID:414d512046555345514d202020202020c940f95a038b3220 │ Hello IBM MQ 9              │ UTF-8   │      │                │ Persistent    │ queue:///DEV.QUEUE.1 │ Never      │ 4        │ false       │         │ Mon May 14 10:17:01 CEST 2018

You can check if the message was sent also from IBM MQ Explorer or from the web console.

7.2.3. Summary of handled properties

Properties from the Configuration Admin factory PID are passed to the relevant org.ops4j.pax.jms.service.ConnectionFactoryFactory implementation.

  • ActiveMQ

    org.ops4j.pax.jms.activemq.ActiveMQConnectionFactoryFactory (JMS 1.1 only)

    Properties that are passed to the org.apache.activemq.ActiveMQConnectionFactory.buildFromMap() method

  • Artemis

    org.ops4j.pax.jms.artemis.ArtemisConnectionFactoryFactory

    If protocol=amqp, properties are passed to the org.apache.qpid.jms.util.PropertyUtil.setProperties() method to configure the org.apache.qpid.jms.JmsConnectionFactory instance.

    Otherwise, org.apache.activemq.artemis.utils.uri.BeanSupport.setData() is called for the org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory instance.

  • IBM MQ

    org.ops4j.pax.jms.ibmmq.MQConnectionFactoryFactory

    Bean properties of com.ibm.mq.jms.MQConnectionFactory or com.ibm.mq.jms.MQXAConnectionFactory are handled.

7.3. Using JMS console commands

Apache Karaf provides the jms feature, which includes shell commands in the jms:* scope. You already saw some examples of using these commands to check the manually configured connection factories. There are also commands that hide the need to create Configuration Admin configurations.

Starting with a fresh instance of Fuse, you can register a broker-specific connection factory. The following listing shows install of the jms feature from Karaf and installation of pax-jms-artemis from pax-jms:

karaf@root()> feature:install jms pax-jms-artemis

karaf@root()> jms:connectionfactories
JMS Connection Factory
──────────────────────
karaf@root()> service:list javax.jms.ConnectionFactory # should be empty

karaf@root()> service:list org.ops4j.pax.jms.service.ConnectionFactoryFactory
[org.ops4j.pax.jms.service.ConnectionFactoryFactory]
----------------------------------------------------
 service.bundleid = 250
 service.id = 326
 service.scope = singleton
 type = artemis
Provided by :
 OPS4J Pax JMS Artemis Support (250)

The following listing shows how to create and check an Artemis connection factory:

karaf@root()> jms:create -t artemis -u admin -p admin --url tcp://localhost:61616 artemis

karaf@root()> jms:connectionfactories
JMS Connection Factory
──────────────────────
jms/artemis

karaf@root()> jms:info -u admin -p admin jms/artemis
Property │ Value
─────────┼──────────────────────────
product  │ ActiveMQ
version  │ 2.4.0.amq-711002-redhat-1

karaf@root()> jms:send -u admin -p admin jms/artemis DEV.QUEUE.1 "Hello Artemis"

karaf@root()> jms:browse -u admin -p admin jms/artemis DEV.QUEUE.1
Message ID                              │ Content       │ Charset │ Type │ Correlation ID │ Delivery Mode │ Destination                │ Expiration │ Priority │ Redelivered │ ReplyTo │ Timestamp
────────────────────────────────────────┼───────────────┼─────────┼──────┼────────────────┼───────────────┼────────────────────────────┼────────────┼──────────┼─────────────┼─────────┼──────────────────────────────
ID:7a944470-574f-11e8-918e-7ee9ecc029d4 │ Hello Artemis │ UTF-8   │      │                │ Persistent    │ ActiveMQQueue[DEV.QUEUE.1] │ Never      │ 4        │ false       │         │ Mon May 14 10:19:10 CEST 2018

karaf@root()> config:list '(service.factoryPid=org.ops4j.connectionfactory)'
----------------------------------------------------------------
Pid:            org.ops4j.connectionfactory.9184db6f-cb5f-4fd7-b5d7-a217090473ad
FactoryPid:     org.ops4j.connectionfactory
BundleLocation: mvn:org.ops4j.pax.jms/pax-jms-config/1.0.0
Properties:
   name = artemis
   osgi.jndi.service.name = jms/artemis
   password = admin
   service.factoryPid = org.ops4j.connectionfactory
   service.pid = org.ops4j.connectionfactory.9184db6f-cb5f-4fd7-b5d7-a217090473ad
   type = artemis
   url = tcp://localhost:61616
   user = admin

As you can see, the org.ops4j.connectionfactory factory PID is created for you. However it is not automatically stored in ${karaf.etc}, which is possible with config:update. It is not possible to specify other properties, but you can add them later.

7.4. Using encrypted configuration values

As with the pax-jdbc-config bundle, you can use Jasypt to encrypt properties.

If there is any org.jasypt.encryption.StringEncryptor service that is registered in OSGi with any alias service property, you can reference it in a connection factory factory PID and use encrypted passwords. Following is an example:

felix.fileinstall.filename = */etc/org.ops4j.connectionfactory-artemis.cfg
name = artemis
type = artemis
decryptor = my-jasypt-decryptor
url = tcp://localhost:61616
user = fuse
password = ENC(<encrypted-password>)

The service filter used to find the decryptor service is (&(objectClass=org.jasypt.encryption.StringEncryptor)(alias=<alias>)), where <alias> is the value of the decryptor property from the connection factory configuration factory PID.

7.5. Using JMS connection pools

This section discusses JMS connection/session pooling options. There are fewer choices than there are for JDBC. The information is organized into the following topics:

Important

To use XA recovery, you should use the pax-jms-pool-transx or pax-jms-pool-narayana connection pool module.

7.5.1. Introduction to using JMS connection pools

So far, you have registered a broker-specific connection factory. Because a connection factory itself is a factory for connection factories, the org.ops4j.pax.jms.service.ConnectionFactoryFactory service may be treated as a meta factory. It should be able to produce two kinds of connection factories:

  • javax.jms.ConnectionFactory
  • javax.jms.XAConnectionFactory

The pax-jms-pool-* bundles work smoothly with the org.ops4j.pax.jms.service.ConnectionFactoryFactory service. These bundles provide implementations of org.ops4j.pax.jms.service.PooledConnectionFactoryFactory that can be used to create pooled connection factories by using a set of properties and the original org.ops4j.pax.jms.service.ConnectionFactoryFactory in a kind of wrapper way. For example:

public interface PooledConnectionFactoryFactory {

    ConnectionFactory create(ConnectionFactoryFactory cff, Map<String, Object> props);

}

The following table shows which bundles register pooled connection factory factories. In the table, o.o.p.j.p represents org.ops4j.pax.jms.pool.

BundlePooledConnectionFactoryFactoryPool Key

pax-jms-pool-pooledjms

o.o.p.j.p.pooledjms.PooledJms(XA)PooledConnectionFactoryFactory

pooledjms

pax-jms-pool-narayana

o.o.p.j.p.narayana.PooledJms(XA)PooledConnectionFactoryFactory

narayana

pax-jms-pool-transx

o.o.p.j.p.transx.Transx(XA)PooledConnectionFactoryFactory

transx

Note

The pax-jms-pool-narayana factory is called PooledJms(XA)PooledConnectionFactoryFactory because it is based on the pooled-jms library. It adds integration with the Narayana transaction manager for XA recovery.

The above bundles install only connection factory factories. The bundles to not install the connection factories themselves. Consequently, something is needed that calls the javax.jms.ConnectionFactory org.ops4j.pax.jms.service.PooledConnectionFactoryFactory.create() method.

7.5.2. Using the pax-jms-pool-pooledjms connection pool module

An understanding of how to use the pax-jms-pool-pooledjms bundle helps you use not only the pax-jms-pool-pooledjms bundle, but also the pax-jms-pool-narayna bundle, which does almost everything as pax-jms-pool-pooledjms.

The pax-jms-config bundle tracks the following:

  • org.ops4j.pax.jms.service.ConnectionFactoryFactory services
  • org.ops4j.connectionfactory factory PIDs
  • Instances of org.ops4j.pax.jms.service.PooledConnectionFactoryFactory that are registered by one of pax-jms-pool-* bundles.

If a factory configuration contains a pool property, the ultimate connection factory registered by the pax-jms-config bundle is the broker-specific connection factory. If pool=pooledjms then the connection factory is wrapped inside one of the following:

  • org.messaginghub.pooled.jms.JmsPoolConnectionFactory (xa=false)
  • org.messaginghub.pooled.jms.JmsPoolXAConnectionFactory (xa=true)

Besides the pool property (and the Boolean xa property, which selects one of non-xa/xa connection factories), the org.ops4j.connectionfactory factory PID may contain properties that are prefixed with pool..

For the pooled-jms library, these prefixed properties are used (after removing the prefix) to configure an instance of:

  • org.messaginghub.pooled.jms.JmsPoolConnectionFactory, or
  • org.messaginghub.pooled.jms.JmsPoolXAConnectionFactory

The following listing is a realistic configuration of a pooled-jms pool (org.ops4j.connectionfactory-artemis factory PID) that is using a convenient syntax with jms.-prefixed properties:

# configuration for pax-jms-config to choose and configure specific org.ops4j.pax.jms.service.ConnectionFactoryFactory
name = jms/artemis
connectionFactoryType = ConnectionFactory
jms.url = tcp://localhost:61616
jms.user = fuse
jms.password = fuse
# org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory specific coniguration
jms.callTimeout = 12000
# ...

# hints for pax-jms-config to use selected org.ops4j.pax.jms.service.PooledConnectionFactoryFactory
pool = pooledjms
xa = false

# pooled-jms specific configuration of org.messaginghub.pooled.jms.JmsPoolConnectionFactory
pool.idleTimeout = 10
pool.maxConnections = 100
pool.blockIfSessionPoolIsFull = true
# ...

In the above configuration, pool and xa keys are hints (service filter properties) to choose one of the registered org.ops4j.pax.jms.service.PooledConnectionFactoryFactory services. In the case of the pooled-jms library it is:

karaf@root()> feature:install pax-jms-pool-pooledjms

karaf@root()> bundle:services -p org.ops4j.pax.jms.pax-jms-pool-pooledjms

OPS4J Pax JMS MessagingHub JMS Pool implementation (252) provides:
------------------------------------------------------------------
objectClass = [org.ops4j.pax.jms.service.PooledConnectionFactoryFactory]
pool = pooledjms
service.bundleid = 252
service.id = 331
service.scope = singleton
xa = false
-----
objectClass = [org.ops4j.pax.jms.service.PooledConnectionFactoryFactory]
pool = pooledjms
service.bundleid = 252
service.id = 335
service.scope = singleton
xa = true

Following is a complete example of the steps for creating and configuring a connection pool:

  1. Install the required features:

    karaf@root()> feature:install -v pax-jms-pool-pooledjms pax-jms-artemis
    Adding features: pax-jms-pool-pooledjms/[1.0.0,1.0.0]
    ...
  2. Install the jms feature:

    karaf@root()> feature:install jms
    
    karaf@root()> service:list org.ops4j.pax.jms.service.ConnectionFactoryFactory
    [org.ops4j.pax.jms.service.ConnectionFactoryFactory]
    ----------------------------------------------------
     service.bundleid = 249
     service.id = 327
     service.scope = singleton
     type = artemis
    Provided by :
     OPS4J Pax JMS Artemis Support (249)
    
    karaf@root()> service:list org.ops4j.pax.jms.service.PooledConnectionFactoryFactory
    [org.ops4j.pax.jms.service.PooledConnectionFactoryFactory]
    ----------------------------------------------------------
     pool = pooledjms
     service.bundleid = 251
     service.id = 328
     service.scope = singleton
     xa = false
    Provided by :
     OPS4J Pax JMS MessagingHub JMS Pool implementation (251)
    
    [org.ops4j.pax.jms.service.PooledConnectionFactoryFactory]
    ----------------------------------------------------------
     pool = pooledjms
     service.bundleid = 251
     service.id = 333
     service.scope = singleton
     xa = true
    Provided by :
     OPS4J Pax JMS MessagingHub JMS Pool implementation (251)
  3. Create a factory configuration:

    karaf@root()> config:edit --factory --alias artemis org.ops4j.connectionfactory
    karaf@root()> config:property-set connectionFactoryType ConnectionFactory
    karaf@root()> config:property-set osgi.jndi.service.name jms/artemis
    karaf@root()> config:property-set type artemis
    karaf@root()> config:property-set protocol amqp # so we switch to org.apache.qpid.jms.JmsConnectionFactory
    karaf@root()> config:property-set jms.url amqp://localhost:61616
    karaf@root()> config:property-set jms.username admin
    karaf@root()> config:property-set jms.password admin
    karaf@root()> config:property-set pool pooledjms
    karaf@root()> config:property-set xa false
    karaf@root()> config:property-set pool.idleTimeout 10
    karaf@root()> config:property-set pool.maxConnections 123
    karaf@root()> config:property-set pool.blockIfSessionPoolIsFull true
    karaf@root()> config:update
  4. Check if pax-jms-config processed the configuration into javax.jms.ConnectionFactory service:

    karaf@root()> service:list javax.jms.ConnectionFactory
    [javax.jms.ConnectionFactory]
    -----------------------------
     connectionFactoryType = ConnectionFactory
     felix.fileinstall.filename = file:${karaf.etc}/org.ops4j.connectionfactory-artemis.cfg
     jms.password = admin
     jms.url = amqp://localhost:61616
     jms.username = admin
     osgi.jndi.service.name = jms/artemis
     pax.jms.managed = true
     pool.blockIfSessionPoolIsFull = true
     pool.idleTimeout = 10
     pool.maxConnections = 123
     protocol = amqp
     service.bundleid = 250
     service.factoryPid = org.ops4j.connectionfactory
     service.id = 347
     service.pid = org.ops4j.connectionfactory.fc1b9e85-91b4-421b-aa16-1151b0f836f9
     service.scope = singleton
     type = artemis
    Provided by :
     OPS4J Pax JMS Config (250)
  5. Use the connection factory:

    karaf@root()> jms:connectionfactories
    JMS Connection Factory
    ──────────────────────
    jms/artemis
    
    karaf@root()> jms:info -u admin -p admin jms/artemis
    Property │ Value
    ─────────┼────────────────
    product  │ QpidJMS
    version  │ 0.30.0.redhat-1
    
    karaf@root()> jms:send -u admin -p admin jms/artemis DEV.QUEUE.1 "Hello Artemis"
    
    karaf@root()> jms:browse -u admin -p admin jms/artemis DEV.QUEUE.1
    Message ID                                      │ Content       │ Charset │ Type │ Correlation ID │ Delivery Mode │ Destination │ Expiration │ Priority │ Redelivered │ ReplyTo │ Timestamp
    ────────────────────────────────────────────────┼───────────────┼─────────┼──────┼────────────────┼───────────────┼─────────────┼────────────┼──────────┼─────────────┼─────────┼──────────────────────────────
    ID:64842f99-5cb2-4850-9e88-f50506d49d20:1:1:1-1 │ Hello Artemis │ UTF-8   │      │                │ Persistent    │ DEV.QUEUE.1 │ Never      │ 4        │ false       │         │ Mon May 14 12:47:13 CEST 2018

7.5.3. Using the pax-jms-pool-narayana connection pool module

The pax-jms-pool-narayna module does almost everything as pax-jms-pool-pooledjms. It installs the pooled-jms-specific org.ops4j.pax.jms.service.PooledConnectionFactoryFactory, both for XA and non-XA scenarios. The only difference is that in an XA scenario, there is an additional integration point. The org.jboss.tm.XAResourceRecovery OSGi service is registered to be picked up by com.arjuna.ats.arjuna.recovery.RecoveryManager.

7.5.4. Using the pax-jms-pool-transx connection pool module

The pax-jms-pool-transx module provides an implementation of org.ops4j.pax.jms.service.PooledConnectionFactoryFactory services that is based on the pax-transx-jms bundle. The pax-transx-jms bundle creates javax.jms.ConnectionFactory pools by using the org.ops4j.pax.transx.jms.ManagedConnectionFactoryBuilder facility. This is a JCA (Java™ Connector Architecture) solution that is discussed in Section 8.3, “About the pax-transx project”.

7.6. Deploying connection factories as artifacts

This topic discusses real-world recommendations.

In the deployment method, javax.jms.ConnectionFactory services are registered directly by application code. Usually, this code is inside a Blueprint container. Blueprint XML may be part of an ordinary OSGi bundle, installable by using mvn: URI, and stored in a Maven repository (local or remote). It is easier to version-control such bundles as compared to Configuration Admin configurations.

The pax-jms-config version 1.0.0 bundle adds a deployment method for connection factory configuration. An application developer registers the javax.jms.(XA)ConnectionFactory service (usually by using Bluerpint XML) and specifies service properties. Then pax-jms-config detects the registered, broker-specific connection factory and (using service properties) wraps the service inside a generic, non broker-specific, connection pool.

Following are three deployment methods that use Blueprint XML.

7.6.1. Manual deployment of connection factories

In this method, the pax-jms-config bundle is not needed. Application code is responsible for registration of both broker-specific and generic connection pools.

<!--
    Broker-specific, non-pooling, non-enlisting javax.jms.XAConnectionFactory
-->
<bean id="artemis" class="org.apache.activemq.artemis.jms.client.ActiveMQXAConnectionFactory">
    <argument value="tcp://localhost:61616" />
    <property name="callTimeout" value="2000" />
    <property name="initialConnectAttempts" value="3" />
</bean>

<!--
    Fuse exports this service from fuse-pax-transx-tm-narayana bundle.
-->
<reference id="tm" interface="javax.transaction.TransactionManager" />

<!--
    Non broker-specific, generic, pooling, enlisting javax.jms.ConnectionFactory
-->
<bean id="pool" class="org.messaginghub.pooled.jms.JmsPoolXAConnectionFactory">
    <property name="connectionFactory" ref="artemis" />
    <property name="transactionManager" ref="tm" />
    <property name="maxConnections" value="10" />
    <property name="idleTimeout" value="10000" />
</bean>

<!--
    Expose connection factory for use by application code (such as Camel, Spring, ...)
-->
<service interface="javax.jms.ConnectionFactory" ref="pool">
    <service-properties>
        <!-- Giving connection factory a name using one of these properties makes identification easier in jms:connectionfactories: -->
        <entry key="osgi.jndi.service.name" value="jms/artemis" />
        <!--<entry key="name" value="jms/artemis" />-->
        <!-- Without any of the above, name will fall back to "service.id" -->
    </service-properties>
</service>

Here are the shell commands that show how it should be used:

karaf@root()> feature:install artemis-core-client artemis-jms-client
karaf@root()> install -s mvn:org.apache.commons/commons-pool2/2.5.0
Bundle ID: 244
karaf@root()> install -s mvn:org.messaginghub/pooled-jms/0.3.0
Bundle ID: 245
karaf@root()> install -s blueprint:file://$PQ_HOME/message-brokers/blueprints/artemis-manual.xml
Bundle ID: 246

karaf@root()> bundle:services -p 246

Bundle 246 provides:
--------------------
objectClass = [javax.jms.ConnectionFactory]
osgi.jndi.service.name = jms/artemis
osgi.service.blueprint.compname = pool
service.bundleid = 246
service.id = 340
service.scope = bundle
-----
objectClass = [org.osgi.service.blueprint.container.BlueprintContainer]
osgi.blueprint.container.symbolicname = artemis-manual.xml
osgi.blueprint.container.version = 0.0.0
service.bundleid = 246
service.id = 341
service.scope = singleton

karaf@root()> feature:install jms

karaf@root()> jms:connectionfactories
JMS Connection Factory
──────────────────────
jms/artemis

karaf@root()> jms:info -u admin -p admin jms/artemis
Property │ Value
─────────┼──────────────────────────
product  │ ActiveMQ
version  │ 2.4.0.amq-711002-redhat-1

As shown in the above listing, the Blueprint bundle exports the javax.jms.ConnectionFactory service, which is a generic, non broker-specific, connection pool. The broker-specific javax.jms.XAConnectionFactory is not registered as an OSGi service, because Blueprint XML does not have an explicit <service ref="artemis"> declaration.

7.6.2. Factory deployment of connection factories

This method shows the use of pax-jms-config in a canonical way. This is a bit different than the method that was recommended for Fuse 6.x, where the requirement was to specify pooling configuration as service properties.

Here is the Blueprint XML example:

<!--
    A broker-specific org.ops4j.pax.jms.service.ConnectionFactoryFactory that can create (XA)ConnectionFactory
    using properties. It is registered by pax-jms-* bundles
-->
<reference id="connectionFactoryFactory"
        interface="org.ops4j.pax.jms.service.ConnectionFactoryFactory"
        filter="(type=artemis)" />

<!--
    Non broker-specific org.ops4j.pax.jms.service.PooledConnectionFactoryFactory that can create
    pooled connection factories with the help of org.ops4j.pax.jms.service.ConnectionFactoryFactory

    For example, pax-jms-pool-pooledjms bundle registers org.ops4j.pax.jms.service.PooledConnectionFactoryFactory
    with these properties:
     - pool = pooledjms
     - xa = true|false (both are registered)
-->
<reference id="pooledConnectionFactoryFactory"
        interface="org.ops4j.pax.jms.service.PooledConnectionFactoryFactory"
        filter="(&amp;(pool=pooledjms)(xa=true))" />

<!--
    When using XA connection factories, javax.transaction.TransactionManager service is not needed here.
    It is used internally by xa-aware pooledConnectionFactoryFactory.
-->
<!--<reference id="tm" interface="javax.transaction.TransactionManager" />-->

<!--
    Finally, use both factories to expose the pooled, xa-aware, connection factory.
-->
<bean id="pool" factory-ref="pooledConnectionFactoryFactory" factory-method="create">
    <argument ref="connectionFactoryFactory" />
    <argument>
        <props>
            <!--
                Properties needed by artemis-specific org.ops4j.pax.jms.service.ConnectionFactoryFactory
            -->
            <prop key="jms.url" value="tcp://localhost:61616" />
            <prop key="jms.callTimeout" value="2000" />
            <prop key="jms.initialConnectAttempts" value="3" />
            <!-- Properties needed by pooled-jms-specific org.ops4j.pax.jms.service.PooledConnectionFactoryFactory -->
            <prop key="pool.maxConnections" value="10" />
            <prop key="pool.idleTimeout" value="10000" />
        </props>
    </argument>
</bean>

<!--
    Expose connection factory for use by application code (such as Camel, Spring, ...)
-->
<service interface="javax.jms.ConnectionFactory" ref="pool">
    <service-properties>
        <!-- Giving connection factory a name using one of these properties makes identification easier in jms:connectionfactories: -->
        <entry key="osgi.jndi.service.name" value="jms/artemis" />
        <!--<entry key="name" value="jms/artemis" />-->
        <!-- Without any of the above, name will fall back to "service.id" -->
    </service-properties>
</service>

The previous example uses factory beans that create connection factories by using connection factory factories (…​). There is no need for an explicit reference to the javax.transaction.TransactionManager service, as this is tracked internally by the XA-aware PooledConnectionFactoryFactory.

Here is how it looks in a Fuse/Karaf shell:

karaf@root()> feature:install jms pax-jms-artemis pax-jms-pool-pooledjms

karaf@root()> install -s blueprint:file://$PQ_HOME/message-brokers/blueprints/artemis-pax-jms-factory-pooledjms.xml
Bundle ID: 253
karaf@root()> bundle:services -p 253

Bundle 253 provides:
--------------------
objectClass = [javax.jms.ConnectionFactory]
osgi.jndi.service.name = jms/artemis
osgi.service.blueprint.compname = pool
service.bundleid = 253
service.id = 347
service.scope = bundle
-----
objectClass = [org.osgi.service.blueprint.container.BlueprintContainer]
osgi.blueprint.container.symbolicname = artemis-pax-jms-factory-pooledjms.xml
osgi.blueprint.container.version = 0.0.0
service.bundleid = 253
service.id = 348
service.scope = singleton

karaf@root()> jms:connectionfactories
JMS Connection Factory
──────────────────────
jms/artemis

karaf@root()> jms:info -u admin -p admin jms/artemis
Property │ Value
─────────┼──────────────────────────
product  │ ActiveMQ
version  │ 2.4.0.amq-711002-redhat-1

As shown in the above listing, the Blueprint bundle exports the javax.jms.ConnectionFactory service, which is a generic, non broker-specific, connection pool. The broker-specific javax.jms.XAConnectionFactory is not registered as an OSGi service because Blueprint XML does not have an explicit <service ref="artemis"> declaration.

7.6.3. Mixed deployment of connection factories

The pax-jms-config 1.0.0 bundle adds another way of wrapping broker-specific connection factories within pooling connection factories by using service properties. This method matches the way it used to work in Fuse 6.x.

Here is the Blueprint XML example:

<!--
    Broker-specific, non-pooling, non-enlisting javax.jms.XAConnectionFactory
-->
<bean id="artemis" class="org.apache.activemq.artemis.jms.client.ActiveMQXAConnectionFactory">
    <argument value="tcp://localhost:61616" />
    <property name="callTimeout" value="2000" />
    <property name="initialConnectAttempts" value="3" />
</bean>

<!--
    Expose broker-specific connection factory with service properties.
    No need to expose pooling, enlisting, non broker-specific javax.jms.XAConnectionFactory. It will be registered
    automatically by pax-jms-config with the same properties as this <service>, but with a higher service.ranking
-->
<service id="pool" ref="artemis" interface="javax.jms.XAConnectionFactory">
    <service-properties>
        <!-- "pool" key is needed for pax-jms-config to wrap broker-specific connection factory inside connection pool -->
        <entry key="pool" value="pooledjms" />
        <!-- <service>/@id attribute does not propagate, but name of the connection factory is required using one of: -->
        <entry key="osgi.jndi.service.name" value="jms/artemis" />
        <!-- or: -->
        <!--<entry key="name" value="jms/artemis" />-->
        <!-- Other properties, that normally by e.g., pax-jms-pool-pooledjms -->
        <entry key="pool.maxConnections" value="10" />
        <entry key="pool.idleTimeout" value="10000" />
    </service-properties>
</service>

In the above example, you can see the manual register of only the broker-specific connection factory. The pool=pooledjms service property is a hint for the connection factory tracker that is managed by the pax-jms-config bundle. Connection factory services with this service property are wrapped within a pooling connection factory, in this example, pax-jms-pool-pooledjms.

Here is how it looks in a Fuse/Karaf shell:

karaf@root()> feature:install jms pax-jms-config pax-jms-artemis pax-jms-pool-pooledjms

karaf@root()> install -s blueprint:file://$PQ_HOME/message-brokers/blueprints/artemis-pax-jms-discovery.xml
Bundle ID: 254

karaf@root()> bundle:services -p 254

Bundle 254 provides:
--------------------
objectClass = [javax.jms.XAConnectionFactory]
osgi.jndi.service.name = jms/artemis
osgi.service.blueprint.compname = artemis
pool = pooledjms
pool.idleTimeout = 10000
pool.maxConnections = 10
service.bundleid = 254
service.id = 349
service.scope = bundle
-----
objectClass = [org.osgi.service.blueprint.container.BlueprintContainer]
osgi.blueprint.container.symbolicname = artemis-pax-jms-discovery.xml
osgi.blueprint.container.version = 0.0.0
service.bundleid = 254
service.id = 351
service.scope = singleton

karaf@root()> service:list javax.jms.XAConnectionFactory
[javax.jms.XAConnectionFactory]
-------------------------------
 osgi.jndi.service.name = jms/artemis
 osgi.service.blueprint.compname = artemis
 pool = pooledjms
 pool.idleTimeout = 10000
 pool.maxConnections = 10
 service.bundleid = 254
 service.id = 349
 service.scope = bundle
Provided by :
 Bundle 254
Used by:
 OPS4J Pax JMS Config (251)

karaf@root()> service:list javax.jms.ConnectionFactory
[javax.jms.ConnectionFactory]
-----------------------------
 osgi.jndi.service.name = jms/artemis
 osgi.service.blueprint.compname = artemis
 pax.jms.managed = true
 pax.jms.service.id.ref = 349
 pool.idleTimeout = 10000
 pool.maxConnections = 10
 service.bundleid = 251
 service.id = 350
 service.ranking = 1000
 service.scope = singleton
Provided by :
 OPS4J Pax JMS Config (251)

karaf@root()> jms:connectionfactories
JMS Connection Factory
──────────────────────
jms/artemis

karaf@root()> jms:info -u admin -p admin jms/artemis
Property │ Value
─────────┼──────────────────────────
product  │ ActiveMQ
version  │ 2.4.0.amq-711002-redhat-1

In the previous example, jms:connectionfactories shows only one service, because this command removes duplicate names. Two services were presented by jdbc:ds-list in the mixed deployment of data sources.

javax.jms.XAConnectionFactory is registered from the Blueprint bundle and it has the pool = pooledjms property declared.

javax.jms.ConnectionFactory is registered from the pax-jms-config bundle and:

  • It does not have the pool = pooledjms property. It was removed when registering the wrapper connection factory.
  • It has the service.ranking = 1000 property, so it is always the preferred version when, for example, looking for a connection factory by name.
  • It has the pax.jms.managed = true property, so it is not tried to be wrapped again.
  • It has the pax.jms.service.id.ref = 349 property, which indicates the original connection factory service that is wrapped inside the connection pool.
Red Hat logoGithubRedditYoutubeTwitter

Learn

Try, buy, & sell

Communities

About Red Hat Documentation

We help Red Hat users innovate and achieve their goals with our products and services with content they can trust.

Making open source more inclusive

Red Hat is committed to replacing problematic language in our code, documentation, and web properties. For more details, see the Red Hat Blog.

About Red Hat

We deliver hardened solutions that make it easier for enterprises to work across platforms and environments, from the core datacenter to the network edge.

© 2024 Red Hat, Inc.