Connecting a Worklight JMS Adapter to Websphere MQ Server - jms

I am getting the below error while invoking a JMS adapter(connects to Websphere MQ Server)
"JMS connection exception received: null. Closing the connection"
Please see below configurations (initialContextFactory, connectionFactory and destination)
MQJMSAdapter.xml
<connectivity>
<connectionPolicy xsi:type="jms:JMSConnectionPolicyType">
<!-- uncomment this if you want to use an external JNDI repository -->
<namingConnection url="file:/C:/JNDI-DIRECTORY/"
initialContextFactory="com.sun.jndi.fscontext.RefFSContextFactory"
/>
<jmsConnection
connectionFactory="myCF"
/>
</connectionPolicy>
<loadConstraints maxConcurrentConnectionsPerNode="10"/>
</connectivity>
I have installed and configured IBM Websphere MQ server in my local machine and followed below guide to configure the JNDI namesapce and administered objects
http://pic.dhe.ibm.com/infocenter/prodconn/v1r0m0/index.jsp?topic=%2Fcom.ibm.scenarios.wmqwasmig2v7.doc%2Ftopics%2Fins_sample.htm
Kindly give your inputs. Thanks in Advance

Related

JMS issue connecting from WebSphere Liberty to Apache TomEE Plume

I need to connect from code running in WebSphere Liberty to an MDB in Apache TomEE Plume. I am using activemq-rar-5.16.3.
Here is the Java code:
public void notifyListeners(String caseId) {
logger.debug("+notifyListeners");
int timeToLive = 15 * 1000; // 15 seconds
try {
logger.debug("Creating context");
InitialContext ic = new InitialContext();
logger.debug("Got Initial context");
ConnectionFactory jmsFactory = (ConnectionFactory)ic.lookup("jndi/JMS_BASE_QCF");
logger.debug("Got Factory");
JMSContext context = jmsFactory.createContext();
logger.debug("Creating text message");
TextMessage msg = context.createTextMessage(caseId);
logger.debug("Sending text message");
context.createProducer().setTimeToLive(timeToLive).send(jmsSendQueue, msg);
logger.debug("Text message sent");
} catch (Throwable e) {
logger.error("Caught Exception sending ActiveMQ Message : " + e, e);
}
logger.debug("-notifyListeners");
}
No matter what I try, the code hangs at jmsFactory.createContext(). There's no exception. It just hangs.
I can see from the Apache TomEE logs that an ActiveMQ listener has been created on tcp://127.0.0.1:61616 and verified this with a netstat command.
I can't move to the later version of the rar because it relies upon a Java 11 JRE.
Does anyone have any ideas how I can debug this? Wireshark shows nothing, and changing the Liberty definition to point the ActiveMQ Connection Factory to 61615 changes nothing - so I don't think the createContext method is getting as far as contacting the ActiveMQ broker. It's hardly relevant, but this method runs in an asynchronous CDI event handler in Liberty. There is nothing untoward in the Liberty logs, and no FFDC events.
Some more details:
Liberty: product = WebSphere Application Server 21.0.0.1 (wlp-1.0.48.cl210120210113-1459)
Apache TomEE: Apache Tomcat (TomEE)/9.0.52 (8.0.8)
My server.xml (relevent bits):
<!-- language: xml -->
<featureManager>
<feature>ejbLite-3.2</feature>
<feature>jaxws-2.2</feature>
<feature>jndi-1.0</feature>
<feature>jpa-2.2</feature>
<feature>jpaContainer-2.2</feature>
<feature>jsp-2.3</feature>
<feature>localConnector-1.0</feature>
<feature>mdb-3.2</feature>
<feature>microProfile-3.3</feature>
<feature>monitor-1.0</feature>
<feature>wasJmsClient-2.0</feature>
<feature>wasJmsSecurity-1.0</feature>
<feature>wasJmsServer-1.0</feature>
<feature>wmqJmsClient-2.0</feature>
<feature>jms-2.0</feature>
</featureManager>
<!--============================================= -->
<!-- Liberty to TomEE JMS over ActiveMQ Config -->
<!--============================================= -->
<resourceAdapter id="activemq" location="C:\apps\liberty\ActiveMQRAR\activemq-rar-5.16.3.rar">
<properties.activemq ServerUrl="tcp://127.0.0.1:61616"/>
</resourceAdapter>
<jmsQueueConnectionFactory jndiName="jndi/JMS_BASE_QCF">
<properties.activemq serverUrl="tcp://127.0.0.1:61616"/>
</jmsQueueConnectionFactory>
<jmsQueue jndiName="jndi/worklistQueue">
<properties.activemq PhysicalName="jms/worklistQueue"/>
</jmsQueue>
<!--============================================= -->
<!-- Liberty to TomEE JMS over ActiveMQ Config end-->
<!--============================================= -->
My main concern here is the use of createContext() in your notifyListeners method. ActiveMQ "Classic" (i.e. 5.x) doesn't fully support JMS 2 so you can't use the JMSContext API with it. JMS 2 is backwards compatible with JMS 1.1 (which ActiveMQ "Classic" fully supports) so you can still integrate using the ActiveMQ "Classic" JCA RA. You just can't use any APIs which are specific to JMS 2 (e.g. createContext()).

How to connect to IBM MQ from JMS publisher without JNDI properties?

I have been trying to connect to IBM MQ from JMeter JMS publisher. Unable to find corrert "Initial context factory" and "connection factory" values to use without JNDI properties. I have all MQ jars present in LIB folder.
I have the following information-host name - Venus, Port - 21717, Destination Queue name - request.queue,Queue manager - venus.QMGR,channel - venus.server.chl
(no authorization required).
My requirement - To connect to IBM MQ using JMS publisher with above details. But I am not able to sort out on what to give for Provider URL, Initial context factory and connection factory. Can you please help as this has been bugging me for past two weeks and couldn't find a solution yet?
It would be great if you can tell me on where to populate the above values in JMS publisher as well for connecting to IBM MQ.
I have tried with user.classpath=/folder/with/mq/jars as well but it is not working and all jars are in place with JMeter restart still no luck.
Note: I have gone through all sites in these two weeks but couldn't get any luck.
Example configuration steps would be something like:
Add javax.jms-api.-x.x.x jar to JMeter Classpath
Add mq-allclient-x.x.x.x.jar to JMeter Classpath
Add JSR223 Sampler to your Test Plan
Put the following code into "Script" area:
import com.ibm.jms.JMSTextMessage;
import com.ibm.mq.jms.*;
import com.ibm.msg.client.wmq.WMQConstants;
import javax.jms.JMSException;
import javax.jms.Session;
MQQueueConnectionFactory cf = new MQQueueConnectionFactory();
cf.setHostName("your_IBMMQ_host");
cf.setPort(1414); // or other port
cf.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT);
cf.setQueueManager("your_IBMMQ_queue_manager");
cf.setChannel("your_IBMMQ_channel");
cf.setStringProperty(WMQConstants.USERID, "your_IBMMQ_username");
cf.setStringProperty(WMQConstants.PASSWORD, "your_IBMMQ_password");
connection = (MQQueueConnection) cf.createQueueConnection();
MQQueueSession session = (MQQueueSession) connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
MQQueue queue = (MQQueue) session.createQueue("queue:///your_IBMMQ_queue");
MQQueueSender sender = (MQQueueSender) session.createSender(queue);
JMSTextMessage message = (JMSTextMessage) session.createTextMessage("your_message_body");
connection.start();
sender.send(message);
More information:
What is installed for IBM MQ classes for Java
Apache Groovy - Why and How You Should Use It
Simplest sample applications using WebSphere MQ JMS
Depending on your exact requirements, you may be interested by JMSToolBox and its possibility to define scriptsthat will read the payload from csv files stored in a directiory, then create and post them in a MQ Q
as a JMS Message from a message template

How to configure Wildfly JMS connection factory and destination

I have migrated recently from Glassfish 4 to Wildfly 8.1
I have configured JMS Connection Factory and Destination in Glassfish as:
connection factory------------------------------
jndi name: emailConnectionFactory
resource type: javax.jms.QueueConnectionFactory
destination ------------------------------------
jndi name: emailQueue
resource type: javax.jms.Queue
In Wildfly I go to Configuration->Messaging->Destinations->Connection Factories and enter values name and jndi name as above. but it tells me that jndi name must start from 'java:/' or 'java:jboss/'.
I tried to use jndi name as 'java:/ConnectionFactory' and destination and in Configuration->Messaging->Destinations->queue/topics jndi name as 'java:/jms/queue/emailQueue'
but it didnt gave me and exception and didnt send email with previous email setting
Do the same configuration in standalone-full.xml file .
link1
link2
cool. our team is also doing the same thing - migrating a huge glassfish4 app to wildfly.
Keep this in mind,
For connection factory must be prefixed with java:/ or
java:jboss/exported/ (for remote access).
For queues and topics, use the same rule. Any jms-queue or jms-topic which needs to be
accessed by a remote client needs to have an entry in the
"java:jboss/exported" namespace.

Unable to proxy a JBossMQ queue in Spring

Spring JMS going against a JBoss 4.x JBossMQ queue (I know, old JBoss, JBossMQ superseded by JBoss Messaging, but I can't change the stack). Everything works when the Spring JMS configuration is loaded at startup, but when I make the JNDI lookups lazy, so that they are first loaded when I want to send a JMS message, I get the following exception:
org.springframework.jms.InvalidDestinationException: Destination is not an instance of SpyDestination QUEUE.myQueueName; nested exception is javax.jms.InvalidDestinationException: Destination is not an instance of SpyDestination QUEUE.myQueueName
at org.springframework.jms.support.JmsUtils.convertJmsAccessException(JmsUtils.java:285)
My config:
<jee:jndi-lookup id="beanNameForMyQueue"
jndi-name="queue/myQueueName"
resource-ref="true" environment-ref="jndiEnvironment"
lookup-on-startup="false" cache="true" proxy-interface="javax.jms.Queue" />
I found a JBoss JIRA on this, and this similar HornetQ post, but so far no dice.
Am I just out of luck with the lazy init, or is there a workaround?

Spring JMS MQJE001: Completion Code '2', Reason '2042'

My setup is Spring 3 JMS, MVC + Websphere MQ + Websphere 7
<!-- this is the Message Driven POJO (MDP) -->
<bean id="messageListener" class="com.SomeListener" />
<!-- and this is the message listener container -->
<bean id="jmsContainer"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="xxxCF" />
<property name="destination" ref="someQueue" />
<property name="messageListener" ref="messageListener" />
</bean>
When I start up the server, the listener seems to start correctly since it receives the messages that are on the queue as I put them.
However, once I run any simple controller/action that doesn't even have anything to do with JMS it gives me the message below over and over...
DefaultMessag W org.springframework.jms.listener.DefaultMessageListenerContainer handleListenerSetupFailure Setup of JMS message listener invoker failed for destination 'queue:///ABCDEF.EFF.OUT?persistence=-1' - trying to recover. Cause: MQJMS2008: failed to open MQ queue ''.; nested exception is com.ibm.mq.MQException: MQJE001: Completion Code '2', Reason '2042'.
DefaultMessag I org.springframework.jms.listener.DefaultMessageListenerContainer refreshConnectionUntilSuccessful Successfully refreshed JMS Connection
ConnectionEve W J2CA0206W: A connection error occurred. To help determine the problem, enable the Diagnose Connection Usage option on the Connection Factory or Data Source.
ConnectionEve A J2CA0056I: The Connection Manager received a fatal connection error from the Resource Adapter for resource JMS$XXXQCF$JMSManagedConnection#2. The exception is: javax.jms.JMSException: MQJMS2008: failed to open MQ queue ''.
ConnectionEve W J2CA0206W: A connection error occurred. To help determine the problem, enable the Diagnose Connection Usage option on the Connection Factory or Data Source.
ConnectionEve A J2CA0056I: The Connection Manager received a fatal connection error from the Resource Adapter for resource jms/XXXQCF. The exception is: javax.jms.JMSException: MQJMS2008: failed to open MQ queue ''.
The original listener seems to be still running correctly...but I think the controller is somehow triggering off another connection?
Does anyone know what I should check for or what might cause this issue?
thanks
The 2042 means "Object in use". Since there is no concept of exclusive use of queues for message producers, then one of your consumers is locking the queue.
This behavior is controlled by the queue definition's DEFSOPT attribute. This is at the queue manager itself and not in the managed object definitions or your factory options. From the command line while signed on as mqm (or the platform equivalent if the QMgr is on Windows, iSeries, z/OS, etc.) you would need to start runmqsc and issue the following commands to verify and then fix the problem. In my example, the QMgr is PLUTO and the example queue is SYSTEM.DEFAULT.LOCAL.QUEUE.
/home/mqm: runmqsc PLUTO
5724-H72 (C) Copyright IBM Corp. 1994, 2009. ALL RIGHTS RESERVED.
Starting MQSC for queue manager PLUTO.
dis q(system.default.local.queue) defsopt
1 : dis q(system.default.local.queue) defsopt
AMQ8409: Display Queue details.
QUEUE(SYSTEM.DEFAULT.LOCAL.QUEUE) TYPE(QLOCAL)
DEFSOPT(EXCL)
alter ql(system.default.local.queue) defsopt(shared)
2 : alter ql(system.default.local.queue) defsopt(shared)
AMQ8008: WebSphere MQ queue changed.
dis q(system.default.local.queue) defsopt
3 : dis q(system.default.local.queue) defsopt
AMQ8409: Display Queue details.
QUEUE(SYSTEM.DEFAULT.LOCAL.QUEUE) TYPE(QLOCAL)
DEFSOPT(SHARED)
If you display the queue and find that it is already set for DEFSOPT(SHARED) then something must be specifying exclusive use of the queue through the API. That typically means a C or base Java program since these non-JMS APIs have access to low-level WMQ functionality. Those can be a little trickier to diagnose and I usually use a trace or the SupportPac MA0W exit to display the API calls and options used. If this is the case, I'd want to know more about what is meant by "simple controller/action" as noted in the original post.
Finally, if the queue that you are accessing is a remote queue then it will resolve to a transmit queue. The channel will always set a transmit queue to GET(INHIBITED) and acquire an exclusive lock on it. This is consistent with WMQ functionality in that an application can only GET messages from a local queue.

Resources