Spring jms to Websphere MQ connection error - jms

AppConfig.xml settings:
<bean id="connectionFactory" class="com.ibm.mq.jms.MQQueueConnectionFactory">
<property name="hostName" value="abchost.com />
<property name="port" value="1414" />
<property name="queueManager" value="ABC_DEV" />
<property name="transportType" value="1" />
<jms:listener-container acknowledge="transacted">
<jms:listener destination="abc.queue.abc"
ref="someComplexServiceImpl"
method="doSomething" />
</jms:listener-container>
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="connectionFactory" />
<property name="defaultDestinationName" value="abc.queue.abc"/>
</bean>
I get the following errors:
Caused by: com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2035' ('MQRC_NOT_AUTHORIZED').
[9/26/16 13:13:35:758 CST] 000000aa SystemErr R at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:204)
[9/26/16 13:13:35:758 CST] 000000aa SystemErr R ... 98 more
Cause: JMSWMQ2013: The security authentication was not valid that was supplied for QueueManager 'ABC_DEV' with connection mode 'Client' and host name 'abchost.com(1414)'.; nested exception is com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2035' ('MQRC_NOT_AUTHORIZED')
What I like to find out is, is there problem in the codes or in some setting in Websphere MQ we need to configure? I wanna make sure this is not a fault in the program before I raise the problem to our Websphere MQ administrator (who by the way is just new to Websphere MQ)
We are using:
Websphere MQ version 9
Spring JMS Version 4.2.4.RELEASE
I used MQ Client to connect to MQ, and I was able to connect (via command line):
C:\Users\me>set MQSERVER=CH.ABC_DEV/TCP/abchost.com(1414)
C:\Users\me>set MQSAMP_USER_ID=someuser
C:\Users\me>c:\IBM\MQ\Tools\c\Samples\Bin\amqsbcgc.exe abc.queue.abc ABC_DEV
Enter password: p#ssword
--connected!
but why cant the same user work when connecting through WAS?

My application was also not able to connect to MQ although I provided the correct credentials. Enabling the authentication compatibility mode solved the issue.
See also: IBM MQ Connection authentication
If you are using mq-jms-spring-boot-starter you can add this in application.properties:
ibm.mq.userAuthenticationMQCP=false
Internally this will apply this to the connection factory:
cf.setBooleanProperty(WMQConstants.USER_AUTHENTICATION_MQCSP, false);

As the message at the bottom clearly says, the connection attempt was rejected with reason code 2035, not authorized. Your MQ administrator must check the MQ error log on the queue manager side for the specific reason. There are multiple ways of setting up the connection authentication and authorization, you need to consult MQ documentation. Additionally, chances are after setting up the connection authorization the application will fail with 2035 when opening the queue(s), so keep reading.

Related

SpringBoot and IBM MQ connection properties not overrided on deploy

I've a SpringBoot App with a local configuration to connect and listen a local Queue
ibm:
mq:
queueManager: LOCAL_QM
channel: DEV.ADMIN.SVRCONN
connName: localhost(1414)
user: admin
password: passw0rd
user-authentication-m-q-c-s-p: false
When a I deploy the app with Gitlab CI some properties are overrided (with a war_name.xml file in ../tomcat/current/conf/Catalina/localhost/) like database connection properties and mq connection properties to listen a Developpement or Qualification environment queue.
But when the app start the database connection is OK but not the MQ connection (The app use the local connection properties defined in the application.yml file)
When I check the xml file on the remote server, the properties are override.
And when I use a tool like spring actuator, I have the right properties override with the specific env properties.
But in the logs: /tomcat/current/logs/catalina.out I can read that the app try to connect to the local queue manage : LOCAL_QM not the specific environment queue.
2021-05-11 12:19:23.484 ERROR 14483 --- [ntContainer#0-1] o.s.j.l.DefaultMessageListenerContainer : Could not refresh JMS Connection for destination '***' - retrying using FixedBackOff{interval=5000, currentAttempts=16093, maxAttempts=unlimited}. Cause: JMSWMQ0018: Failed to connect to queue manager 'LOCAL_QM' with connection mode 'Client' and host name 'localhost(1414)'.; nested exception is com.ibm.mq.MQException: JMSCMQ0001: IBM MQ call failed with compcode '2' ('MQCC_FAILED') reason '2538' ('MQRC_HOST_NOT_AVAILABLE')
The properties are in the same xml file, it works for the database "spring.datasource" but not for MQ "ibm.mq"
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Environment name="spring.datasource.url" value="jdbc:postgresql://***:5432/**" type="java.lang.String"/>
<Environment name="spring.datasource.username" value="****" type="java.lang.String"/>
<Environment name="spring.datasource.password" value="****" type="java.lang.String"/>
<Environment name="ibm.mq.queueManager" value="***" type="java.lang.String"/>
<Environment name="ibm.mq.channel" value="***" type="java.lang.String"/>
<Environment name="ibm.mq.connName" value="***" type="java.lang.String"/>
<Environment name="ibm.mq.user" value="***" type="java.lang.String"/>
<Environment name="ibm.mq.password" value="" type="java.lang.String"/>
</Context>
Any idea why the properties are not overrided ?
Thanks
This started out as a comment, but as I wrote it I suspected that you are missing the relevant ibm.mq properties. If you don't provide the following properties:
ibm.mq.queueManager
ibm.mq.channel
ibm.mq.connName
ibm.mq.user
ibm.mq.password
then they default to
ibm.mq.queueManager=QM1
ibm.mq.channel=DEV.ADMIN.SVRCONN
ibm.mq.connName=localhost(1414)
ibm.mq.user=admin
ibm.mq.password=passw0rd
ie. localhost.
The mq-jms-spring-boot-starter makes use of
import org.springframework.boot.context.properties.ConfigurationProperties;
#ConfigurationProperties(prefix = "ibm.mq")
to read the connection properties. In this module https://github.com/ibm-messaging/mq-jms-spring/blob/master/mq-jms-spring-boot-starter/src/main/java/com/ibm/mq/spring/boot/MQConfigurationProperties.java
So it relies on spring to make the properties prefixed with ibm.mq available to it. ie. As long as spring through #ConfigurationProperties knows how to handle the overrides it will make them available to mq-jms-spring-boot-starter.

can not get an an MQ MDB to work in Liberty

I have a sample Java program that works. I try to put the same credentials / queue data into the MDB and I get
Caused by: com.ibm.msg.client.jms.DetailedJMSSecurityException: JMSWMQ2013: The security authentication was not valid that was supplied for QueueManager 'QueueMgr1' with connection mode 'Client' and host name 'queuemgr1.....'.
Please check if the supplied username and password are correct on the QueueManager to which you are connecting.
This is happening in Open Liberty and WAS Liberty.
this is my config
<resourceAdapter id="mq" location="/config/wmq.jmsra.rar" />
<jmsActivationSpec id="Messaging/MessagingEJB/MessagingMDB" authDataRef="MQCredentials" maxEndpoints="1">
<properties.mq
transportType="CLIENT"
hostName="${env.MQ_HOST}"
port="${env.MQ_PORT}"
channel="${env.MQ_CHANNEL}"
queueManager="${env.MQ_QUEUE_MANAGER}"
destinationRef="NotificationQ"
destinationType="javax.jms.Queue" />
</jmsActivationSpec>
<jmsQueue id="NotificationQ" jndiName="jms/StockTrader/NotificationQueue">
<properties.mq baseQueueName="${env.MQ_QUEUE}" baseQueueManagerName="${env.MQ_QUEUE_MANAGER}" />
</jmsQueue>

Error using Spring CachingConnectionFactory with Websphere MQ on Websphere Application Server

I am getting the error below when using spring CachingConnectionFactory to connect to Websphere MQ on WAS
org.springframework.jms.IllegalStateException: **Method setExceptionListener not permitted;** nested exception is javax.jms.IllegalStateException: Method setExceptionListener not permitted
at org.springframework.jms.support.JmsUtils.convertJmsAccessException(JmsUtils.java:279) ~[spring-jms-4.1.5.RELEASE.jar:4.1.5.RELEASE]
at org.springframework.jms.support.JmsAccessor.convertJmsAccessException(JmsAccessor.java:169) ~[spring-jms-4.1.5.RELEASE.jar:4.1.5.RELEASE]
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:496) ~[spring-jms-4.1.5.RELEASE.jar:4.1.5.RELEASE]
at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:568) ~[spring-jms-4.1.5.RELEASE.jar:4.1.5.RELEASE]
at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:559) ~[spring-jms-4.1.5.RELEASE.jar:4.1.5.RELEASE]
My configuration looks like -
<jee:jndi-lookup id="jmsConnectionFactory"
jndi-name="jms/XXXCF" />
<bean id="cachedConnectionFactory"
class="org.springframework.jms.connection.CachingConnectionFactory">
<property name="targetConnectionFactory" ref="jmsConnectionFactory"/>
<property name="sessionCacheSize" value="50" />
</bean>
<bean id="jmsResponseTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="cachedConnectionFactory" />
<property name="defaultDestination" ref="XXXQueue" />
</bean>
Does anyone know if I am missing any configuration on spring or WAS side? Thanks in advance.
I'm facing the same kind of problem. After debugging the spring code I found that ibm has trouble with this because of a setting "reconnectOnException"
By adding
< property name="reconnectOnException" value="false" />
to your cachedConnectionFactory. you bypass this problem.
But now of course, after an exception was thrown, I get exceptions like this
Producer closed
org.springframework.jms.IllegalStateException: Session closed;
javax.jms.IllegalStateException: Connection closed
Does anyone have an idea how to get IBM to play nice with the reconnectOnException="true" ?

Error connecting ActiveMQ

I am working on ActiveMQ JMS Spring application. I am using ActiveMQ instance which is present in Cloud server and i trying to read message from queue. In a configuration file i have configured broker URL as
<bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<!-- brokerURL, You may have different IP or port -->
<constructor-arg index="0" value="tcp://ip address:8161" />
</bean>
but when i try to connect it gives me error
Caused by: org.apache.activemq.transport.InactivityIOException: Cannot send, channel has already failed: tcp://ip address:8161
at org.apache.activemq.transport.AbstractInactivityMonitor.doOnewaySend(AbstractInactivityMonitor.java:297)
at org.apache.activemq.transport.AbstractInactivityMonitor.oneway(AbstractInactivityMonitor.java:286)
at org.apache.activemq.transport.TransportFilter.oneway(TransportFilter.java:85)
at org.apache.activemq.transport.WireFormatNegotiator.oneway(WireFormatNegotiator.java:104)
at org.apache.activemq.transport.MutexTransport.oneway(MutexTransport.java:68)
at org.apache.activemq.transport.ResponseCorrelator.asyncRequest(ResponseCorrelator.java:81)
at org.apache.activemq.transport.ResponseCorrelator.request(ResponseCorrelator.java:86)
at org.apache.activemq.ActiveMQConnection.syncSendPacket(ActiveMQConnection.java:1409)
... 21 more
Can you please suggest me is am i missing something here?

Security:090398 Invalid Subject - Spring and weblogic

I am writing a new application using spring and JMS. Myintent is to use Spring's Asynchronous Reception - Message-Driven POJOs. I get the following error.
org.springframework.jms.listener.DefaultMessageListenerContainer.refreshConnectionUntilSuccessful[904] -
Could not refresh JMS Connection for destination
'xyz_Module!xyz_Queue' - retrying in 5000 ms. Cause:
[Security:090398]Invalid Subject: principals=[user, groupa, groupb]
java.lang.SecurityException: [Security:090398]Invalid Subject: principals=[user, groupa, groupb]
I have the following spring definition
<bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
<property name="destination" ref="destination" />
<property name="messageListener" ref="messageAdapter" />
</bean>
<bean id="connectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jms/xxxxx" />
<property name="resourceRef" value="true"></property>
</bean>
<bean id="destination" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jms/yyyyy" />
</bean>
<bean id="messageAdapter" class="org.springframework.jms.listener.adapter.MessageListenerAdapter">
<property name="delegate" ref="messageReceiverDelegate" />
<property name="defaultListenerMethod" value="receive" />
</bean>
I read in several posts that we have to enable cross domain security. I was not convinced that we need to enable Cross Domain Security because several other applications in my company that are MDBs are working just fine by reading from a remote queue. These applications do not have cross domain security enabled in their weblogic servers.
I spent some time digging and by some fortune I discovered that if I restarted the weblogic servers after I deployed my application, I don't see the security error anymore. I am able to get notified of the message in the remote queue.
Although my problem is solved, I am curious to know why I get the error if I just deploy the app and not restart the JVM.
Adding more log information
12/15/2014 08:58:15,079PM ERROR org.springframework.jms.listener.DefaultMessageListenerContainer.refreshConnectionUntilSuccessful[904] -
Could not refresh JMS Connection for destination 'XXXXXXXXXXXXXXXXXXXXX' - retrying in 5000 ms. Cause: [Security:090398]Invalid Subject: principals=[weblogic, Administrators, super_users]
java.lang.SecurityException: **[Security:090398]**Invalid Subject: principals=[weblogic, Administrators, super_users]
at weblogic.rjvm.ResponseImpl.unmarshalReturn(ResponseImpl.java:234)
at weblogic.rmi.cluster.ClusterableRemoteRef.invoke(ClusterableRemoteRef.java:348)
at weblogic.rmi.cluster.ClusterableRemoteRef.invoke(ClusterableRemoteRef.java:259)
at weblogic.jms.frontend.FEConnectionFactoryImpl_1034_WLStub.connectionCreateRequest(Unknown Source)
at weblogic.jms.client.JMSConnectionFactory.setupJMSConnection(JMSConnectionFactory.java:224)
at weblogic.jms.client.JMSConnectionFactory.createConnectionInternal(JMSConnectionFactory.java:285)
at weblogic.jms.client.JMSConnectionFactory.createConnection(JMSConnectionFactory.java:191)
at org.springframework.jms.support.JmsAccessor.createConnection(JmsAccessor.java:184)
at org.springframework.jms.listener.AbstractJmsListeningContainer.createSharedConnection(AbstractJmsListeningContainer.java:405)
at org.springframework.jms.listener.AbstractJmsListeningContainer.refreshSharedConnection(AbstractJmsListeningContainer.java:390)
at org.springframework.jms.listener.DefaultMessageListenerContainer.refreshConnectionUntilSuccessful(DefaultMessageListenerContainer.java:885)
at org.springframework.jms.listener.DefaultMessageListenerContainer.recoverAfterListenerSetupFailure(DefaultMessageListenerContainer.java:861)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1012)
at java.lang.Thread.run(Thread.java:662)
Caused by: java.lang.SecurityException: [Security:090398]Invalid Subject: principals=[weblogic, Administrators, super_users]
at weblogic.security.service.SecurityServiceManager.seal(SecurityServiceManager.java:833)
at weblogic.security.service.SecurityServiceManager.getSealedSubjectFromWire(SecurityServiceManager.java:522)
at weblogic.rjvm.MsgAbbrevInputStream.getSubject(MsgAbbrevInputStream.java:349)
at weblogic.rmi.internal.BasicServerRef.acceptRequest(BasicServerRef.java:953)
at weblogic.rmi.internal.BasicServerRef.dispatch(BasicServerRef.java:351)
at weblogic.rmi.cluster.ClusterableServerRef.dispatch(ClusterableServerRef.java:243)
at weblogic.rjvm.RJVMImpl.dispatchRequest(RJVMImpl.java:1141)
at weblogic.rjvm.RJVMImpl.dispatch(RJVMImpl.java:1023)
at weblogic.rjvm.ConnectionManagerServer.handleRJVM(ConnectionManagerServer.java:240)
at weblogic.rjvm.ConnectionManager.dispatch(ConnectionManager.java:888)
at weblogic.rjvm.MsgAbbrevJVMConnection.dispatch(MsgAbbrevJVMConnection.java:512)
at weblogic.rjvm.t3.MuxableSocketT3.dispatch(MuxableSocketT3.java:330)
at weblogic.socket.BaseAbstractMuxableSocket.dispatch(BaseAbstractMuxableSocket.java:298)
at weblogic.socket.SocketMuxer.readReadySocketOnce(SocketMuxer.java:950)
at weblogic.socket.SocketMuxer.readReadySocket(SocketMuxer.java:898)
at weblogic.socket.EPollSocketMuxer.dataReceived(EPollSocketMuxer.java:215)
at weblogic.socket.EPollSocketMuxer.processSockets(EPollSocketMuxer.java:177)
at weblogic.socket.SocketReaderRequest.run(SocketReaderRequest.java:29)
at weblogic.socket.SocketReaderRequest.execute(SocketReaderRequest.java:43)
at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:145)
at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:117)
12/15/2014 08:58:20,095PM DEBUG org.springframework.jms.listener.DefaultMessageListenerContainer.shutdown[211] - Shutting down JMS listener container
12/15/2014 08:58:20,095PM DEBUG org.springframework.jms.listener.DefaultMessageListenerContainer.doShutdown[534] - Waiting for shutdown of message listener invokers
12/15/2014 08:58:20,111PM DEBUG org.springframework.jms.listener.DefaultMessageListenerContainer.shutdown[211] - Shutting down JMS listener container
12/15/2014 08:58:20,111PM DEBUG org.springframework.jms.listener.DefaultMessageListenerContainer.doShutdown[534] - Waiting for shutdown of message listener invokers
12/15/2014 08:58:55,595PM DEBUG org.springframework.jms.listener.DefaultMessageListenerContainer.establishSharedConnection[374] - Established shared JMS Connection
12/15/2014 08:58:55,611PM DEBUG org.springframework.jms.listener.DefaultMessageListenerContainer.resumePausedTasks[541] - Resumed paused task: org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker#189f205
12/15/2014 08:58:55,642PM DEBUG org.springframework.jms.listener.DefaultMessageListenerContainer.establishSharedConnection[374] - Established shared JMS Connection
12/15/2014 08:58:55,642PM DEBUG org.springframework.jms.listener.DefaultMessageListenerContainer.resumePausedTasks[541] - Resumed paused task: org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker#18fd51b
12/15/2014 08:59:52,740PM DEBUG org.springframework.jms.listener.DefaultMessageListenerContainer.doReceiveAndExecute[313] - Received message of type [class weblogic.jms.common.TextMessageImpl] from consumer [weblogic.jms.client.WLConsumerImpl#2506f03] of session [weblogic.jms.client.WLSessionImpl#2506efd]
if you look at the logs you will see that I restarted the server and when the server came up it consumed the message # 08:58:55
Either we will have to enable cross domain security or you will have to restart the JVM
You can authenticate a subject for each weblogic services.
More information https://github.com/dmacdonald2013/weblogic-jms-spring
import weblogic.jndi.Environment;
import weblogic.security.auth.Authenticate;
import javax.security.auth.Subject;
for(JmsComponentConfig config : this.config.jmsComponents()){
Environment environment = new Environment();
environment.setProviderUrl(config.url());
environment.setSecurityPrincipal(config.username());
environment.setSecurityCredentials(config.password());
Subject subject = new Subject();
Authenticate.authenticate(environment, subject);
}

Resources