Chapter 34. Resource adapters
A Jakarta Connectors Resource Adapter lets your applications communicate with any messaging provider. It configures how Jakarta EE components such as MDBs and other Jakarta Enterprise Beans, and even Servlets, can send or receive messages.
34.1. About the integrated Artemis resource adapter Copy linkLink copied to clipboard!
JBoss EAP 8.1 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-factoryelement, which is then used in Jakarta EE deployments by Jakarta Enterprise Beans 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 Java Message Service 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 theonMessage(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 Jakarta Enterprise Beans Applications for JBoss EAP.
34.2. Configuring the Artemis resource adapter to connect to Red Hat AMQ Copy linkLink copied to clipboard!
You can configure the integrated Artemis resource adapter to connect to a remote installation of Red Hat AMQ 7, which then becomes the Java Message Service provider for your JBoss EAP 8.1 applications. This allows JBoss EAP to be a client for the remote Red Hat AMQ 7 server.
If you require support for other messaging protocols, such as AMQP or STOMP, you must configure Red Hat AMQ 7 as your messaging broker. The Artemis resource adapter integrated in the JBoss EAP server can then be used to process messages for the deployed applications.
- 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 8.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-factoryand theexternal-context, there is a difference in the way each connection factory is created. When theexternal-contextis used to create the connection factory, it creates simple Java Message Service connection factory as defined in the Java Message Service specification. The newly created connection factory is equivalent to theRemoteConnectionFactory, which is defined by default inmessaging-activemqsubsystem. 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 thepooled-connection-factorycan be used to create connection factories in JBoss EAP 8. Theexternal-contextcan only be used to register Java Message Service destinations, which are already configured on the remote AMQ 7 broker, into the JNDI tree of the JBoss EAP 8 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 Red Hat AMQ server
.Procedure
Configure the queue in the Red Hat AMQ 7
broker.xmldeployment 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 uses the ActiveMQ Artemis Java Message Service Client 2.x. This client requires
anycastPrefixandmulticastPrefixprefixing on the address. It also expects the queue name to be the same as the address name.Create the remote connector.
/subsystem=messaging-activemq/remote-connector=netty-remote-throughput:add(socket-binding=messaging-remote-throughput)This creates the following
remote-connectorin themessaging-activemqsubsystem.<subsystem xmlns="urn:jboss:domain:messaging-activemq:17.0"> ... <remote-connector name="netty-remote-throughput" socket-binding="messaging-remote-throughput"/> ... </subsystem>Add the remote destination outbound socket binding.
/socket-binding-group=standard-sockets/remote-destination-outbound-socket-binding=messaging-remote-throughput:add(host=localhost, port=61616)This creates the following
remote-destinationin theoutbound-socket-bindingelement configuration.<outbound-socket-binding name="messaging-remote-throughput"> <remote-destination host="localhost" port="61616"/> </outbound-socket-binding>Add a pooled connection factory for the remote connector.
/subsystem=messaging-activemq/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-factoryin themessaging-activemqsubsystem.<subsystem xmlns="urn:jboss:domain:messaging-activemq:17.0"> ... <pooled-connection-factory name="activemq-ra-remote" entries="java:/RemoteJmsXA java:jboss/RemoteJmsXA" connectors="netty-remote-throughput"/> ... </subsystem>JBoss EAP is now configured to use the remote installation of Red Hat AMQ 7 as the messaging provider.
34.3. Java Message Service resources configuration for a remote Artemis-based broker Copy linkLink copied to clipboard!
From the management CLI, you can configure Java Message Service resources for a remote Artemis-based broker, such as Red Hat AMQ 7, using annotations like @JMSConnectionFactoryDefinition or @JMSDestinationDefinition, or by defining connection factories and pooled connection factories directly in the messaging-activemq subsystem. These resources do not require a local embedded Artemis broker, which reduces the memory and CPU footprint of the JBoss EAP server.
All examples use the modern addressing form: `/subsystem=messaging-activemq/
This addressing allows configuring messaging for a remote broker without requiring an embedded server. The legacy form, /subsystem=messaging-activemq/server=default/, should not be used for remote-broker configurations.
When configuring connections to a remote Artemis broker, always use /subsystem=messaging-activemq/ addressing. The /server=default/ path is preserved only for legacy embedded-broker setups.
Artemis 1.x required destination prefixes (jms.queue.* and jms.topic.*).
Artemis 2.x does not.
For compatibility, JBoss EAP still adds these prefixes by default.
To disable prefixes when connecting to a remote Artemis 2.x server, set:
enable-amq1-prefix=false
- Java Message Service resources configuration using the @JMSConnectionFactoryDefinition annotation
-
JBoss EAP uses the
@JMSConnectionFactoryDefinitionannotation to define a connection factory. This factory can reference a local or a remote broker. The annotation’sresourceAdapterattribute must refer to the pooled connection factory defined in themessaging-activemqsubsystem.
If resourceAdapter is omitted, the server resolves it through the default binding: /subsystem=ee/service=default-bindings
If the default binding does not resolve to a pooled connection factory, the resource is created under the resource-adapters subsystem instead.
Procedure
- Configuring @JMSConnectionFactoryDefinition using the default resource adapter
- Create an outbound socket binding:
/socket-binding-group=standard-sockets/remote-destination-outbound-socket-binding=messaging-remote:add(host=127.0.0.2, port=5445)Create a connector referencing the socket binding:
/subsystem=messaging-activemq/remote-connector=remote-amq:add(socket-binding="messaging-remote")Create a pooled connection factory referencing the connector:
/subsystem=messaging-activemq/pooled-connection-factory=activemq-ra-remote:add(entries=["java:/jms/remoteCF"], connectors=["remote-amq"])Define the default JMS connection factory for the EE subsystem:
/subsystem=ee/service=default-bindings:write-attribute(name=jms-connection-factory, value="java:/jms/remoteCF")Use the
@JMSConnectionFactoryDefinitionannotation in your application code:@JMSConnectionFactoryDefinition(name="java:/jms/remoteCF")
- Configuring @JMSConnectionFactoryDefinition using a remote Artemis broker
- Create a connector:
/subsystem=messaging-activemq/remote-connector=remote-amq:add(socket-binding="messaging-remote")Create a pooled connection factory:
/subsystem=messaging-activemq/pooled-connection-factory=activemq-ra-remote:add(entries=["java:/jms/remoteCF"], connectors=["remote-amq"])Assign the default JMS connection factory:
/subsystem=ee/service=default-bindings:write-attribute(name=jms-connection-factory, value="java:/jms/remoteCF")Use the
@JMSConnectionFactoryDefinitionannotation in your application code:@JMSConnectionFactoryDefinition( name="java:app/myCF", resourceAdapter="activemq-ra-remote" )
- Configuring @JMSConnectionFactoryDefinition using a third-party JMS resource adapter
- Create a connector:
/subsystem=messaging-activemq/remote-connector=remote-amq:add(socket-binding="messaging-remote")Create a pooled connection factory:
/subsystem=messaging-activemq/pooled-connection-factory=thirdparty-ra:add(entries=["java:/jms/remoteCF"], connectors=["remote-amq"])Update the default EE binding:
/subsystem=ee/service=default-bindings:write-attribute(name=jms-connection-factory, value="java:/jms/remoteCF")Use the
@JMSConnectionFactoryDefinitionannotation in your application code:@JMSConnectionFactoryDefinition( name="java:app/myCF", resourceAdapter="thirdparty-ra" )
- Java Message Service Resources configuration using the JMSDestinationDefinition annotation
-
If the
resourceAdapterattribute points to a pooled connection factory inmessaging-activemq, the server may create destinations on the local broker. To ensure destinations are created on a remote Artemis-based broker, the pooled-connection-factory must be defined under/subsystem=messaging-activemq/, and must reference a remote connector.
To create destinations on a remote Artemis broker, define the pooled connection factory without /server=default/.
- Configuring Java Message Service Resources using the JMSDestinationDefinition annotation
- Create a connector:
/subsystem=messaging-activemq/remote-connector=remote-amq:add(socket-binding="messaging-remote")Create a pooled connection factory for the remote broker:
/subsystem=messaging-activemq/pooled-connection-factory=activemq-ra-remote:add(entries=["java:/jms/remoteCF"], connectors=["remote-amq"])Set the EE default binding:
/subsystem=ee/service=default-bindings:write-attribute(name=jms-connection-factory, value="java:/jms/remoteCF")Use the
@JMSDestinationDefinitionannotation in your application code:@JMSDestinationDefinition( name = "java:/jms/queue/MessageBeanQueue", interfaceName = "jakarta.jms.Queue", destinationName = "MessageBeanQueue" properties = { "management-address=remote-activemq.management" } )
- Configuring an MDB to use a pooled connection factory
- Annotate the MDB with the name of the pooled connection factory created for remote Artemis:
import org.jboss.ejb3.annotation.ResourceAdapter;
@ResourceAdapter("activemq-ra-remote")
@MessageDriven(name="MyMDB", activationConfig={ ... })
public class MyMDB implements MessageListener {
public void onMessage(Message message) {
...
}
}
To send messages using the remote connection factory:
@Inject
@JMSConnectionFactory("java:/jms/remoteCF")
private JMSContext context;
- Configuring remote destinations for MDBs
- If the local server does not define a JNDI binding for the remote destination, the MDB can specify the physical destination name and disable JNDI lookup:
@ResourceAdapter("activemq-ra-remote")
@MessageDriven(name="MyMDB", activationConfig={
@ActivationConfigProperty(propertyName="useJNDI", propertyValue="false"),
@ActivationConfigProperty(propertyName="destination", propertyValue="myQueue")
})
public class MyMDB implements MessageListener {
}
- Configuring remote ActiveMQ server resources using the management console
You can configure the following remote ActiveMQ server resources from the management console:
- Generic Connector
- In VM Connector
- HTTP Connector
- Remote Connector
- Discovery Group
- Connection Factory
- Pooled Connection Factory
- External JMS Queue
- External JMS Topic
To configure the remote ActiveMQ server resources from the management console:
-
Access the management console and navigate to Configuration
Subsystems Messaging (ActiveMQ) Remote ActiveMQ Server and click View. - In the navigation pane, click the resource you want to configure.
Additional resources
34.4. Deploying the IBM MQ resource adapter Copy linkLink copied to clipboard!
IBM provides many versions of the IBM MQ resource adapter, including Java EE–based variants and resource adapters targeting earlier Jakarta EE releases. JBoss EAP 8.1 implements Jakarta EE 10 and therefore requires the IBM MQ resource adapter that is specifically built for the Jakarta EE 10 APIs.
Always deploy the wmq.jakarta.jmsra.rar adapter when using IBM MQ with JBoss EAP 8.x. Older IBM MQ resource adapters that use the javax.* package namespace or target earlier Jakarta EE versions are not compatible and must not be deployed.
IBM 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 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 MQ, see IBM MQ on the IBM products website.
- Summary
- IBM MQ can be configured as an external Java Message Service provider for JBoss EAP 8.1. This section covers the steps to deploy and configure the IBM MQ resource adapter in JBoss EAP. This deployment and configuration can be accomplished by using the management CLI tool or the web-based management console. See JBoss EAP supported configurations for the most current information about the supported configurations of IBM MQ.
You must restart your system after configuring your IBM MQ resource adapter for the configuration changes to take effect.
JBoss EAP 8.0 is a Jakarta EE 10 implementation, so the packages used for all EE APIs have changed from javax to jakarta, which requires a Jakarta EE 10 compliant resource adapter. If you were using the IBM MQ Resource adapter in JBoss EAP 7.x or earlier, you must use wmq.jakarta.jmsra.rar, the IBM MQ Resource Adapter that uses this jakarta namespace.
-
Remove the previous resource adapter configuration for
wmq.jmsra.rarand usewmq.jakarta.jmsra.rar -
Deploy
wmq.jakarta.jmsra.rarand configure as described in the steps in this section.
Prerequisites
- Before you get started, you must verify the version of the IBM MQ resource adapter and understand its configuration properties.
-
The IBM MQ resource adapter is supplied as a Resource Archive (RAR) file called
wmq.jakarta.jmsra.rar. You can obtain thewmq.jakarta.jmsra.rarfile from/opt/mqm/java/lib/jca/wmq.jakarta.jmsra.rar. See JBoss EAP supported configurations for information about the specific versions that are supported for each release of JBoss EAP. You must know the following IBM MQ configuration values. Refer to the IBM MQ product documentation for details about these values.
- MQ_QUEUE_MANAGER: The name of the IBM MQ queue manager
- MQ_HOST_NAME: The hostname used to connect to the IBM MQ queue manager
- MQ_CHANNEL_NAME: The server channel used to connect to the IBM 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 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
-
First, deploy the resource adapter manually by copying the
wmq.jakarta.jmsra.rarfile 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.jakarta.jmsra.rar:add(archive=wmq.jakarta.jmsra.rar, transaction-support=XATransaction)Note that the
transaction-supportelement 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 Configuration Guide.
For non-transactional deployments, change the value of
transaction-supporttoNoTransaction./subsystem=resource-adapters/resource-adapter=wmq.jakarta.jmsra.rar:add(archive=wmq.jakarta.jmsra.rar, transaction-support=NoTransaction)Now that the resource adapter is created, you can add the necessary configuration elements to it.
Add an
admin-objectfor queues and configure its properties:/subsystem=resource-adapters/resource-adapter=wmq.jakarta.jmsra.rar/admin-objects=queue-ao:add(class-name=com.ibm.mq.jakarta.connector.outbound.MQQueueProxy, jndi-name=java:jboss/MQ_QUEUE_NAME) /subsystem=resource-adapters/resource-adapter=wmq.jakarta.jmsra.rar/admin-objects=queue-ao/config-properties=baseQueueName:add(value=MQ_QUEUE_NAME) /subsystem=resource-adapters/resource-adapter=wmq.jakarta.jmsra.rar/admin-objects=queue-ao/config-properties=baseQueueManagerName:add(value=MQ_QUEUE_MANAGER)Add an
admin-objectfor topics and configure its properties:/subsystem=resource-adapters/resource-adapter=wmq.jakarta.jmsra.rar/admin-objects=topic-ao:add(class-name=com.ibm.mq.jakarta.connector.outbound.MQTopicProxy, jndi-name=java:jboss/MQ_TOPIC_NAME) /subsystem=resource-adapters/resource-adapter=wmq.jakarta.jmsra.rar/admin-objects=topic-ao/config-properties=baseTopicName:add(value=MQ_TOPIC_NAME) /subsystem=resource-adapters/resource-adapter=wmq.jakarta.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.jakarta.jmsra.rar/connection-definitions=mq-cd:add(class-name=com.ibm.mq.jakarta.connector.outbound.ManagedConnectionFactoryImpl, jndi-name=java:jboss/MQ_CONNECTIONFACTORY_NAME, tracking=false) /subsystem=resource-adapters/resource-adapter=wmq.jakarta.jmsra.rar/connection-definitions=mq-cd/config-properties=hostName:add(value=MQ_HOST_NAME) /subsystem=resource-adapters/resource-adapter=wmq.jakarta.jmsra.rar/connection-definitions=mq-cd/config-properties=port:add(value=MQ_PORT) /subsystem=resource-adapters/resource-adapter=wmq.jakarta.jmsra.rar/connection-definitions=mq-cd/config-properties=channel:add(value=MQ_CHANNEL_NAME) /subsystem=resource-adapters/resource-adapter=wmq.jakarta.jmsra.rar/connection-definitions=mq-cd/config-properties=transportType:add(value=MQ_CLIENT) /subsystem=resource-adapters/resource-adapter=wmq.jakarta.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 8.1 messaging to IBM MQ, use the management CLI to modify the
ejb3subsystem as follows:/subsystem=ejb3:write-attribute(name=default-resource-adapter-name,value=wmq.jakarta.jmsra.rar)Configure the
@ActivationConfigPropertyand@ResourceAdapterannotations in the MDB code as follows:@MessageDriven(name="IbmMqMdb", activationConfig = { @ActivationConfigProperty(propertyName = "destinationType",propertyValue = "jakarta.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.jakarta.jmsra-VERSION.rar") @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) public class IbmMqMdb implements MessageListener { }Be sure to replace the VERSION in the
@ResourceAdaptervalue with the actual version in the name of the RAR.Activate your resource adapter:
/subsystem=resource-adapters/resource-adapter=wmq.jakarta.jmsra.rar:activate()
34.4.1. Limitations and known issues with the IBM MQ resource adapters Copy linkLink copied to clipboard!
The following table lists known issues with the IBM MQ resource adapters. A checkmark (✔) in the version column indicates the issue is a problem for that version of the resource adapter.
| JIRA | Description of Issue | IBM MQ 9 |
|---|---|---|
|
The IBM MQ resource adapter returns different String values for the | ✔ | |
| The following restrictions apply to message property names for IBM MQ.
See Property name restrictions for IBM MQ, Version 8.0 and Property name restrictions for IBM MQ, Version 9.0 on the IBM Knowledge Center website for the complete list of message property name restrictions for each version of the resource adapter. | ✔ | |
|
When specifying the @ActivationConfigProperty(propertyName = "destination", propertyValue = "QUEUE")
| ✔ | |
|
If the IBM MQ resource adapter is used to create a connection factory in a Jakarta EE deployment using the @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>"
}
)
| ✔ | |
|
The IBM MQ resource adapter is able to read messages from queues and topics even before the connection has started. This means a consumer can consume messages before the connection is started. To avoid hitting this issue, use connection factories created by the remote IBM MQ broker using the | ✔ | |
|
Once
In the following code example, the @Inject
@JMSConnectionFactory("jms/CF")
@JMSPasswordCredential(userName="myusername", password="mypassword")
@JMSSessionMode(JMSContext.DUPS_OK_ACKNOWLEDGE)
transient JMSContext context3;
| ✔ | |
|
According to the Java Message Service specification, the | ✔ | |
|
The | ✔ | |
|
The default | ✔ | |
|
The IBM MQ resource adapter throws WARN [org.jboss.jca.core.connectionmanager.pool.strategy.PoolByCri] (EJB default - 7) IJ000604: Throwable while attempting to get a new connection: null: com.ibm.mq.connector.DetailedResourceException: MQJCA1011: Failed to allocate a {JMS} connection., error code: MQJCA1011 An internal error caused an attempt to allocate a connection to fail. See the linked exception for details of the failure.
The following is an example of code that can cause this issue. QueueConnection qc = queueConnectionFactory.createQueueConnection("invalidUserName", "invalidPassword");
| ✔ | |
|
Due to an invalid class cast conversion by the resource adapter in the SVR-ERROR: Expected JMSException, received com.ibm.mq.connector.outbound.MQQueueProxy cannot be cast to com.ibm.mq.jms.MQDestination
This is because the JNDI name used in the queue or topic lookup is | ✔ | |
|
The | ✔ | |
|
If work is done on a | ✔ | |
|
If you close a connection and then immediately create a ERROR [io.undertow.request] (default task-1) UT005023: Exception handling request to /jmsServlet-1.0-SNAPSHOT/: com.ibm.msg.client.jms.DetailedJMSRuntimeException: MQJCA0002: An exception occurred in the IBM MQ layer. See the linked exception for details.
A call to IBM MQ classes for Java(tm) caused an exception to be thrown.
This issue does not occur when there is a delay in creating the new | ✔ | |
| If a stateful session bean tries to send a message to a topic while in a container managed transaction (CMT), the message send fails with the following message. SVR-ERROR: com.ibm.msg.client.jms.DetailedJMSException: JMSWMQ2007: Failed to send a message to destination 'MDB_NAME TOPIC_NAME'
The stack trace shows it to be caused by the following exception. com.ibm.mq.MQException: JMSCMQ0001: IBM MQ call failed with compcode '2' ('MQCC_FAILED') reason '2072' ('MQRC_SYNCPOINT_NOT_AVAILABLE')
| ✔ | |
|
When you deploy either the IBM MQ 8 or IBM MQ 9 resource adapter, WARN [org.jboss.as.connector.deployers.RADeployer] (MSC service thread 1-8) IJ020017: Invalid archive: file:/<path-to-jboss>/jboss-eap-7.4/standalone/tmp/vfs/temp/tempa02bdd5ee254e590/content-135e13d4f38704fc/contents/
The IBM MQ v9.0.0.4 resource adapter was tested as part of the Java Message Service providers tests for JBoss EAP 8.1. You can choose to ignore this warning message or you can disable the archive validation by setting the /subsystem=jca/archive-validation=archive-validation:write-attribute(name=enabled, value=false)
| ✔ |
34.5. Deploying a generic Java Message Service resource adapter Copy linkLink copied to clipboard!
JBoss EAP can be configured to work with third-party Java Message Service providers; however, not all Java Message Service providers produce a Java Message Service Jakarta Connectors resource adapter for integration with Jakarta application platforms. This procedure covers the steps required to configure the generic Java Message Service resource adapter included in JBoss EAP to connect to a Java Message Service provider. In this procedure, Tibco EMS 10 is used as an example Java Message Service provider. Other Java Message Service providers may require different configuration.
Before using the generic Java Message Service resource adapter, check with the Java Message Service provider to see if they have their own resource adapter that can be used with JBoss EAP. The generic Java Message Service Jakarta Connectors resource adapter should only be used when a Java Message Service provider does not provide its own resource adapter.
Tibco EMS is not a tested or supported broker with JBoss EAP 8.x and serves only to demonstrate the configuration of the generic Java Message Service resource adapter.
Prerequisites
- Your Java Message Service provider server must already be configured and ready for use. Any binaries required for the provider’s Java Message Service implementation will be needed.
You will need to know the values of the following Java Message Service provider properties to be able to look up its Java Message Service 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 Java Message Service provider values for your environment.
Procedure
Create and configure the resource adapter module.
Create a JBoss EAP module that contains all the libraries required to connect and communicate with the Java Message Service 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 Java Message Service implementation to
EAP_HOME/modules/org/jboss/genericjms/provider/main.NoteFor Tibco EMS, the only binary required is
jakarta.jms-tibjms.jarfrom the Tibco installation’slibdirectory.Create a
module.xmlfile inEAP_HOME/modules/org/jboss/genericjms/provider/mainas below, listing the JAR files from the previous steps as resources:<module xmlns="urn:jboss:module:1.9" name="org.jboss.genericjms.provider"> <resources> <!-- all jars required by the Jakarta Messaging provider, in this case Tibco --> <resource-root path="jakarta.jms-tibjms.jar"/> </resources> <dependencies> <module name="javax.api"/> <module name="jakarta.jms.api"/> </dependencies> </module>Add the module to the
eesubsystem 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 Java Naming and Directory Interface external context to the Java Message Service provider.
The Java Message Service resources, such as connection factories and destinations, are looked up in the Java Message Service 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 Java Message Service provider.
NoteIn this procedure,
EAP_HOME/standalone/configuration/standalone-full.xmlis used as the JBoss EAP configuration file.Use the management CLI to create an external Java Naming and Directory Interface context and include its configuration properties. The properties in the example below should be replaced by the correct value to connect to the remote Java Message Service provider. For example, some Java Message Service providers, such as Tibco EMS, do not support the Java Naming and Directory Interface
lookup(Name)method. In these cases, add theorg.jboss.as.naming.lookup.by.stringproperty with a value oftrueto 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 Java Naming and Directory Interface lookup to a resource starting with
java:global/remoteJMS/will be done on the remote Java Message Service provider. As an example, if a message-driven bean performs a Java Naming and Directory Interface lookup forjava:global/remoteJMS/Queue1, the external context will connect to the remote Java Message Service provider and perform a lookup for theQueue1resource.Alternatively, you can make a Java Naming and Directory Interface lookup to the remote server without using an
external-contextwhen looking up the Java Naming and Directory Interface 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 Java Naming and Directory Interface lookup for
java:/jms/queue/myQueuewill locate the queue namedmyQueueon the remote server.Create the generic Java Message Service 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 Java Message Service resource adapter.
Use the management CLI to configure the resource adapter’s
connection-definitionand 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
ejb3subsystem to use the generic resource adapter./subsystem=ejb3:write-attribute(name=default-resource-adapter-name, value=generic-ra)The generic Java Message Service 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 Jakarta Messaging resource adapter requires the Java Naming and Directory Interface 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 = "jakarta.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 Jakarta Messaging provider. } }ImportantWhen using the generic Java Message Service resource adapter, ensure you set the session to be transacted, to avoid a potential
NullPointerExceptionerror. The error occurs because the generic Java Message Service resource adapter attempts processing of parameters, when the Jakarta 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")
34.5.1. The limitations and known issues for the generic Java Message Service resource adapter Copy linkLink copied to clipboard!
The Java Message Service API does not provide a programmatic way to create the Java Message Service resources, only the features that are defined in the Java Message Service 3.1 specification are supported. For more information about the specification, see Jakarta Messaging 3 specification.
EE.5.18.4 Java Message Service Connection Factory Resource Definition
This is the ability for an application to define a Java Message Service
ConnectionFactoryresource.EE.5.18.5 Java Message Service Destination Definition
This is the ability for an application to define a Java Message Service
Destinationresource.
34.6. Using the resource annotation Copy linkLink copied to clipboard!
Using the @Resource annotation, Jakarta Enterprise Beans can directly inject Java Message Service 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.
- Injecting Java Message Service resources
.Procedure
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 Java Naming and Directory Interface name in the
lookup,name, ormappedNameparameter of the@Resourceannotation. For example:
@Resource(lookup = "java:jboss/exported/jms/queue/OutQueue") public Queue myOutQueue;
34.6.1. Injecting Connection Factories Copy linkLink copied to clipboard!
Define your connection factory as shown below. The example shows a
JmsXApooled connection factory.<pooled-connection-factory name="activemq-ra" entries="java:/JmsXA java:jboss/DefaultJMSConnectionFactory" connectors="in-vm" transaction="xa"/>Inject the default
activemq-rapooled connection factory as shown below:@Resource(lookup = "java:/JmsXA") private ConnectionFactory cf;