此内容没有您所选择的语言版本。
Chapter 31. Resource Adapters
A Java Connector Architecture (JCA) Resource Adapter lets your applications communicate with any messaging provider. It configures how JEE components such as MDBs and other EJBs, and even Servlets, can send or receive messages.
31.1. About the Integrated Artemis Resource Adapter
JBoss EAP 7 includes an integrated Artemis resource adapter, which uses the pooled-connection-factory
element to configure the outbound and inbound connections of the resource adapter.
Outbound Connection
Outbound connections are defined using the pooled-connection-factory
element, which is then used in Java EE deployments by EJBs and servlets to send messages to and receive messages from queues or topics. Because connections created from connection factories are created in the scope of the application server, they can use application server features like the following:
- Connection pooling
- Authentication using the security domains defined by the application server
- Participation in XA transactions using the transaction manager
This is a major difference with a pooled-connection-factory
as these features are not available with a basic connection-factory
like InVmConnectionFactory
or RemoteConnectionFactory
. Also, be aware that with a connection factory defined using pooled-connection-factory
, it is not possible to do a lookup using JNDI from an external standalone JMS client.
Inbound Connections
Inbound connections are used only by message-driven beans (MDBs) to receive message from a queue or a topic. MDBs are stateless session beans that listen on a queue or topic. They must implement the public onMessage(Message message)
method, which is called when a message is sent to a queue or a topic. The Artemis resource adapter is responsible for receiving the message from the queue or the topic and passing it to the onMessage(Message message)
method. For this purpose it configures the inbound connection, which defines the location of the integrated Artemis server and some additional elements.
Each MDB session bean uses a thread from the client thread pool to consume the message from the destination. If the maximum pool size is not defined, it is determined to be eight (8) times the number of CPU core processors. For systems with many MDB sessions, such as test suites, this can potentially lead to thread exhaustion and force MDBs to wait for a free thread from the pool. You can increase the maximum pool size of client thread pool using the management CLI. The following command sets the maximum client thread pool size to 128
.
/subsystem=messaging-activemq:write-attribute(name=global-client-thread-pool-max-size,value=128)
For information about how to configure the client thread pool size, see Client Thread Management. For more information about MDBs, see Message Driven Beans in Developing EJB Applications for JBoss EAP.
31.2. Using the Integrated Artemis Resource Adapter for Remote Connections
JBoss EAP includes a resource adapter to make connections to its integrated ActiveMQ Artemis messaging server. By default the pooled-connection-factory
defined in the messaging-activemq
subsystem uses the adapter to make the connections. However, you can use the same resource adapter to make connections to an Artemis server running inside a remote instance of JBoss EAP as well.
The activemq-ra
pooled connection factory, which is configured by default in the messaging-activemq
subsystem, has the java:jboss/DefaultJMSConnectionFactory
entry assigned. This entry is required by the messaging-activemq
subsystem. If you decide to remove the activemq-ra
pooled connection factory, you must assign this entry to a different connection factory. Otherwise you will see the following error in the server log on deployment.
WFLYCTL0412: Required services that are not installed:" => ["jboss.naming.context.java.jboss.DefaultJMSConnectionFactory"]
To connect to an Artemis server running inside a remote instance of JBoss EAP, create a new pooled-connection-factory
by following the steps below.
Create an outbound-socket-binding pointing to the remote messaging server:
/socket-binding-group=standard-sockets/remote-destination-outbound-socket-binding=remote-server:add(host=<server host>, port=8080)
Create a remote-connector referencing the outbound-socket-binding created in step 1.
/subsystem=messaging-activemq/server=default/http-connector=remote-http-connector:add(socket-binding=remote-server,endpoint=http-acceptor)
Create a pooled-connection-factory referencing the remote-connector created in step 2.
/subsystem=messaging-activemq/server=default/pooled-connection-factory=remote-artemis:add(connectors=[remote-http-connector], entries=[java:/jms/remoteCF])
Configuring an MDB to use a pooled-connection-factory
After the pooled-connection-factory
is configured to connect to a remote Artemis server, Message-Driven Beans (MDB) wanting to read messages from the remote server must be annotated with the @ResourceAdapter
annotation using the name of the pooled-connection-factory
resource.
import org.jboss.ejb3.annotation.ResourceAdapter; @ResourceAdapter("remote-artemis") @MessageDriven(name = "MyMDB", activationConfig = { ... }) public class MyMDB implements MessageListener { public void onMessage(Message message) { ... } }
If the MDB needs to send messages to the remote server, it must inject the pooled-connection-factory
by looking it up using one of its JNDI entries
.
@Inject @JMSConnectionFactory("java:/jms/remoteCF") private JMSContext context;
Configuring the JMS destination
An MDB must also specify the destination from which it will consume messages. The standard way to do this is to define a destinationLookup
activation config property that corresponds to a JNDI lookup on the local server.
@ResourceAdapter("remote-artemis") @MessageDriven(name = "MyMDB", activationConfig = { @ActivationConfigProperty(propertyName = "destinationLookup", propertyValue = "myQueue"), ... }) public class MyMDB implements MessageListener { ... }
If the local server does not include a JNDI binding for the remote Artemis server, specify the name of the destination, as configured in the remote Artemis server, using the destination
activation config property and set the useJNDI
activation config property to false
. This instructs the Artemis resource adapter to automatically create the JMS destination without requiring a JNDI lookup.
@ResourceAdapter("remote-artemis") @MessageDriven(name = "MyMDB", activationConfig = { @ActivationConfigProperty(propertyName = "useJNDI", propertyValue = "false"), @ActivationConfigProperty(propertyName = "destination", propertyValue = "myQueue"), ... }) public class MyMDB implements MessageListener { ... }
In the above example, the activation config properties configure the MDB to consume messages from the JMS Queue named myQueue
hosted on the remote Artemis server. In most cases, the MDB does not need to lookup other destinations to process the consumed messages, and it can use the JMSReplyTo
destination if it is defined on the message.
If the MDB needs any other JMS destinations defined on the remote server, it must use client-side JNDI. See Connecting to a Server for more information.
31.3. Configuring the Artemis Resource Adapter to Connect to Red Hat JBoss AMQ 7
You can configure the integrated Artemis resource adapter to connect to a remote installation of Red Hat JBoss AMQ 7, which then becomes the JMS provider for your JBoss EAP 7.1 applications. This allows JBoss EAP to be a client for the remote Red Hat JBoss AMQ 7 server.
Be aware that the Artemis resource adapter that is integrated in JBoss EAP 7.1 does not support dynamic creation of queues and topics in the Red Hat JBoss AMQ 7 broker. You must configure all queue and topic destinations directly on the remote Red Hat JBoss AMQ 7 server.
Limitations of the Integrated Resource Adapter
Dynamic Creation of Queues and Topics
Be aware that the Artemis resource adapter that is integrated in JBoss EAP 7.1 does not support dynamic creation of queues and topics in the Red Hat AMQ 7 broker. You must configure all queue and topic destinations directly on the remote Red Hat AMQ 7 server.
Creation of Connection Factories
Although Red Hat AMQ allows connection factories to be configured using both the pooled-connection-factory
and the external-context
, there is a difference in the way each connection factory is created. When the external-context
is used to create the connection factory, it creates simple JMS connection factory as defined in the JMS specification. The newly created connection factory is equivalent to the RemoteConnectionFactory
, which is defined by default in messaging-activemq
subsystem. This connection factory is independent of the other components in the application server, meaning it is not aware of, nor is it able to use, other components like the transaction manager or the security manager. For this reason, only the pooled-connection-factory
can be used to create connection factories in JBoss EAP 7. The external-context
can only be used to register JMS destinations, which are already configured on the remote AMQ 7 broker, into the JNDI tree of the JBoss EAP 7 server so that local deployments can look them up or inject them.
Connection factories created by configuring the external-context
or the connection-factory
elements cannot be used to connect to the remote AMQ 7 broker as they do not use the Artemis resource adapter. Only connection factories created by configuring the pooled-connection-factory
element are supported for use when connecting to the remote AMQ7 broker.
Configure JBoss EAP to Use a Remote JBoss AMQ Server
You can use the management CLI to configure JBoss EAP to use a remote installation of Red Hat JBoss AMQ 7 as the messaging provider by following the steps below.
Configure the queue in the Red Hat JBoss AMQ 7
broker.xml
deployment descriptor file.<configuration xmlns="urn:activemq" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:activemq /schema/artemis-configuration.xsd"> <core xmlns="urn:activemq:core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:activemq:core "> .... <acceptors> <acceptor name="netty-acceptor">tcp://localhost:61616?anycastPrefix=jms.queue.;multicastPrefix=jms.topic. </acceptor> </acceptors> <addresses> <address name="MyQueue"> <anycast> <queue name="MyQueue" /> </anycast> </address> <address name="MyOtherQueue"> <anycast> <queue name="MyOtherQueue" /> </anycast> </address> <address name="MyTopic"> <multicast/> </address> <addresses> .... </core> </configuration>
NoteThe Artemis resource adapter that is included with JBoss EAP 7.1 uses the ActiveMQ Artemis JMS Client 1.5.5. This client requires
anycastPrefix
andmulticastPrefix
prefixing on the address. It also expects the queue name to be the same as the address name.Create the remote connector.
/subsystem=messaging-activemq/server=default/remote-connector=netty-remote-throughput:add(socket-binding=messaging-remote-throughput)
This creates the following
remote-connector
in themessaging-activemq
subsystem.<subsystem xmlns="urn:jboss:domain:messaging-activemq:2.0"> <server name="default"> .... <remote-connector name="netty-remote-throughput" socket-binding="messaging-remote-throughput"/> ... </subsystem>
Add a pooled connection factory for the remote connector.
/subsystem=messaging-activemq/server=default/pooled-connection-factory=activemq-ra-remote:add(transaction=xa,entries=[java:/RemoteJmsXA, java:jboss/RemoteJmsXA],connectors=[netty-remote-throughput])
This creates the following
pooled-connection-factory
in themessaging-activemq
subsystem.<pooled-connection-factory name="activemq-ra-remote" entries="java:/RemoteJmsXA java:jboss/RemoteJmsXA" connectors="netty-remote-throughput"/>
Add the remote server to the remote destination outbound socket binding group.
/socket-binding-group=standard-sockets/remote-destination-outbound-socket-binding=messaging-remote-throughput:add(host=localhost, port=61616)
This creates the following
remote-destination
in theoutbound-socket-binding
element configuration.<outbound-socket-binding name="messaging-remote-throughput"> <remote-destination host="localhost" port="61616"/> </outbound-socket-binding>
Create the
external-context
bindings for the queues and topics./subsystem=naming/binding=java\:global\/remoteContext:add(binding-type=external-context, class=javax.naming.InitialContext, module=org.apache.activemq.artemis, environment=[java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory, java.naming.provider.url=tcp://127.0.0.1:61616, queue.MyQueue=MyQueue, queue.MyOtherQueue=MyOtherQueue, topic.MyTopic=MyTopic])
This creates the following
external-context
bindings in thenaming
subsystem.<subsystem xmlns="urn:jboss:domain:naming:2.0"> <bindings> <external-context name="java:global/remoteContext" module="org.apache.activemq.artemis" class="javax.naming.InitialContext"> <environment> <property name="java.naming.factory.initial" value="org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory"/> <property name="java.naming.provider.url" value="tcp://127.0.0.1:61616"/> <property name="queue.MyQueue" value="MyQueue"/> <property name="queue.MyOtherQueue" value="MyOtherQueue"/> <property name="topic.MyTopic" value="MyTopic"/> </environment> </external-context> </bindings> ... </subsystem>
Create the lookup entry for the JMS queues and topics by setting the JNDI name to the Red Hat JBoss AMQ 7 address name value. This creates a mapping between the JNDI name and the Red Hat JBoss AMQ 7 address name.
/subsystem=naming/binding=java\:\/MyQueue:add(lookup=java:global/remoteContext/MyQueue,binding-type=lookup) /subsystem=naming/binding=java\:\/MyOtherQueue:add(lookup=java:global/remoteContext/MyOtherQueue,binding-type=lookup) /subsystem=naming/binding=java\:\/MyTopic:add(lookup=java:global/remoteContext/MyTopic,binding-type=lookup)
This creates the following
lookup
configurations in thenaming
subsystem.<subsystem xmlns="urn:jboss:domain:naming:2.0"> .... <lookup name="java:/MyQueue" lookup="java:global/remoteContext/MyQueue"/> <lookup name="java:/MyOtherQueue" lookup="java:global/remoteContext/MyOtherQueue"/> <lookup name="java:/MyTopic" lookup="java:global/remoteContext/MyTopic"/> .... </subsystem>
JBoss EAP is now configured to use the remote installation of Red Hat JBoss AMQ 7 as the messaging provider.
31.4. Deploying an A-MQ Resource Adapter
You can deploy the resource adapter provided by the Red Hat JBoss A-MQ product and have, for example, Red Hat JBoss A-MQ 6.3.0, become the external JMS provider for JBoss EAP.
See Install the ActiveMQ Resource Adapter in Integrating with JBoss Enterprise Application Platform, which is in the Red Hat JBoss A-MQ documentation suite, for details on how to deploy and configure a Red Hat JBoss A-MQ resource adapter.
31.4.1. Issues with the A-MQ 6 Resource Adapter
JBoss EAP will track and monitor applications, looking for unclosed resources. While useful in many cases, such monitoring might cause unexpected behavior when an application tries to re-use a closed instance of
UserTransaction
in a single method. Add the attributetracking="false"
to the<connection-definition/>
element when configuring the A-MQ resource adapter if your applications re-use connections in this way.<connection-definition class-name="..." tracking="false" ... />
-
The A-MQ 6 resource adapter does not implement
XAResourceWrapper
from the Narayana API, which is used by JBoss EAP. Consequently, when the Transaction Manager sends a commit to all the XA transaction participants and then crashes while waiting for a reply, it will go on indefinitely logging warnings until records of the committed transaction are removed from its object store. The A-MQ 6 resource adapter returns the code
XAER_RMERR
when an error, such as a network disconnection, occurs during the call of the commit method protocol. This behavior breaks the XA specification since the correct return code should beXAER_RMFAIL
orXAER_RETRY
. Consequently, the transaction is left in an unknown state on the message broker side, which can cause data inconsistency in some cases. A message will be logged similar to the one below when the unexpected error code is returned.WARN [com.arjuna.ats.jtax] ...: XAResourceRecord.rollback caused an XA error: ARJUNA016099: Unknown error code:0 from resource ... in transaction ...: javax.transaction.xa.XAException: Transaction ... has not been started.
- Red Hat JBoss A-MQ 6.x supports the JMS 1.1 specification that is included with Java EE 6. It does not support the JMS 2.0 specification that is included with Java EE 7 and supported in JBoss EAP 7. If you need to send messages to a remote A-MQ broker, you must use the JMS 1.1 API within your application code. For more information about JBoss A-MQ supported standards, see Red Hat JBoss A-MQ Supported Standards and Protocols.
31.5. Deploying the IBM Resource Adapters
About IBM WebSphere® MQ
IBM WebSphere® MQ is the Messaging Oriented Middleware (MOM) product offering from IBM that allows applications on distributed systems to communicate with each other. This is accomplished through the use of messages and message queues. IBM WebSphere® MQ is responsible for delivering messages to the message queues and for transferring data to other queue managers using message channels. For more information about IBM WebSphere® MQ, see IBM MQ.
Summary
This section covers the steps to deploy and configure the IBM WebSphere® MQ resource adapter in JBoss EAP. This deployment and configuration can be accomplished by manually editing configuration files, using the management CLI tool, or using the web-based management console.
See JBoss EAP supported configurations for information about the supported configurations of IBM WebSphere® MQ.
IBM MQ can be configured as an external JMS provider for JBoss EAP 7.1 and later.
The IBM resource adapter was renamed from IBM WebSphere® MQ to IBM MQ for release 8.0 of the product. For more information, see IBM MQ (formerly IBM WebSphere® MQ) Version 8.0 documentation.
Prerequisites
Before you get started, you must verify the version of the IBM WebSphere® MQ resource adapter and understand its configuration properties.
-
The IBM WebSphere® MQ resource adapter is supplied as a Resource Archive (RAR) file called
wmq.jmsra.rar
. You can obtain thewmq.jmsra.rar
file from/opt/mqm/java/lib/jca/wmq.jmsra.rar
. See JBoss EAP supported configurations for information about the specific versions that are supported. You must know the following IBM WebSphere® MQ configuration values. Refer to the IBM WebSphere® MQ product documentation for details about these values.
- MQ_QUEUE_MANAGER: The name of the IBM WebSphere® MQ queue manager
- MQ_HOST_NAME: The host name used to connect to the IBM WebSphere® MQ queue manager
- MQ_CHANNEL_NAME: The server channel used to connect to the IBM WebSphere® MQ queue manager
- MQ_QUEUE_NAME: The name of the destination queue
- MQ_TOPIC_NAME: The name of the destination topic
- MQ_PORT: The port used to connect to the IBM WebSphere® MQ queue manager
- MQ_CLIENT: The transport type
For outbound connections, you must also be familiar with the following configuration value:
- MQ_CONNECTIONFACTORY_NAME: The name of the connection factory instance that will provide the connection to the remote system
Procedure
The following are default configurations provided by IBM and are subject to change. Please refer to IBM WebSphere® MQ documentation for more information.
-
First, deploy the resource adapter manually by copying the
wmq.jmsra.rar
file to theEAP_HOME/standalone/deployments/
directory. Next, use the management CLI to add the resource adapter and configure it.
/subsystem=resource-adapters/resource-adapter=wmq.jmsra.rar:add(archive=wmq.jmsra.rar, transaction-support=XATransaction)
Note that the
transaction-support
element was set toXATransaction
. When using transactions, be sure to supply the security domain of the XA recovery datasource, as in the example below./subsystem=resource-adapters/resource-adapter=test/connection-definitions=test:write-attribute(name=recovery-security-domain,value=myDomain)
For more information about XA Recovery see Configuring XA Recovery in the JBoss EAP Configuration Guide.
For non-transactional deployments, change the value of
transaction-support
toNoTransaction
./subsystem=resource-adapters/resource-adapter=wmq.jmsra.rar:add(archive=wmq.jmsra.rar, transaction-support=NoTransaction)
Now that the resource adapter is created, you can add the necessary configuration elements to it.
Add an
admin-object
for queues and configure its properties./subsystem=resource-adapters/resource-adapter=wmq.jmsra.rar/admin-objects=queue-ao:add(class-name=com.ibm.mq.connector.outbound.MQQueueProxy, jndi-name=java:jboss/MQ_QUEUE_NAME) /subsystem=resource-adapters/resource-adapter=wmq.jmsra.rar/admin-objects=queue-ao/config-properties=baseQueueName:add(value=MQ_QUEUE_NAME) /subsystem=resource-adapters/resource-adapter=wmq.jmsra.rar/admin-objects=queue-ao/config-properties=baseQueueManagerName:add(value=MQ_QUEUE_MANAGER)
Add an
admin-object
for topics and configure its properties./subsystem=resource-adapters/resource-adapter=wmq.jmsra.rar/admin-objects=topic-ao:add(class-name=com.ibm.mq.connector.outbound.MQTopicProxy, jndi-name=java:jboss/MQ_TOPIC_NAME) /subsystem=resource-adapters/resource-adapter=wmq.jmsra.rar/admin-objects=topic-ao/config-properties=baseTopicName:add(value=MQ_TOPIC_NAME) /subsystem=resource-adapters/resource-adapter=wmq.jmsra.rar/admin-objects=topic-ao/config-properties=brokerPubQueueManager:add(value=MQ_QUEUE_MANAGER)
Add a connection definition for a managed connection factory and configure its properties.
/subsystem=resource-adapters/resource-adapter=wmq.jmsra.rar/connection-definitions=mq-cd:add(class-name=com.ibm.mq.connector.outbound.ManagedConnectionFactoryImpl, jndi-name=java:jboss/MQ_CONNECTIONFACTORY_NAME, tracking=false) /subsystem=resource-adapters/resource-adapter=wmq.jmsra.rar/connection-definitions=mq-cd/config-properties=hostName:add(value=MQ_HOST_NAME) /subsystem=resource-adapters/resource-adapter=wmq.jmsra.rar/connection-definitions=mq-cd/config-properties=port:add(value=MQ_PORT) /subsystem=resource-adapters/resource-adapter=wmq.jmsra.rar/connection-definitions=mq-cd/config-properties=channel:add(value=MQ_CHANNEL_NAME) /subsystem=resource-adapters/resource-adapter=wmq.jmsra.rar/connection-definitions=mq-cd/config-properties=transportType:add(value=MQ_CLIENT) /subsystem=resource-adapters/resource-adapter=wmq.jmsra.rar/connection-definitions=mq-cd/config-properties=queueManager:add(value=MQ_QUEUE_MANAGER)
If you want to change the default provider for the EJB3 messaging system in JBoss EAP from JBoss EAP 7 messaging to IBM WebSphere® MQ, use the management CLI to modify the
ejb3
subsystem as follows:/subsystem=ejb3:write-attribute(name=default-resource-adapter-name,value=wmq.jmsra.rar)
Configure the
@ActivationConfigProperty
and@ResourceAdapter
annotations in the MDB code as follows:@MessageDriven(name="WebSphereMQMDB", activationConfig = { @ActivationConfigProperty(propertyName = "destinationType",propertyValue = "javax.jms.Queue"), @ActivationConfigProperty(propertyName = "useJNDI", propertyValue = "false"), @ActivationConfigProperty(propertyName = "hostName", propertyValue = "MQ_HOST_NAME"), @ActivationConfigProperty(propertyName = "port", propertyValue = "MQ_PORT"), @ActivationConfigProperty(propertyName = "channel", propertyValue = "MQ_CHANNEL_NAME"), @ActivationConfigProperty(propertyName = "queueManager", propertyValue = "MQ_QUEUE_MANAGER"), @ActivationConfigProperty(propertyName = "destination", propertyValue = "MQ_QUEUE_NAME"), @ActivationConfigProperty(propertyName = "transportType", propertyValue = "MQ_CLIENT") }) @ResourceAdapter(value = "wmq.jmsra-VERSION.rar") @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) public class WebSphereMQMDB implements MessageListener { }
Be sure to replace the VERSION in the
@ResourceAdapter
value with the actual version in the name of the RAR.
31.5.1. IBM WebSphere® MQ and IBM MQ Resource Adapters - The Limitations and Known Issues
IBM WebSphere® MQ 7.5 Resource Adapter - Limitations and Known Issues
The deployment of the IBM WebSphere® MQ 7.5 resource adapter does not load the
javax.jms.api
module for your deployment. It also does not provide support for the new Java EE 7 annotations like@JMSConnectionFactoryDefinitions
,@JMSDestinationDefinition
. It is necessary to have themessaging-activemq
subsystem in the configuration to enable it. If you do not want the JBoss EAP messaging server to be started, add an emptymessaging-activemq
subsystem.<subsystem xmlns="urn:jboss:domain:messaging-activemq:2.0"> </subsystem>
-
Calling the
createConnection()
method on the IBM Websphere® MQ 7.5.0.4 resource adapter implementation ofQueueConnectionFactory
andTopicConnectionFactory
, with or without parameters, leads to ajavax.jms.JMSException
to be thrown. - The IBM Websphere® MQ 7.5.0.4 resource adapter is able to read messages from queues and topics even before the connection has started.
-
If the transaction manager calls second rollback against the same XID, then IBM WebSphere® MQ 7.5 resource adapter does not return
XAException
with error codeXAER_NOTA
but it rather returnsXAER_RMFAIL
which is incorrect. This does not have an impact on data consistency but the logged warnings in the server log are impacted. -
The IBM WebSphere® MQ resource adapter does not implement
XAResourceWrapper
from the Narayana API, which is used by JBoss EAP. Consequently, when the Transaction Manager sends a commit to all the XA transaction participants and then crashes while waiting for a reply, it will go on indefinitely logging warnings until records of the committed transaction are removed from its object store. There is a known issue in IBM WebSphere® MQ Resource Adapter version 7.5.0.3 and earlier that causes periodic recovery to fail with an XA exception with messages similar to the following in the JBoss EAP server log:
WARN [com.arjuna.ats.jta] (Periodic Recovery) ARJUNA016027: Local XARecoveryModule.xaRecovery got XA exception XAException.XAER_INVAL: javax.transaction.xa.XAException: The method 'xa_recover' has failed with errorCode '-5'.
A fix is available in later versions, but remember the behavior of version 7.5.0.4 as noted in this list. A detailed description of this issue can be found here: http://www-01.ibm.com/support/docview.wss?uid=swg1IC97579.
With IBM WebSphere® MQ 7.5 and later, the
commit()
androllback()
methods onUserTransaction
close any JMS connections that are part of that transaction. Resolve this issue by settingtracking="false"
in theconnection-definition
as in the following example./subsystem=resource-adapters/resource-adapter=eis.rar/connection-definitions=myConnectionDef:write-attribute(name=tracking,value=false)
The
wmq.jmsra.rar
resource adapter contains jars with dependencies configured to be found in specific locations. When these hard-coded locations are not discovered, JBoss EAP will log warnings like those below. These warnings are harmless from a functional point of view and require no action.14:38:27,543 WARN [org.jboss.as.server.deployment] (MSC service thread 1-8) WFLYSRV0059: Class Path entry connector.jar in /content/wmq.jmsra.rar/com.ibm.mq.jar does not point to a valid jar for a Class-Path reference. 14:38:27,551 WARN [org.jboss.as.server.deployment] (MSC service thread 1-8) WFLYSRV0059: Class Path entry jta.jar in /content/wmq.jmsra.rar/com.ibm.mq.jmqi.jar does not point to a valid jar for a Class-Path reference. 14:38:27,552 WARN [org.jboss.as.server.deployment] (MSC service thread 1-8) WFLYSRV0059: Class Path entry ldap.jar in /content/wmq.jmsra.rar/com.ibm.mqjms.jar does not point to a valid jar for a Class-Path reference. 14:38:27,553 WARN [org.jboss.as.server.deployment] (MSC service thread 1-8) WFLYSRV0059: Class Path entry jndi.jar in /content/wmq.jmsra.rar/com.ibm.mqjms.jar does not point to a valid jar for a Class-Path reference. 14:38:27,553 WARN [org.jboss.as.server.deployment] (MSC service thread 1-8) WFLYSRV0059: Class Path entry fscontext.jar in /content/wmq.jmsra.rar/com.ibm.mqjms.jar does not point to a valid jar for a Class-Path reference. 14:38:27,553 WARN [org.jboss.as.server.deployment] (MSC service thread 1-8) WFLYSRV0059: Class Path entry providerutil.jar in /content/wmq.jmsra.rar/com.ibm.mqjms.jar does not point to a valid jar for a Class-Path reference. 14:38:27,555 WARN [org.jboss.as.server.deployment] (MSC service thread 1-8) WFLYSRV0059: Class Path entry jms.jar in /content/wmq.jmsra.rar/com.ibm.msg.client.jms.jar does not point to a valid jar for a Class-Path reference. 14:38:27,557 WARN [org.jboss.as.server.deployment] (MSC service thread 1-8) WFLYSRV0059: Class Path entry rmm.jar in /content/wmq.jmsra.rar/com.ibm.msg.client.wmq.v6.jar does not point to a valid jar for a Class-Path reference. 14:38:27,557 WARN [org.jboss.as.server.deployment] (MSC service thread 1-8) WFLYSRV0059: Class Path entry CL3Export.jar in /content/wmq.jmsra.rar/com.ibm.msg.client.wmq.v6.jar does not point to a valid jar for a Class-Path reference. 14:38:27,557 WARN [org.jboss.as.server.deployment] (MSC service thread 1-8) WFLYSRV0059: Class Path entry CL3Nonexport.jar in /content/wmq.jmsra.rar/com.ibm.msg.client.wmq.v6.jar does not point to a valid jar for a Class-Path reference. ... 14:38:28,018 WARN [org.jboss.as.connector.deployers.RADeployer] (MSC service thread 1-5) IJ020017: Invalid archive: file:/home/mnovak/tmp/jboss-eap-7.0/standalone/tmp/vfs/temp/tempc3f7f9d35e24ba16/content-12e0796e05502d20/contents/ 14:38:28,124 WARN [org.jboss.as.connector.deployers.RaXmlDeployer] (MSC service thread 1-8) IJ020017: Invalid archive: file:/home/mnovak/tmp/jboss-eap-7.0/standalone/tmp/vfs/temp/tempc3f7f9d35e24ba16/content-12e0796e05502d20/contents/
When specifying the
destination
property name value for an MDB using the@ActivationConfigProperty
annotation, you must use all upper case letters. For example:@ActivationConfigProperty(propertyName = "destination", propertyValue = "QUEUE")
IBM MQ 8 Resource Adapter - Limitations and Known Issues
The IBM resource adapter was renamed from IBM WebSphere® MQ to IBM MQ for release 8.0 of the product. For more information, see IBM MQ (formerly IBM WebSphere® MQ) Version 8.0 documentation.
Like the deployment of the IBM WebSphere® MQ 7.5 resoure adapter, it is necessary to have the
messaging-activemq
subsystem in the configuration to enable the IBM MQ 8 resource adapter. If you do not want the JBoss EAP messaging server to be started, add an emptymessaging-activemq
subsystem.<subsystem xmlns="urn:jboss:domain:messaging-activemq:2.0"> </subsystem>
The following restrictions apply to property names for IBM MQ. See Property name restrictions for IBM MQ, Version 8.0 on the IBM Knowledge Center web site for complete details.
- A property must not begin with "JMS" or "usr.JMS" as they are reserved for use by IBM® MQ JMS classes. Exceptions are noted on the IBM Knowledge Center web site.
- Do not use any lower or upper case mix of the strings "NULL", "TRUE", "FALSE", "NOT", "AND", "OR", "BETWEEN", "LIKE", "IN", "IS", or "ESCAPE", as they are reserved SQL keywords used in selection strings.
- A property name beginning with any lower or upper case mix of "mq", with the exception of "mq_usr", can contain only one full stop "." (U+002E) character. Multiple "." characters are not allowed in properties with those prefixes.
- Two "." characters must contain other characters in between; you cannot have an empty "." character in the hierarchy. A property name cannot end in a "." character.
- If an application sets the property "a.b" and then the property "a.b.c", it is unclear whether in the hierarchy "b" contains a value or another logical grouping. Such a hierarchy is "mixed content" and this is not supported. Setting a property that causes mixed content is not allowed.
-
In the
activation-config
section of the deployment descriptor, you must not configure thedestinationName
property using special characters such as_
,&
, or|
. Use of these characters causes the MDB deployment to fail with acom.ibm.msg.client.jms.DetailedInvalidDestinationException
exception.
If the IBM MQ resource adapter is used to create a connection factory in a Java EE deployment using the
@JMSConnectionFactoryDefinition
annotation, you must specify theresourceAdapter
property. Otherwise, the deployment will fail.@JMSConnectionFactoryDefinition( name = "java:/jms/WMQConnectionFactory", interfaceName = "javax.jms.ConnectionFactory", resourceAdapter = "wmq.jmsra", properties = { "channel=<channel>", "hostName=<hostname_wmq_broker>", "transportType=<transport_type>", "queueManager=<queue_manager>" } )
IBM MQ resource adapter version 8.0.0.2 has a known issue creating connections using the user name and password. The following is an example of code that can run into this issue.
connectionFactory.createConnection(username, password);
The execution of this code can result in the following error being written to the server log.
ERROR [stderr] (default task-1) com.ibm.msg.client.jms.DetailedJMSException: MQJCA0002: An exception occurred in the WebSphere MQ layer. See the linked exception for details. ... Caused by: com.ibm.mq.connector.DetailedSecurityException: MQJCA1028: Re-authentication is not supported., error code: MQJCA1028 The application server attempted to re-authenticate a JMS connection, but the WebSphere MQ resource adapter does not support re-authentication. In the supplied ra.xml file, the property called reauthentication-support has the value false. Make sure that you have not changed the value of this property. If the property still has the value false, then this error is an application server error.
If you run into this error, upgrade to IBM MQ v8.0.0.6, which contains the fix and is certified to work with JBoss EAP 7.1 or later.
When specifying the
destination
property name value for an MDB using the@ActivationConfigProperty
annotation, you must use all upper case letters. For example:@ActivationConfigProperty(propertyName = "destination", propertyValue = "QUEUE")
31.6. Deploying a Generic JMS Resource Adapter
JBoss EAP can be configured to work with third-party JMS providers; however, not all JMS providers produce a JMS JCA resource adapter for integration with Java application platforms. This procedure covers the steps required to configure the generic JMS resource adapter included in JBoss EAP to connect to a JMS provider. In this procedure, Tibco EMS 8 is used as an example JMS provider. Other JMS providers may require different configuration.
Before using the generic JMS resource adapter, check with the JMS provider to see if they have their own resource adapter that can be used with JBoss EAP. The generic JMS JCA resource adapter should only be used when a JMS provider does not provide its own resource adapter.
Before you can configure a generic resource adapter, you will need to do the following:
- Your JMS provider server must already be configured and ready for use. Any binaries required for the provider’s JMS implementation will be needed.
You will need to know the values of the following JMS provider properties to be able to look up its JMS resources, such as connection factories, queues or topics.
-
java.naming.factory.initial
-
java.naming.provider.url
-
java.naming.factory.url.pkgs
-
In the example XML used in this procedure, these parameters are written as PROVIDER_FACTORY_INITIAL
, PROVIDER_URL
, and PROVIDER_CONNECTION_FACTORY
respectively. Replace these placeholders with the JMS provider values for your environment.
31.6.1. Configure a Generic JMS Resource Adapter for Use with a Third-party JMS Provider
Create and configure the resource adapter module.
Create a JBoss EAP module that contains all the libraries required to connect and communicate with the JMS provider. This module will be named org.jboss.genericjms.provider.
-
Create the following directory structure:
EAP_HOME/modules/org/jboss/genericjms/provider/main
Copy the binaries required for the provider’s JMS implementation to
EAP_HOME/modules/org/jboss/genericjms/provider/main
.NoteFor Tibco EMS, the binaries required are
tibjms.jar
andtibcrypt.jar
from the Tibco installation’slib
directory.Create a
module.xml
file inEAP_HOME/modules/org/jboss/genericjms/provider/main
as below, listing the JAR files from the previous steps as resources:<module xmlns="urn:jboss:module:1.5" name="org.jboss.genericjms.provider"> <resources> <!-- all jars required by the JMS provider, in this case Tibco --> <resource-root path="tibjms.jar"/> <resource-root path="tibcrypt.jar"/> </resources> <dependencies> <module name="javax.api"/> <module name="javax.jms.api"/> </dependencies> </module>
Add the module to the
ee
subsystem using the following CLI command:/subsystem=ee:list-add(name=global-modules, value={"name" => "org.jboss.genericjms.provider", "slot" =>"main"}
-
Create the following directory structure:
Create and configure a JNDI external context to the JMS provider.
The JMS resources, such as connection factories and destinations, are looked up in the JMS provider. Add an external context in the JBoss EAP instance so that any local lookup for this resource will automatically look up the resource on the remote JMS provider.
NoteIn this procedure,
EAP_HOME/standalone/configuration/standalone-full.xml
is used as the JBoss EAP configuration file.Use the management CLI to create an external JNDI context and include its configuration properties. The properties in the example below should be replaced by the correct value to connect to the remote JMS provider. For example, some JMS providers, such as Tibco EMS, do not support the JNDI
lookup(Name)
method. In these cases, add theorg.jboss.as.naming.lookup.by.string
property with a value oftrue
to work around this issue. Check the adapter’s documentation for information on required properties and their values./subsystem=naming/binding="java:global/remoteJMS":add(binding-type=external-context,module=org.jboss.genericjms.provider,class=javax.naming.InitialContext,environment=[java.naming.factory.initial=com.tibco.tibjms.naming.TibjmsInitialContextFactory,java.naming.provider.url=tcp://<hostname>:7222,org.jboss.as.naming.lookup.by.string=true])
With the external context configured properly, any JNDI lookup to a resource starting with
java:global/remoteJMS/
will be done on the remote JMS provider. As an example, if a message-driven bean performs a JNDI lookup forjava:global/remoteJMS/Queue1
, the external context will connect to the remote JMS provider and perform a lookup for theQueue1
resource.Alternatively, you can make a JNDI lookup to the remote server without using an
external-context
when looking up the JNDI name. To do so, use the CLI to create a new binding that references theexternal-context
, as in the example below./subsystem=naming/binding=java\:\/jms\/queue\/myQueue:add(binding-type=lookup, lookup=java:global/remoteJMS/jms/queue/myQueue)
In the example above, an application that does a JNDI lookup for
java:/jms/queue/myQueue
will locate the queue namedmyQueue
on the remote server.Create the generic JMS resource adapter.
Use the management CLI to create the resource adapter
/subsystem=resource-adapters/resource-adapter=generic-ra:add(module=org.jboss.genericjms,transaction-support=XATransaction)
Configure the generic JMS resource adapter.
Use the management CLI to configure the resource adapter’s
connection-definition
and other elements./subsystem=resource-adapters/resource-adapter=generic-ra/connection-definitions=tibco-cd:add(class-name=org.jboss.resource.adapter.jms.JmsManagedConnectionFactory, jndi-name=java:/jms/XAQCF) /subsystem=resource-adapters/resource-adapter=generic-ra/connection-definitions=tibco-cd/config-properties=ConnectionFactory:add(value=XAQCF) /subsystem=resource-adapters/resource-adapter=generic-ra/connection-definitions=tibco-cd/config-properties=JndiParameters:add(value="java.naming.factory.initial=com.tibco.tibjms.naming.TibjmsInitialContextFactory;java.naming.provider.url=tcp://<hostname>:7222") /subsystem=resource-adapters/resource-adapter=generic-ra/connection-definitions=tibco-cd:write-attribute(name=security-application,value=true)
Configure the default message-driven bean pool in the
ejb3
subsystem to use the generic resource adapter./subsystem=ejb3:write-attribute(name=default-resource-adapter-name, value=generic-ra)
The generic JMS resource adapter is now configured and ready for use. Below is an example of using the resource adapter when creating a new message-driven bean.
Example: Code Using the Generic Resource Adapter
@MessageDriven(name = "HelloWorldQueueMDB", activationConfig = { // The generic JMS resource adapter requires the JNDI bindings // for the actual remote connection factory and destination @ActivationConfigProperty(propertyName = "connectionFactory", propertyValue = "java:global/remoteJMS/XAQCF"), @ActivationConfigProperty(propertyName = "destination", propertyValue = "java:global/remoteJMS/Queue1"), @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"), @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge") }) public class HelloWorldQueueMDB implements MessageListener { public void onMessage(Message message) { // called every time a message is received from the _Queue1_ queue on the JMS provider. } }
When using the generic JMS resource adapter, ensure you set the session to be transacted, to avoid a potential NullPointerException
error. The error occurs because the generic JMS resource adapter attempts processing of parameters, when the Java EE specification states that they are not to be processed. This is accomplished by doing the following: connection.createSession(true, Session.SESSION_TRANSACTED);
You can also use the pooled connection factory from the resource adapter:
@Resource(lookup = "java:/jms/XAQCF") private ConnectionFactory cf;
It is not possible to inject a resource from an external context directly but it is possible to inject an external context and then perform a lookup. For example, a lookup for a queue deployed in a Tibco EMS broker would be as follows.
@Resource(lookup = "java:global/remoteJMS") private Context context; ... Queue queue = (Queue) context.lookup("Queue1")
31.7. Using the Resource Annotation
Using the @Resource
annotation, Enterprise Java Beans (EJBs) can directly inject Java Message Service (JMS) resources or connection factories. You can specify the following parameters using the @Resource
annotations:
-
lookup
-
name
-
mappedName
To inject a resource, you must specify the Java Naming and Directory Interface (JNDI) name of the resource in one of these parameters.
31.7.1. Injecting JMS Resources
Define your queue as shown below:
<jms-queue name="OutQueue" entries="jms/queue/OutQueue java:jboss/exported/jms/queue/OutQueue"/>
Inject this queue by specifying its JNDI name in the
lookup
,name
, ormappedName
parameter of the@Resource
annotation. For example:@Resource(lookup = "java:jboss/exported/jms/queue/OutQueue") public Queue myOutQueue;
31.7.2. Injecting Connection Factories
Define your connection factory as shown below. The example shows a
JmsXA
pooled connection factory.<pooled-connection-factory name="activemq-ra" entries="java:/JmsXA java:jboss/DefaultJMSConnectionFactory" connectors="in-vm" transaction="xa"/>
Inject the default
activemq-ra
pooled connection factory as shown below:@Resource(lookup = "java:/JmsXA") private ConnectionFactory cf;
31.7.3. The Limitations and Known Issues for the Generic JMS Resource Adapter
The generic JMS resource adapter relies on the JMS API to communicate with JMS servers. Because the JMS API does not provide a programmatic way to create the JMS resources, the following new features that are defined in the Java™ Platform, Enterprise Edition (Java EE) Specification, v7 are not supported.
EE.5.18.4 JMS Connection Factory Resource Definition
This is the ability for an application to define a JMS
ConnectionFactory
resource.EE.5.18.5 JMS Destination Definition
This is the ability for an application to define a JMS
Destination
resource.