MQ-7 connectivity issue - java

Hi below is the code I used to check the connectivity
String qManager="";
int openOptions = CMQC.MQOO_FAIL_IF_QUIESCING + CMQC.MQOO_INPUT_SHARED + CMQC.MQOO_INQUIRE+CMQC.MQOO_BROWSE;
try{
Hashtable props = new Hashtable();
props.put(CMQC.HOST_NAME_PROPERTY, "IP");
props.put(CMQC.PORT_PROPERTY, port_num);
props.put(CMQC.CHANNEL_PROPERTY, "SYSTEM.DEFAULT.LOCAL.QUEUE");
MQQueueManager qMgr = new MQQueueManager("QM", props);
MQQueue destQueue = qMgr.accessQueue("Q_name", openOptions);
System.out.println("Connected");
destQueue.close();
qMgr.disconnect();
}catch(MQException mqe){
System.out.println(mqe.reasonCode);
}
}
}
When I run the program I get this Exception
MQJE001: An MQException occurred: Completion Code 2, Reason 2009
MQJE016: MQ queue manager closed channel immediately during connect
2009
Closure reason = 2009
MQJE001: Completion Code 2, Reason 2009
Kindly help me

There are 2 things I suspect here:
props.put(CMQC.HOST_NAME_PROPERTY, "IP"); <-- Is the hostname so short?
props.put(CMQC.CHANNEL_PROPERTY, "SYSTEM.DEFAULT.LOCAL.QUEUE"); <-- Why is the local queue name set as channel property
There are some samples in the "tools" folder of MQ installation, that can help you.

I got this error bcoz in IBM Websphere MQ-7 the channel security was enabled. After Disabling the channel security i was able to connect it

Related

IBM MQ listener using JMS in a JVM cluster

I have setup a JMS listener for IBM MQ . When the listener is running on single JVM like tomcat on local machine it runs fine. But when i deploy it to the Cloud where there are 2 VM's , it's running fine on one of the VM and connects to MQ but it says below on the other one.
Is there any limitation from IBM MQ on using a ID,password from multiple clients in order to connect to the Queue manager?
RROR> com.ssc.ach.mq.JMSMQReceiver[main]: errorMQJMS2013: invalid security authentication supplied for MQQueueManager
javax.jms.JMSSecurityException: MQJMS2013: invalid security authentication supplied for MQQueueManager
at com.ibm.mq.jms.MQConnection.createQM(MQConnection.java:2050)
at com.ibm.mq.jms.MQConnection.createQMNonXA(MQConnection.java:1532)
at com.ibm.mq.jms.MQQueueConnection.<init>(MQQueueConnection.java:150)
at com.ibm.mq.jms.MQQueueConnectionFactory.createQueueConnection(MQQueueConnectionFactory.java:185)
at com.ibm.mq.jms.MQQueueConnectionFactory.createConnection(MQQueueConnectionFactory.java:1066)
at
I am starting the listener on VM startup using Servlet init method
public void init(ServletConfig config) throws ServletException {
logger.info("App Init");
try {
boolean isListnerOn = Boolean.parseBoolean(System.getProperty("listner", "false"));
logger.info(" startReceiver , listner flag is "+isListnerOn);
if(isListnerOn){
if (mqReceive == null) {
MyMessageListener jmsListner = new MyMessageListener();
mqReceive = new JMSMQReceiver(jmsListner);
}
if (mqReceive != null) {
try{
mqReceive.start();
} catch (Exception e) {
logger.error("Error starting the listner ", e);
}
}
}else{
logger.info(" listner not started as flag is "+isListnerOn);
}
} catch (Exception e) {
logger.error(e, e);
}
}
private MQQueueConnectionFactory mqQueueConnectionFactory;
public MQReceiver(MyMessageListener listner) {
userName=System.getProperty( "mqId","");
pwd=System.getProperty("mqId","");
host = System.getProperty(PREFIX + ".host");
port = Integer.parseInt(System.getProperty(PREFIX + ".port"));
qManager = System.getProperty(PREFIX + ".qManager");
channel = System.getProperty(PREFIX + ".channel");
queueName = System.getProperty(PREFIX + ".achqueueName");
logger.info("HOST:" + host + "\tPORT:" + port + "\tqManager:"+ qManager + "\tchannel:" + channel + "\tqueueName:"+ queueName);
try {
mqQueueConnectionFactory = new MQQueueConnectionFactory();
mqQueueConnectionFactory.setHostName(host);
mqQueueConnectionFactory.setChannel(channel);//communications link
mqQueueConnectionFactory.setPort(port);
mqQueueConnectionFactory.setQueueManager(qManager);//service provider
mqQueueConnectionFactory.setTransportType(JMSC.MQJMS_TP_CLIENT_MQ_TCPIP);
queueConnection = mqQueueConnectionFactory.createConnection(trustUserName, trustID);
session = queueConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
queue = session.createQueue(queueName);
((MQDestination) queue).setTargetClient(WMQConstants.WMQ_CLIENT_NONJMS_MQ);
MessageConsumer consumer = session.createConsumer(queue);
consumer.setMessageListener(listner);
logger.info(" Connect MQ successfully.");
} catch (JMSException e) {
logger.error("error" + e.getMessage(), e);
}
}
public void start() {
logger.info("Starting MQListener... ");
//mqListener.start();
try {
queueConnection.start();
logger.info("MQListener start successfully");
} catch (JMSException e) {
logger.error("error" + e.getMessage(), e);
}
}
The IBM MQ Classes for JMS client error JMSWMQ2013 can be caused by quite a few issues.
IBM Support Technote "WMQ 7.1 / 7.5 / 8.0 / 9.0 queue manager RC 2035 MQRC_NOT_AUTHORIZED or AMQ4036 or JMSWMQ2013 when using client connection as an MQ Administrator" has a good write up on diagnosing and resolving issues like this.
If you want more specific help, to start with please provide the following details by editing and adding them to your question.
Version of IBM MQ Classes for JMS used by the client application.
Version of IBM MQ installed on the IBM MQ queue manager
Errors in the queue manager's AMQERR01.LOG that happen at the same time as the error you receive in the IBM MQ Classes for JMS client application on the second VM..
It is strange that it works on the first VM and fails on the second. If the trustUserName, trustID are the same for both VMs, IBM MQ should accept them equally.
If you are using IBM MQ v8 or later native connection authentication it is possible the OS or PAM is denying the second connection. I have only seen this where pam_tally had a limit of 5 and more than 5 connection hit at the same time. It could be possible there is some sort of login limit of one login per user.
Per you comment it appears that you had a CHLAUTH ADDRESSMAP rule missing, the first VM's IP was allowed and the second VM's IP was not allowed. Depending on how the queue manager is configured and how the CHLAUTH rule is blocking the connection the queue manager may return MQRC 2035 to the client. On a IBM MQ Classes for JMS client this is returned as MQJMS2013. This could happen for instance if your queue manager is using ADOPTCTX(NO) and has a CHLAUTH rule that maps ADDRESS(*) to a MCAUSER that does not exist (ex: *NOACCESS) and other CHLAUTH rules that map connections from specific IPs to a user that does have access.
A more secure setup is to use ADOPTCTX(YES) which will tell MQ to set the MCAUSER to the id that is authenticated by CONNAUTH. You could also have a ADDRESSMAP rule with ADDRESS(*) USERSRC(NOACCESS) to block by default and then other rules with specific IPs and USERSRC(CHANNEL to allow those IPs you want to whitelist.
com.ssc.ach.mq.JMSMQReceiver[main]: errorMQJMS2013: invalid security authentication supplied for MQQueueManager
javax.jms.JMSSecurityException: MQJMS2013: invalid security authentication supplied for MQQueueManager
Is because:
queueConnection = mqQueueConnectionFactory.createConnection(trustUserName, trustID);
If you don't supply a valid UserId and Password that can be authenticated by the queue manager then your connection will rejected. I have no idea what you are passing into the method but it is supposed to be a valid UserId and Password for the remote system.
Also, I wish people would stop using the term 'MQ Listener' because you are not creating an 'MQ Listener', you are creating a consumer that is receiving messages.
An MQ listener is a component of MQ that accepts and handles incoming connections. See here.

Why do I get a MQRC_NOT_AUTHORIZED error when trying to get channel information using PCF?

I am using MQ Java PCF API to retrieve information from an MQ installation. There are several constructors for the class PCFMessageAgent. There is one that accepts the host, port and channel name. I have shown an extract from the documentation.
public PCFMessageAgent(String host,
int port,
String channel)
throws MQException
Initialises a new PCFMessageAgent with a client connection to a queue manager.
The code I have is
PCFMessageAgent agent = new PCFMessageAgent(host, port, "SYSTEM.DEF.SVRCONN");
PCFMessage pcfCmd = new PCFMessage(MQConstants.MQCMD_INQUIRE_CHANNEL);
pcfCmd.addParameter(MQConstants.MQCACH_CHANNEL_NAME, channelName);
PCFMessage[] pcfResponse = agent.send(pcfCmd);
but I get a MQRC_NOT_AUTHORIZED error
Exception in thread "main" com.ibm.mq.MQException: MQJE001: Completion Code '2', Reason '2035'.
at com.ibm.mq.MQManagedConnectionJ11.<init>(MQManagedConnectionJ11.java:249)
at com.ibm.mq.MQClientManagedConnectionFactoryJ11._createManagedConnection(MQClientManagedConnectionFactoryJ11.java:450)
at com.ibm.mq.MQClientManagedConnectionFactoryJ11.createManagedConnection(MQClientManagedConnectionFactoryJ11.java:487)
at com.ibm.mq.StoredManagedConnection.<init>(StoredManagedConnection.java:97)
at com.ibm.mq.MQSimpleConnectionManager.allocateConnection(MQSimpleConnectionManager.java:194)
at com.ibm.mq.MQQueueManagerFactory.obtainBaseMQQueueManager(MQQueueManagerFactory.java:868)
Why do I get this error? How do I fix this.
I found this in the error logs. Any help will be much appreciated.
07/08/17 15:42:51 - Process(3294.15) User(user1) Program(amqrmppa)
Host(ubuntuvm-2) Installation(Installation1)
VRMF(8.0.0.7) QMgr(QM_FR2_2)
AMQ9777: Channel was blocked
EXPLANATION:
The inbound channel 'SYSTEM.DEF.SVRCONN' was blocked from address
'192.168.56.101' because the active values of the channel matched a record
configured with USERSRC(NOACCESS). The active values of the channel were
'CLNTUSER(user1)'.
ACTION:
Contact the systems administrator, who should examine the channel
authentication records to ensure that the correct settings have been
configured. The ALTER QMGR CHLAUTH switch is used to control whether channel
authentication records are used. The command DISPLAY CHLAUTH can be used to
query the channel authentication records.
----- cmqxrmsa.c : 1462 -------------------------------------------------------
07/08/17 15:42:51 - Process(3294.15) User(user1) Program(amqrmppa)
Host(ubuntuvm-2) Installation(Installation1)
VRMF(8.0.0.7) QMgr(QM_FR2_2)
AMQ9999: Channel 'SYSTEM.DEF.SVRCONN' to host '192.168.56.101' ended
abnormally.
EXPLANATION:
The channel program running under process ID 3294 for channel
'SYSTEM.DEF.SVRCONN' ended abnormally. The host name is '192.168.56.101'; in
some cases the host name cannot be determined and so is shown as '????'.
ACTION:
Look at previous error messages for the channel program in the error logs to
determine the cause of the failure. Note that this message can be excluded
completely or suppressed by tuning the "ExcludeMessage" or "SuppressMessage"
attributes under the "QMErrorLog" stanza in qm.ini. Further information can be
found in the System Administration Guide.
----- amqrmrsa.c : 930 --------------------------------------------------------
The issue is that you are attempting to connect to the channel SYSTEM.DEV.SVRCONN. By default there is a CHLAUTH rule that blocks access to channels named SYSTEM.*.
You can create a new SVRCONN channel that does not have a name that starts with SYSTEM and it would get past this check.

No response when using IBM MQ client jars in application to connect to IBM MQ server

The application I am working on needs to communicate to an IBM MQ server in a remote location. We currently have a working system using active MQ which uses a broker, and a bridge to connect to this remote IBM MQ server and is working fine.
Due to some new enhancement, we are now trying to achieve the same using IBM client jars instead of Active MQ.
The problem I am facing is that I can connect to the remote server's inboundQ and send messages.But I am always receiving null from the remote servers outbound Queue. But I have no way to check if the messages are received at the remote location. But the same message if sending through the old ActiveMQ system will get a response from remote MQ server.
Old Active MQ internally uses the bridge to connect to remote IBM MQ server which is configured exactly like the new code I am using.
I have tried multiple codes from internet and stack overflow itself and always I am able to connect but not getting any responses.
Also, I get no errors or exceptions while trying to send or receive from remote IBM MQ.
I will paste a sample code which I am trying to get to work. I have changed some configuration values in the code.
My doubts are the following.
All I am doing for this is copying IBM MQ client jars into the application and using the code to send messages to remote MQ. I have not installed any other application. Will such a system work or should there always be some intermediate program like active MQ?
The same code is able to send and receive from an IBM MQ server which I installed in our local network but fails to get a response from the remote server? This leads me to believe if I am missing anything in configuration ? should anything else be configured other than in code?
I see no errors or exceptions. Always message is sent but the response is null. I have not seen the usage of any username-password or public-private key authentication. Is there any authentication used normally to check the source. ?
I am using IBM MQ client 5.3 version which I know is old. But used that since they working active MQ setup uses the same and is working correctly. I have no way of knowing which version on IBM MQ server is present on the remote machine. Is there a problem if we use a different client MQ version than the version of server MQ version. ?
Sample code which works for me in local environment ie is able to send and receive from an IBM MQ server I have installed in another machine in the local network. The same code will fetch null response when I am trying to use it with remote IBM MQ server.
import javax.jms.*;
import javax.jms.JMSException;
import com.ibm.mq.jms.*;
import com.ibm.jms.JMSMessage;
import javax.jms.TextMessage;
public class SendReceive {
private MQQueueConnectionFactory connectionFactory;
private MQQueueConnection connection;
private void runTest() {
try {
connect();
connection.start();
MQQueueSession session = (MQQueueSession) connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
MQQueue queue = (MQQueue) session.createQueue("INBOUND_QUEUE"); /* values replaced with correct values in deployment server */
MQQueue queue2 = (MQQueue) session.createQueue("OUTBOUND_QUEUE"); /* values replaced with correct values in deployment server */
MQQueueSender sender = (MQQueueSender) session.createSender(queue);
MQQueueReceiver receiver = (MQQueueReceiver) session.createReceiver(queue2);
//TextMessage message = session.createTextMessage("yesyesyes");
String stt = "Test Message"; //
TextMessage message = session.createTextMessage(stt);
message.setJMSReplyTo(queue2);
sender.send(message);
System.out.println("Sent: " + message);
Message msg1 = receiver.receive(5000);
if(msg1!=null){
String responseMsg = ((TextMessage) msg1).getText();
System.out.println("Received: " + responseMsg);
}else{
System.out.println("Message received is null");
}
}catch(Exception e){
System.out.println("Exception caught in program : " + e);
e.printStackTrace();
}
}
public boolean connect() {
boolean connected = false;
try {
/* values below are replaced with correct values in deployment server */
connectionFactory = new MQQueueConnectionFactory();
connectionFactory.setPort(1515);
connectionFactory.setHostName("192.168.1.23"); //
connectionFactory.setQueueManager("QCCMGR");
connectionFactory.setChannel("QCHANNEL");
connectionFactory.setTransportType(JMSC.MQJMS_TP_CLIENT_MQ_TCPIP);
connection = (MQQueueConnection) connectionFactory.createQueueConnection();
connected = true;
} catch (Exception e) {
connected = false;
}
return connected;
}
public static void main(String[] args) {
new SendReceive().runTest();
}
}
MQ v5.3 was released November 29th 2002 and has been out of support since September 28th 2007 (almost 9 years). The version may not have anything to do with your issue but I would strongly suggest that you move to a supported version of the MQ client. Newer MQ client versions can connect to older MQ queue managers. You can download a java only install of MQ 8.0 or MQ 9.0 jar files at the links below:
IBM MQ v8.0 Client
IBM MQ v9.0 Client
I read on some old threads that having the sender and receiver on the same session caused problems when a timeout was specified. Try adding another session for the receiver.
private void runTest() {
try {
connect();
connection.start();
MQQueueSession session = (MQQueueSession) connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
MQQueueSession session2 = (MQQueueSession) connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
MQQueue queue = (MQQueue) session.createQueue("INBOUND_QUEUE"); /* values replaced with correct values in deployment server */
MQQueue queue2 = (MQQueue) session2.createQueue("OUTBOUND_QUEUE"); /* values replaced with correct values in deployment server */
MQQueueSender sender = (MQQueueSender) session.createSender(queue);
MQQueueReceiver receiver = (MQQueueReceiver) session2.createReceiver(queue2);
//TextMessage message = session.createTextMessage("yesyesyes");
String stt = "Test Message"; //
TextMessage message = session.createTextMessage(stt);
message.setJMSReplyTo(queue2);
sender.send(message);
System.out.println("Sent: " + message);
Message msg1 = receiver.receive(5000);
if(msg1!=null){
String responseMsg = ((TextMessage) msg1).getText();
System.out.println("Received: " + responseMsg);
}else{
System.out.println("Message received is null");
}
}catch(Exception e){
System.out.println("Exception caught in program : " + e);
e.printStackTrace();
}
}
Try taking a JMS trace by adding the following to the execution of the java app:
-DMQJMS_TRACE_LEVEL=base
-DMQJMS_TRACE_DIR=/tracedirectory
ex: java -DMQJMS_TRACE_LEVEL=base -DMQJMS_TRACE_DIR=/tracedirectory JavaApp
This should produce a file that I believe ends in .trc in the directory you specify.
You can review this for errors that might help point you in the right direction.
Suggestions:
Try changing your program to force it to send a blank username:
connection = (MQQueueConnection) connectionFactory.createQueueConnection("", "");
Try closing the sender after sender.send is called
sender.close();
With out further information it is difficult to determine the cause. The more information you can gather the better.
It could be some network related configuration issue or maybe Windows Messaging not configured well. You may consider giving WebSphere MQ - Message Test Utility by IBM to ensure that there are no such system or network configuration issues are present.

.JSchException: Packet corrupt

I am using Jsch 0.1.51 on RHEl 6 with Jdk 1.7_51. While making session to a remote machine I am getting exception that is :
com.jcraft.jsch.JSchException: Packet corrupt
at com.jcraft.jsch.Session.start_discard(Session.java:1049)
at com.jcraft.jsch.Session.read(Session.java:919)
at com.jcraft.jsch.UserAuthNone.start(UserAuthNone.java:56)
at com.jcraft.jsch.Session.connect(Session.java:389)
at com.jcraft.jsch.Session.connect(Session.java:183)
at TestSFTP.checkException(TestSFTP.java:130)
at TestSFTP.moveFileToDir(TestSFTP.java:78)
at TestSFTP.main(TestSFTP.java:73)
Same code was working fine with RHEL 5. Can any body provide some suggestions .. Thanks
code used is :
Session session = null;
ChannelSftp channelSftp = null;
JSch jsch = new JSch();
session = jsch.getSession(this.sftpUser,this.sftpHost,this.sftpPort);
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.setPassword(this.sftpPassword);
session.connect();
channelSftp = (ChannelSftp)session.openChannel("sftp");
channelSftp.connect();
I am getting error at session.connect();
This exception can occur if you are trying to connect on an already existent session. A work around is closing the session and then starting a new session. This helped me. Found some help from this site:
http://flyingjxswithjava.blogspot.com/2015/03/comjcraftjschjschexception-packet.html
Quoting essential points from the site to understand the problem:
This exception occurs when the Session is reused repeatedly in a loop where the session is disconnected intentionally or due to time out and needs to reconnect again.
The reason that such an exception is thrown is that the first time the Session is connected to the remote site, a random number called Packet is generated for the session.
When the thread is having its 1 hour sleep, the session gets automatically disconnected due to no activity for a certain period of time.
When the Session is disconnected, the Packet is lost.
When the Session is trying to reconnect, it could not find the Packet, thus the exception is thrown.

How to access Queue for MQ7?

qMgr = new MQQueueManager(qManager);
int openOptions = MQC.MQOO_INPUT_AS_Q_DEF
| MQC.MQOO_OUTPUT | MQC.MQOO_INQUIRE;
*queue = qMgr.accessQueue(queueName, openOptions);* //Here i need to change it for MQ7, as for Mq7 their is no Queue Manager Name.
System.out.println("Successfully registered");
Hi all,
I need to monitor the queue for IBM MQ7.. Currently we did for MQ6, but for MQ7 their no Queue Manager name and 'm stuck with this. Can anyone help me
I think I have understood your question:
First be clear that you can not connect to something that does not exist whether it is a server or anything. To connect an object that object must exist.
The same case applies to MQ also. To connect to a queue manager, that queue manager must be existing and running.
Coming to the snippet you mention: MQ Java API does not have a MQQueueManager constructor that does not take a queue manager name parameter. So queue manager name parameter is mandatory and not optional. But you can pass "" (blank) as the name of the queue manager to MQQueueManager constructor. In such a case the application will connect to a queue manager based on the host, port and channel parameters. So you must pass at least host, port and channel parameters.
Hope I have answered your question.
EDIT Sample Code
// Create a connection to the QueueManager
qManager = "";
System.out.println("Connecting to queue manager: " + qManager);
Hashtable props = new Hashtable();
// Change the host name to your host name. Leave it as it is if
// queue manager is on the same machine
props.put(CMQC.HOST_NAME_PROPERTY, "localhost");
props.put(CMQC.PORT_PROPERTY, 1414);
props.put(CMQC.CHANNEL_PROPERTY, "SYSTEM.DEF.SVRCONN");
MQQueueManager qMgr = new MQQueueManager(qManager, props);

Categories

Resources