I am trying to connect to the MQ7 Server below is the code :
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, serverConfig.server);
props.put(CMQC.PORT_PROPERTY, serverConfig.port);
props.put(CMQC.CHANNEL_PROPERTY, serverConfig.sChannel);
qMgr = new MQQueueManager(qManager, props);
System.out.println("Queue Manager : "+qMgr+" null");
int openOptions = MQC.MQOO_INPUT_AS_Q_DEF
| MQC.MQOO_OUTPUT | MQC.MQOO_INQUIRE;
queue = qMgr.accessQueue(queueName, openOptions);
System.out.println("Successfully registered");
//creating msg
message = new MQMessage();
it's getting connected but after sending one message its throwing a error
" MQJE001: Completion Code '1', Reason '2068'.
com.ibm.mq.MQException: MQJE001: Completion Code '1', Reason '2068'.
strngError: No valid counters.
strngError: No valid counters.
at com.ibm.mq.MQManagedObject.inquire(MQManagedObject.java:269)
at com.ibm.mq.MQManagedObject.getInt(MQManagedObject.java:479)
at com.ibm.mq.MQQueue.getCurrentDepth(MQQueue.java:995)
at middlewarex.IBMmq.getQueueCount(IBMmq.java:227)
at middlewarex.ThreadScenario.run(ThreadScenario.java:94)
at java.lang.Thread.run(Thread.java:722)
pointing on the line
" public long getQueueCount() throws Exception{
return queue.getCurrentDepth();
} "
Kindly Help me
Did you look up Reason Code 2068 in the manual? Because if you did, you would have seen that using option MQOO_INQUIRE is invalid.
Secondly, why are you opening the queue for BOTH putting and getting messages? This is a VERY bad practice. You say you are sending (putting) a message to a queue, therefore, you should be opening the queue for output only.
Due to firewall I was facing the exception when sending the message. Please try telnet and check whether the firewall is blocking you from accessing the machine.
Related
I have a IBM MQ version 7.5 installation in windows 7. I have created a queue manager, channel and listener using the following commands.
//CREATE THE QUEUE MANAGER
crtmqm.exe PG3RT1
//START THE QUEUE MANAGER AS INTERACTIVE
strmqm.exe -si PG3RT1
//CONNECT AS SCRIPT CONSOLE
runmqsc.exe PG3RT1
//CREATE THE CHANNEL TO APPLICATION CONNECTIVITY
DEFINE CHANNEL(PG3RT1.CHANNEL) CHLTYPE(SVRCONN) TRPTYPE(TCP)
//CREATE THE LISTENER
DEFINE LISTENER(LISTENER.PG3RT1) TRPTYPE(TCP) PORT(1414)
//START THE LISTENER
START LISTENER(LISTENER.PG3RT1)
Now i am trying to connect to the Queue Manager using following java client.
connection is rejected with the following error.
15:06:52.175 [localhost-startStop-1] ERROR c.b.c.s.s.m.MQUtil - MQJE001: Completion Code '2', Reason '2035'.
com.ibm.mq.MQException: MQJE001: Completion Code '2', Reason '2035'.
at com.ibm.mq.MQManagedConnectionJ11.<init>(MQManagedConnectionJ11.java:230)
at com.ibm.mq.MQClientManagedConnectionFactoryJ11._createManagedConnection(MQClientManagedConnectionFactoryJ11.java:553)
at com.ibm.mq.MQClientManagedConnectionFactoryJ11.createManagedConnection(MQClientManagedConnectionFactoryJ11.java:593)
at com.ibm.mq.StoredManagedConnection.<init>(StoredManagedConnection.java:96)
at com.ibm.mq.MQSimpleConnectionManager.allocateConnection(MQSimpleConnectionManager.java:198)
at com.ibm.mq.MQQueueManagerFactory.obtainBaseMQQueueManager(MQQueueManagerFactory.java:893)
at com.ibm.mq.MQQueueManagerFactory.procure(MQQueueManagerFactory.java:780)
at com.ibm.mq.MQQueueManagerFactory.constructQueueManager(MQQueueManagerFactory.java:729)
at com.ibm.mq.MQQueueManagerFactory.createQueueManager(MQQueueManagerFactory.java:177)
at com.ibm.mq.MQQueueManager.<init>(MQQueueManager.java:745)
at com.bcs.cas.sach.simulator.mq.MQUtil.init(MQUtil.java:52)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
Can anyone advise why the connection is failing.
Do i need to enable remote administration on the queue manager?
Following is the code fragement i used for connection
public void init(){
MQEnvironment.hostname = hostName;
MQEnvironment.port = Integer.valueOf(port);
MQEnvironment.channel = serverChannelName;
MQEnvironment.properties.put(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES);
LOGGER.info("queueManagerName: " + queueManagerName);
LOGGER.info("hostName: " + hostName);
LOGGER.info("serverChannelName: " + serverChannelName);
LOGGER.info("port: " + port);
//initialize the connection pool
MQPoolToken token = MQEnvironment.addConnectionPoolToken();
try {
mqQueueManager = new MQQueueManager(queueManagerName, MQEnvironment.properties);
LOGGER.info("mqQueueManager: " + mqQueueManager);
} catch (MQException e) {
LOGGER.error(e.getMessage(), e);
}
}
MQRC 2035 is MQRC_NOT_AUTHORIZED. The reason this was returned can be found in the AMQERR log on the queue manager.
As CHLAUTH hasn't been configured, and is on by default, I expect you're not able to connect as you're not passing the CHLAUTH rules.
It is quite likely that this is an authorization issue. The easiest is to look at the return code and interpret
mqrc 2035 returns MQRC_NOT_AUTHORIZED
One of the reasons for it could be permissions. This can be resolved either by setting the right privilges on the QueueManager (setmqaut) , then on the channel enable the user with you are connecting to MQ to authorize as explained here . Post this you can use the code to connect by adding userId to the MQEnvironment and go
You can also refer this technote for information.
We are using clearing the authentication setting on manager by runmqsc:
SET CHLAUTH('CNL_NAME') TYPE(BLOCKUSER) USERLIST(ALLOWANY)
ALTER QMGR CONNAUTH(' ')
REFRESH SECURITY TYPE(CONNAUTH)
in case of development. Or proper setting of credentials:
QueueConnectionFactory.createQueueConnection(props.get(PROP.USER), props.get(PROP.PASSWD));
for JMS or:
...
MQEnvironment.userID = uid;
MQEnvironment.password = passwd;
new MQQueueManager(isQueueMgr);
for native com.ibm.mq.MQQueueManager.
I am Migrating from Mq version 7.0 to 7.5 . I am able to receive messages through the inbound queues using ejb - Message Driven Beans(MDBs) but while posting the message after processing it on the. I am getting the IBM MQRC 2082 MQRC_UNKOWN_ALIAS_BASE_Q Exception.
This is the exception that I am getting :
Caused by: javax.jms.InvalidDestinationException: MQJMS2008: failed to
open MQ queue 'OFS.TIG_IND2NSE_MSG'.
at com.ibm.msg.client.wmq.v6.jms.internal.MQQueueServices.getQueueOpenException(MQQueueServices.java:901)
at com.ibm.msg.client.wmq.v6.jms.internal.MQQueueServices.getOutputQueue(MQQueueServices.java:727)
at com.ibm.msg.client.wmq.v6.jms.internal.JMSServicesMgr.getOutputQueue(JMSServicesMgr.java:210)
at com.ibm.msg.client.wmq.v6.jms.internal.MQSession.createQProducer(MQSession.java:3138)
at com.ibm.msg.client.wmq.v6.jms.internal.MQSession.createProducer(MQSession.java:2863)
at com.ibm.msg.client.wmq.v6.jms.internal.MQSession.createProducer(MQSession.java:2920)
at com.ibm.msg.client.jms.internal.JmsSessionImpl.createProducer(JmsSessionImpl.java:1191)
at com.ibm.msg.client.jms.internal.JmsXAQueueSessionImpl$1.createSender(JmsXAQueueSessionImpl.java:415)
at com.ibm.mq.jms.MQQueueSession.createSender(MQQueueSession.java:148)
at weblogic.deployment.jms.WrappedSession.createSender(WrappedSession.java:344)
at com.tiger.gmfs.framework.jms.QUtil.getSender(QUtil.java:216)
at com.tiger.gmfs.framework.jms.QUtil.sendMessage(QUtil.java:110)
The piece of code that i wrote is :
this is my getSender method:
protected QueueSender getSender() throws JavaMessagingException,
JMSException {
QueueSender sender = null;
queue = qsess.createQueue(qVO.getName());
sender = qsess.createSender(queue);
if (sender == null)
throw new JavaMessagingException("The queue sender is null.");
sender.setPriority(qVO.getPriority());
return sender;
}
and this is my sendMessage method:
public void sendMessage(Message jmsMessage) throws JavaMessagingException,
JMSException {
QueueSender sender = null;
try {
sender = getSender();
sender.send(jmsMessage);
} catch (JMSException j) {
Exception l = j.getLinkedException();
if (l != null) {
JavaMessagingException be = new JavaMessagingException(
"JMSErrCode:" + l + " Code:" + j.getErrorCode()
+ " Message: " + jmsMessage, j);
throw be;
} else
throw new JavaMessagingException(j);
}catch(Exception e1){
System.out.println(e1);
}finally {
if (sender != null) {
sender.close();
TracingHelper.infoLog(QUtil.class, "sendMessage",
"Closed sender");
}
}
}
What changes should i do here that my code works?
I have Implemented the same code in jre 1.7 +weblogic 12c that works perfectly but when i changed it to jre 1.6 + weblogic 11g, i get this error.
From a development point of view, when an application opens the queue - the developer has to make sure that the right open options are used to open a WebSphere MQ queue.
If the application wants to put a message, open the queue with MQOO_OUTPUT open option and not any of the MQOO_INPUT* options.
If the application wants to get a message, open the queue with any one of the below open options, but not all at the same time
MQOO_INPUT_SHARED
MQOO_INPUT_EXCLUSIVE
MQOO_INPUT_AS_Q_DEF
The reason being, if the queue being opened is an alias queue pointing to a base queue in the same queue manager where the alias queue is present, and the base queue is a local queue - both, the OUTPUT and INPUT open options are valid.
However, if the alias queue being opened is pointing to a remote queue or a topic in the same queue manager where the alias queue is present, or if the alias queue is pointing to a cluster local queue present in a different queue manager in the cluster, all of the MQOO_INPUT* open options are invalid in this scenario.
Hence it is always advisable to open a WebSphere MQ queue only and only with the appropriate open options required for the operation being performed.
In your case, if you are trying to open the alias queue with any of the MQOO_INPUT* open option, and it is pointing to a cluster local queue in a different queue manager, it is incorrect. You have to remove the MQOO_INPUT* open option from your code to resolve the issue, as the MQOO_INPUT* option is not valid in this scenario.
MQRC 2082 MQRC_UNKOWN_ALIAS_BASE_Q is telling you that the queue in question:-
MQJMS2008: failed to open MQ queue 'OFS.TIG_IND2NSE_MSG'.
is an alias queue that isn't defined correctly, because the base queue it is pointing at doesn't exist.
Suggest you use the following MQSC command to display it:-
DISPLAY QALIAS(OFS.TIG_IND2NSE_MSG) ALL
and look for the field TARGET, and then issue another MQSC command to display the queue it is aliasing:-
DISPLAY QUEUE(target-queue-name) ALL
which I expect will fail telling you the queue doesn't exist. In that case you should either define it, or correct the QALIAS definition to point at the correct target queue name.
The Problem is for an alias when the Base Queue Manager is present at the cluster or some other Remote Queue manager. setting the Queuemanger name explicitly will give this error.
if(jmsConfigQueue.getOpenOptions()!=null){
if(jmsConfigQueue.getOpenOptions().equalsIgnoreCase("Inbound"))
{
mqqueue.setBaseQueueManagerName(qcf.getQueueManager());
}
else if(jmsConfigQueue.getOpenOptions().equalsIgnoreCase("Outbound"))
{
mqqueue.setBaseQueueManagerName("");
}
else
mqqueue.setBaseQueueManagerName(qcf.getQueueManager());
}
else {
mqqueue.setBaseQueueManagerName(qcf.getQueueManager());
}
So to enable the application search the Base Queue Manager(Remote) set it as blank. as the above code.
I want to receive some messages from IBM MQ based on java. So I write a very simple code to test what I want. Here is the sample code below.
Const.MQ_QMANAGER = "QM.CREDITWEB3T.PC";
Const.MQ_QUEUE_RECEIVE = "MQ.AIRPORTS";
MQSimpleConnectionManager myConnMan = new MQSimpleConnectionManager();
myConnMan.setActive(MQSimpleConnectionManager.MODE_AUTO);
MQQueueManager qMgr = new MQQueueManager(Const.MQ_QMANAGER,
myConnMan);
When I new the MQQueueManager. It’s throw an error message.
The error message is
MQJE001: Completion Code '2', Reason '2495'
May someone help me to figure out what’s wrong here? Thanks a lot.
(1) Your 1st posting is requesting that the connection to the queue manager be in "bindings mode". This means you MUST run the code on the same server where the queue manager is running.
(2) Your 2nd posting is requesting that the connection to the queue manager be in "client mode" (over the network i.e.TCP/IP). This means you can run the code on a remote server and connect to the remote queue manager using the network.
After many times error and searched for the answer. Finally I found the solution. You needed to settle environmental parameter for MQ. I am sorry about that because I am so new about MQ. Here is the sample code below.
// Host
MQEnvironment.properties.put(MQConstants.HOST_NAME_PROPERTY,
Const.MQ_HOST_NAME_PROPERTY);
// Port
MQEnvironment.properties.put(MQConstants.PORT_PROPERTY,
Const.MQ_PORT_PROPERTY);
// Channel
MQEnvironment.properties.put(MQConstants.CHANNEL_PROPERTY,
Const.MQ_CHANNEL_PROPERTY);
MQEnvironment.properties.put(MQConstants.CCSID_PROPERTY, XXX);
I have a server containing folders date wise and each folder further contains many files (size 200kb each) containing all the log for a particular day. I am new to RabbitMQ , while going through the documentation of RabbitMQ i found below code for Producer
Refer Link: https://github.com/rabbitmq/rabbitmq-tutorials/blob/master/java/Send.java
public class Send {
private final static String QUEUE_NAME = "hello";
public static void main(String[] argv) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
String message = "Hello World!";
channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
System.out.println(" [x] Sent '" + message + "'");
channel.close();
connection.close();
}
}
on the above code i have added sample string "Hello World!" to publish. As stated above in the problem description that i have to read the log information from the server with different date stamp directory So do i need to write a simply an infinite loop(as logs are continuously updated) and recursively read all directory and files and Then for each line of File i can compose a message and then publish it to receiver ?
In this case our channel will never close and Connection will be always up is it an idle condition with RabbitMQ ?
Is it possible for RabbitMQ to mark the file which are read and don't read it again OR i need to manage it programmatically like renaming the file and folder with some different names. I was thinking this as might be our program gets terminated with some power failure or something while i am in mid of any file and then how can i guarantee that records would not be duplicated ?
Any other best way to achieve this would be great help for me. Thanks in advance.
I would enqueue a list of files to process to RabbitMQ and then have a separate set of processes picking up messages from that queue to do what you want with the data. Then try to make sure to subscribe to the queues in ack mode, so RabbitMQ will only delete the message from the queue once you ack it. With this setting, you should prevent sending the same information twice.
That would work on most situations. I say most, because if RabbitMQ sends a message to your consumer, then your consumer takes an action (like replicating the information, or placing an entry on a database) and then the connection to RabbitMQ dies before you sent the ack to RabbitMQ, then the broker has no way of telling that you already processed the message, so it will deliver it again later.
I'm very new to ibm mq, I find out the documents or books related to mb are so few, the only one I found is 'WebSphere MQ Using Java' written in 2004. But the real world has changed a lot.
I installed and verified mq server 7.5 on redhat linux 64 bit successfully according to this
I also created queue manager myqm1, queue LQ.TEST, channel JAVA.CHANNEL and did some test through command lines on server to ensure they work well. However when I installed a mq client on windows xp and wrote below java code, it always throw a exception:com.ibm.mq.MQException: MQJE001: Completion Code '2', Reason '2035'
my code:
import com.ibm.mq.*; import com.ibm.mq.constants.MQConstants;
/** * Simple example program */ public class MQSample {
// code identifier
static final String sccsid = "#(#) MQMBID sn=p000-L120604 su=_H-IvIK4nEeGko6IWl3MDhA pn=MQJavaSamples/wmqjava/MQSample.java";
// define the name of the QueueManager
private static final String qManager = "myqm1";
// and define the name of the Queue
private static final String qName = "LQ.TEST";
/**
* Main entry point
*
* #param args - command line arguments (ignored)
*/
public static void main(String args[]) {
try {
MQEnvironment.hostname = "58.2.221.196";
MQEnvironment.channel = "JAVA.CHANNEL";
MQEnvironment.port = 1414;
MQEnvironment.properties.put(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES);
MQEnvironment.userID = "mqm";
MQEnvironment.password = "mqm";
MQEnvironment.CCSID = 1208;
// Create a connection to the QueueManager
System.out.println("Connecting to queue manager: " + qManager);
MQQueueManager qMgr = new MQQueueManager(qManager);
// Set up the options on the queue we wish to open
int openOptions = MQConstants.MQOO_INPUT_AS_Q_DEF | MQConstants.MQOO_OUTPUT;
// Now specify the queue that we wish to open and the open options
System.out.println("Accessing queue: " + qName);
MQQueue queue = qMgr.accessQueue(qName, openOptions);
// Define a simple WebSphere MQ Message ...
MQMessage msg = new MQMessage();
// ... and write some text in UTF8 format
msg.writeUTF("Hello, World!");
// Specify the default put message options
MQPutMessageOptions pmo = new MQPutMessageOptions();
// Put the message to the queue
System.out.println("Sending a message...");
queue.put(msg, pmo);
// Now get the message back again. First define a WebSphere MQ
// message
// to receive the data
MQMessage rcvMessage = new MQMessage();
// Specify default get message options
MQGetMessageOptions gmo = new MQGetMessageOptions();
// Get the message off the queue.
System.out.println("...and getting the message back again");
queue.get(rcvMessage, gmo);
// And display the message text...
String msgText = rcvMessage.readUTF();
System.out.println("The message is: " + msgText);
// Close the queue
System.out.println("Closing the queue");
queue.close();
// Disconnect from the QueueManager
System.out.println("Disconnecting from the Queue Manager");
qMgr.disconnect();
System.out.println("Done!");
} catch (MQException ex) {
ex.printStackTrace();
System.out.println("A WebSphere MQ Error occured : Completion Code " + ex.completionCode
+ " Reason Code " + ex.reasonCode);
} catch (java.io.IOException ex) {
System.out.println("An IOException occured whilst writing to the message buffer: " + ex);
}
return;
} }
Can anybody throw a light to me on that? I'm totally down.
To expand on Shashi's answer, since WMQ V7.1 the default CHLAUTH rules block all access on all SVRCONN channels and they block administrative access on all SVRCONN channels. If you really want to connect to JAVA.CHANNEL as mqm then you will need to override both of these behaviors.
If you are actually willing to allow remote, unauthenticated connections to the QMgr with an administrative user ID, then you have the option of disabling CHLAUTH rules altogether. You can do this by issuing the ALTER QMGR CHLAUTH(DISABLED) command in runmqsc however this is HIGHLY discouraged because it leaves the QMgr open to anonymous remote code execution using the WMQ administrative user ID. This is, however, what you appear to be trying to do.
The recommended approach would be to use an ID that is not administrative. For example, if you made an ID called mquser with a private group also called mquser then you could grant it rights to connect and inquire on the QMgr and to open the designated queue for put, get, browse and inquire. Since the ID is not administrative, it would be relatively safe to use on unauthenticated channels. You could change your code to specify the ID as mquser instead of mqm and then use a CHLAUTH rule to allow the connection. For example:
SET CHLAUTH('JAVA.CHANNEL') TYPE(USERMAP) +
CLNTUSER('mquser') USERSRC(MAP) +
MCAUSER('mquser') ACTION(ADD)
The above rule tells the QMgr "when you see a connection from the mquser ID on JAVA.CHANNEL, then set MCAUSER to mquser and allow the connection."
When you grant permissions, remember to grant them on the group and not the user. For example, if using setmqaut use the -g option and not the -p option. If there are any issues with authorization errors, you can sort these out easily using event messages. First, enable events using the ALTER QMGR AUTHOREV(ENABLED). This will cause the QMgr to emit an event message into the SYSTEM.ADMIN.QMGR.EVENT queue. You can use SupportPac MH05 or SupportPac MS0P to parse the event messages. For any given authorization event the message tells you the ID that requested access, the API call (connect, open, close etc.), the object the call was made against and the exact options that were used.
Prior to WMQ V7.1, WebSphere MQ allowed all remote connections, even anonymous, administrative ones. Although this allowed you to connect easily, in today's more hostile network environment the ability to remotely and anonymously execute code on the QMgr's host server is seen as an unacceptable security risk. So now a new QMgr is set to not allow any remote administrative access by default. As the administrator this requires you to explicitly disable security to get the old behavior or to explicitly provision secure access.
In MQ v7.5, by default access to queue manager is blocked. You need to create channel authentication records for the channel you created, JAVA.CHANNEL to allow user to access queue manager. Please follow this link for more details on Channel Authentication Records