Getting JMSException connecting to IBM MQ from Java client - java

We are trying to connect to IBM MQ from a Java client. We have generated .bindings for JNDI context using the JMSAdmin utility. When connecting to IBM MQ we are getting following exception:
ERR fmbaJMS JMSException: JMSWMQ0018: Failed to connect to queue manager '<queue manager name>' with connection mode 'Client' and host name 'null'
Host name parameter sent is null while .bindings file correctly have
mq/RefAddr/30/Content=localhost(51410)
mq/RefAddr/30/Type=CRSHOSTS
Entries pointing to localhost and port 51410.

Your .bindings file does not look right. What was the JMSAdmin command you used to create it?
MQ0018: Failed to connect to queue manager 'bt.qm.ccxp0'
Is that your queue manager name or QCF? Note: As per the IBM Best Practises, queue manager names should be in uppercase.
To define a QCF (Queue Connection Factory), you would do:
DEFINE QCF(myQCF) QMANAGER(MQA1) CHANNEL(TEST.CHL) HOSTNAME(127.0.0.1) PORT(1414) TRANSPORT(CLIENT) FAILIFQUIESCE(YES)
To define a JMS queue, you would do:
DEFINE Q(mqs.dev.test.q) QUEUE(TEST.Q1) QMANAGER(MQA1) TARGCLIENT(JMS) FAILIFQUIESCE(YES)
Then in your code, you would do the following to load the objects from the MQ JNDI:
Hashtable<String,String> env = new Hashtable<String,String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory");
env.put(Context.PROVIDER_URL, "file:/C:/JNDI-Directory");
Context ctx = new InitialContext(env);
QueueConnectionFactory cf = (QueueConnectionFactory) ctx.lookup("myQCF");
Queue q = (Queue) ctx.lookup("mqs.dev.test.q");

Related

How to specify host, port and channel in ConnectionFactory without using JNDI

Am trying to create a standalone java application to send message to different application using JMS. My reference code uses queueConnectionFactory and all connection parameters are configured in WAS server and retrieved using JNDI. But I cannot use server in my standalone application. In this case, how can I get or connect to the same host, port and queue without using JNDI.
Below is the code I have tried so far
try {
//Set connection factory
ActiveMQConnectionFacotry connectionFactory = new ActiveMQConnectionFactory("");
//create connection with connection factory
Connection connection = connectionFactory.createConnection();
connection.start();
//create session from connection
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//create queue from session
Destination destination = session.createQueue("sample.Queuename");
//create messageProducer
MessageProducer producer = session.createProducer(destination);
My reference code
//#Resource
private static Queue queue;
private QueueConnection con;
private QueueSession session;
private QueueSender sender;
private static InitialContext ctx;
private static JAXBContext jaxb;
private static IBwLogContext logContext = BwLogContextFactory.create();
static{
try {
ctx = new InitialContext();
queue = (Queue) ctx.lookup("jms/sampleJNDI1");
qcf = (QueueConnectionFactory) ctx.lookup("jms/sampleJNDI2");
JMS configuration is server for jms/sampleJNDI2
Now how do I connect to same xxx,yyy,zzz without server. Can we put these details in properties file and use them. If so, how to do it or is there any other way. I have hard coded queue name copying from the server. But stuck with ConnectionFactory.
Thanks in advance
You seem to be using the class ActiveMQConnectionFactory. This classname is used by both ActiveMQ 5.x and ActiveMQ Artemis, but with different package names. For better or worse, though, the basic configuration is the same for both:
ActiveMQConnectionFactory qcf = new ActiveMQConnectionFactory
("tcp://" + host + ":" + port);
QueueConnection qc = qcf.createQueueConnection ("user", "password");
There are other properties you can set on the connection factory, but host, port, user, and password are probably the most used.
Both ActiveMQ 5.x and ActiveMQ Artemis support other protocols than their proprietary ones (OpenWire and Artemis Core, respectively). For example, you can use the Qpid JMS runtime library to connect using the AMQP protocol. This has a different means of configuration, as do all the other client runtime libraries you might use.
Here is one way to set up a connection factory for IBM MQ, using IBM's "Class for Java" runtime.
import com.ibm.msg.client.wmq.*;
import com.ibm.mq.jms.*;
MQQueueConnectionFactory qcf = new MQQueueConnectionFactory();
qcf.setHostName ("my_mq.acme.com");
qcf.setPort (1414);
qcf.setQueueManager ("QMA");
qcf.setChannel ("SYSTEM.DEF.SVRCONN");
qcf.setTransportType (WMQConstants.WMQ_CM_CLIENT);
QueueConnection qc = qcf.createQueueConnection ("user", "password");
And here is an example for Qpid-JMS, that provides AMQP wire protocol support for many message brokers:
QueueConnectionFactory qcf = new
org.apache.qpid.jms.JmsConnectionFactory
("amqp://" + host + ":" + port);
QueueConnection qc = qcf.createQueueConnection ("user", "password");
I'm not sure why, but using a JMS client runtime without JNDI is often not well-documented. It's always possible, in my experience, but sometimes a bit of digging is required, to find the relevant settings.

Can't connect to IBMMQ MQRC_NOT_UNAUTHORIZED

I have installed IBMMQ 9.0 in windows running in virtualbox in my local and I have sample java code sending message to MQ.
here is the java code
MQQueueConnectionFactory cf = new MQQueueConnectionFactory();
cf.setHostName(MY_IP);
cf.setPort(1417);
cf.setTransportType(WMQConstants.WMQ_CM_CLIENT);
cf.setQueueManager("QM1_TEST");
cf.setChannel("QM1_TEST.CH");
MQQueueConnection connection = (MQQueueConnection)
cf.createQueueConnection();
MQQueueSession session = (MQQueueSession)
connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
MQQueue queue = (MQQueue) session.createQueue("queue:///QUEUE_TEST");
MQQueueSender sender = (MQQueueSender) session.createSender(queue);
String message = "Test Message";
TextMessage textMessage = (TextMessage)
session.createTextMessage(message);
connection.start();
sender.send(textMessage);
The program receives this error.
com.ibm.msg.client.jms.DetailedJMSSecurityException: JMSWMQ2013: The
security authentication was not valid that was supplied for QueueManager
'QM1_TEST' with connection mode 'Client' and host name '192.168.0.24(1417)'.
Please check if the supplied username and password are correct on the
QueueManager to which you are connecting. at
com.ibm.msg.client.wmq.common.internal.Reason.reasonToException(Reason.java:531)
at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:215)
at com.ibm.msg.client.wmq.internal.WMQConnection.<init>(WMQConnection.java:424)
at com.ibm.msg.client.wmq.factories.WMQConnectionFactory.createV7ProviderConnection(WMQConnectionFactory.java:8475)
at com.ibm.msg.client.wmq.factories.WMQConnectionFactory.createProviderConnection(WMQConnectionFactory.java:7815)
at com.ibm.msg.client.jms.admin.JmsConnectionFactoryImpl._createConnection(JmsConnectionFactoryImpl.java:303)
at com.ibm.msg.client.jms.admin.JmsConnectionFactoryImpl.createConnection(JmsConnectionFactoryImpl.java:236)
at com.ibm.mq.jms.MQConnectionFactory.createCommonConnection(MQConnectionFactory.java:6016)
at com.ibm.mq.jms.MQQueueConnectionFactory.createQueueConnection(MQQueueConnectionFactory.java:111)
at com.cwt.bpg.cbr.demo.ibm.mq.client.SendMessage.main(SendMessage.java:24)
Caused by: com.ibm.mq.MQException: JMSCMQ0001: IBM MQ call failed with compcode '2' ('MQCC_FAILED') reason '2035' ('MQRC_NOT_AUTHORIZED').
at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:203)
... 8 more
Here is the log under my queue manager with significant details.
5/21/2018 16:42:46 - Process(4984.8) User(MUSR_MQADMIN) Program
(amqrmppa.exe) Host(MSEDGEWIN10) Installation(Installation1) VRMF(9.0.0.0)
QMgr(QM1_DEV) AMQ9776: Channel was blocked by userid
EXPLANATION:
The inbound channel 'QM1_DEV.CH' was blocked from address '10.xx.xx.xx'
because the active values of the channel were mapped to a userid which
should be blocked. The active values of the channel were 'MCAUSER(IEUser)
CLNTUSER(IEUser) ADDRESS(LWPHL1U012FXP)'
You are not providing a user and password, your are connecting with the default user identity.
QueueConnection createQueueConnection()
Creates a queue connection with default user identity.
You can either provide credentials:
QueueConnection createQueueConnection(String userid,String password)
By default the userid and password for any user in the mqm group on the MQ broker will have access to the queue managers.
The IBM MQ docs also have instructions for disabling security altogether.

NamingException getting when tried to push the message to Activemq

i tried to publish message to activemq.but i am getting one naming exception in my java application. here is the code follows
Properties props = new Properties();
props.setProperty(Context.INITIAL_CONTEXT_FACTORY,"org.apache.activemq.jndi.ActiveMQInitialContextFactory");
props.setProperty(Context.PROVIDER_URL,"tcp://localhost:61616");
InitialContext ctx = new InitialContext(props);
// get the initial context
// InitialContext ctx = new InitialContext();
QueueConnectionFactory connFactory = (QueueConnectionFactory) ctx.lookup("ConnectionFactory");
// create a queue connection
QueueConnection queueConn = connFactory.createQueueConnection();
// lookup the queue object
Queue queue = (Queue) ctx.lookup("nixon");
i am getting three warning plus below one error like this
Exception in thread "main" javax.naming.NameNotFoundException: nixon
at org.apache.activemq.jndi.ReadOnlyContext.lookup(ReadOnlyContext.java:235)
at javax.naming.InitialContext.lookup(Unknown Source)
at com.youtube.rest2.status.ProducerNewClient.main(ProducerNewClient.java:38)
can anyone tell why i am getting this error..?
You are most likely getting this error because you haven't configured the destinations in you JNDI configuration file. You can either add these definitions to your file or use the dynamic destination features of ActiveMQ.
For the easiest possible configuration with JNDI based programs, there are 2 dynamic contexts as follows
dynamicQueues
dynamicTopics
which allows you to lookup queues and topics using JNDI without any configuration.
e.g. if you use the following name to lookup into JNDI
dynamicQueues/FOO.BAR
you will get back an ActiveMQQueue of the name "FOO.BAR".
Read the JNDI Documentation at the ActiveMQ site for more.

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);

Setting the URL for a JMS connection

The JMS Hello World example shows producers and consumers sending and consuming messages; this is how they seem to create the connection:
ConnectionFactory cf = new com.sun.messaging.ConnectionFactory();
Connection connection = cf.createConnection();
How specify the address and parameters of the remote JMS server?
I want to create an encrypted and compressed connection to an OpenMQ server that is running on another machine. Ideally I would like to use both client and server authentication.
This post seems to provide an example using JMS server address.
This is how it creates a connection. They provide the address and also username and password (admin).
String addressList = "http://127.0.0.1:8080/imqhttp/tunnel";
com.sun.messaging.TopicConnectionFactory topicConnectionFactory = new com.sun.messaging.TopicConnectionFactory();
topicConnectionFactory.setProperty(com.sun.messaging.ConnectionConfiguration.imqAddressList, addressList);
javax.jms.Topic top;
javax.jms.Connection con = topicConnectionFactory.createTopicConnection("admin", "admin");

Categories

Resources