I am still new with Spring and Ibm/mq but I am using JMSTemplate in a Spring project (build with maven) to send messages to a MQ. It works fine when I use the application.propeties file to define the MQ server infos.
Now I am triyng to do the same with a ".bindings", the binding file that I generated from my MQ server. It has lines like: QUEUE_CONNECTION_FACTORY_NAME/ClassName=com.ibm.mq.jms.MyQueueConnectionFactory
Can I use JMSTemplate to load the configuration from that binding file? How?
What I know is that the main way to use this file is with a JNDI FSContext, But I did not find how:
Where do you put the .bindings file?
How do you load it? (and do you load from a bean xml or from a context in the java code)
Is it even possible? I saw some old messages on a board saying that: "Spring does not support a .binding file. Any configuration items in the .binding file need to be translated into the appropriate Spring XML configuration."
In the other side I have this that have an incomplete answer to my question:
How to load JNDI context from the file system into Spring?
I have an overload of information but not a simple how to do this.
EDIT:
Now I can load the content of the file but it seems not compatible.
My code is like this:
environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory");
environment.put(Context.PROVIDER_URL, "file:/Users/user/jndi");
Context mycontext = new InitialContext( environment );
ConnectionFactory connectionFactory = (ConnectionFactory) mycontext.lookup("QCONNECTION_FACTORY");
JmsTemplate jmsTemplate = new JmsTemplate();
jmsTemplate.setConnectionFactory(connectionFactory);
MQQueue dest = (MQQueue) mycontext.lookup("LQ1");
//Connection connection = connectionFactory.createConnection("***","***");
//Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
jmsTemplate.convertAndSend(dest, "hello");
My queue jndi info:
LQ1/RefAddr/12/Type=MDCTX
LQ1/RefAddr/12/Encoding=String
LQ1/RefAddr/12/Content=0
LQ1/RefAddr/16/Content=LQ1
LQ1/RefAddr/16/Type=QU
and the JMSAdmin script:
DEF Q(LQ1) QUEUE(LQ1)
def qcf(QCONNECTION_FACTORY)transport(CLIENT)channel(DEV.APP.CHANNEL)host(localhost)port(1414)qmgr(QM1)
end
But I am getting:
org.springframework.jms.JmsSecurityException: JMSWMQ2008: Failed to open MQ queue 'LQ1'.; nested exception is com.ibm.msg.client.jms.DetailedJMSSecurityException: JMSWMQ2008: Failed to open MQ queue 'LQ1'
JMS attempted to perform an MQOPEN, but IBM MQ reported an error.
Use the linked exception to determine the cause of this error. Check that the specified queue and queue manager are defined correctly.; nested exception is com.ibm.mq.MQException: JMSCMQ0001: IBM MQ call failed with compcode '2' ('MQCC_FAILED') reason '2035' ('MQRC_NOT_AUTHORIZED').
Related
I'm trying to set ccdturl with the ccdt file which located in a remote server. I tried to set ccdt url using ftp but it does not work out. Does anyone know what is the correct way to set url for ccdt file in remote server?
Thanks!
I tried:
String channelTablePath = "ftp://user#host:/path-to-ccdt-file";
Url url = new URL(channelTablePath );
connectionFactory.setCCDTURL(url);
The error that I get is:
Exception in thread "main" javax.jms.JMSException: JMSWMQ2020: Failed to connect to queue manager '*QQ' with connection mode 'Client' and supplied CCDT URL 'ftp://user#host:/path/ccdt.tab', see linked exception for more information.
JMS Error code: com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2278' ('MQRC_CLIENT_CONN_ERROR').
EXPLANATION:
The filesystem returned error code 'java.net.ConnectException[Connection timed
out]' for file 'ftp://user#host:/path/ccdt.tab'.
ACTION:
Record the name of the file 'ftp://user#host:/path/ccdt.tab'
and tell the systems administrator, who should ensure that file 'ftp://user#host:/path/ccdt.tab'
is correct and available.
Summary:
You should not have a colon (:) after the host in the URL. You should specify a password value in the URL if required. You also need to specify the name of the ccdt file. References to the IBM Knowlege center at at the end of this answer.
Try the following value instead:
String channelTablePath = "ftp://user:pass#host/path-to-ccdt-file/AMQCLCHL.TAB";
The IBM MQ v9 Knowledge center page "Using a client channel definition table with IBM MQ classes for JMS" states:
As another example, suppose the file ccdt2.tab contains a client
channel definition table and is stored on a system that is different
from the one on which the application is running. If the file can be
accessed using the FTP protocol, the application can set the CCDTURL
property in the following way:
java.net.URL chanTab2 = new URL("ftp://ftp.server/admdata/ccdt2.tab");
factory.setCCDTURL(chanTab2);
The IBM MQ v9 Knowledge center page "Web addressable access to the client channel definition table" shows an example of a FTP URL with username and password:
Authenticated connections
export MQCHLLIB=ftp://myuser:password#myhost.sample.com/var/mqm/qmgrs/QMGR/#ipcc
export MQCHLLIB=http://myuser:password#myhost.sample.com/var/mqm/qmgrs/QMGR/#ipcc
...
Note
If you want to use authenticated connections you must, as with JMS, provide the user name and password encoded in the URL.
I already setup a connection to an Azure Servicebus queue with camel-amqp successfully and could read messages from it. Then I tried to switch to transactional mode. This time, it fails with the following warning, which will be repeated every 5 seconds:
c.c.j.DefaultJmsMessageListenerContainer : Setup of JMS message listener invoker failed for destination 'incoming' - trying to recover. Cause: Could not create JMS transaction; nested exception is javax.jms.JMSException: An AMQP error occurred (condition='amqp:internal-error'). [condition = amqp:internal-error]
My route looks like this:
from("amqp:queue:incoming?connectionFactory=#connectionFactory&transacted=true&transactionManager=#transactionManager").
The transactionManager is of type org.springframework.jms.connection.JmsTransactionManager and the (well configured) connectionFactory of type org.apache.qpid.jms.JmsConnectionFactory.
Could anybody imagine what is missing, maybe some additional configuration?
I configured a queue and a QueueConnectionFactory using the V5 Messaging provider in WebSphere Application Server 6.1.
I also have a ListenerPort configured for this destination.
It throws an exception when I try to connect to this queue using the queue connection factory or when the Message Listener listening to this ListenerPort starts up.
javax.jms.JMSException: MQJMS2005: failed to create MQQueueManager
for 'localhost:WAS_Node01_server1'
and the nested exception is
com.ibm.mq.MQException: MQJE001: An MQException occurred: Completion Code 2, Reason 2059
MQJE011: Socket connection attempt refused
Can someone please point me to what possibily could have gone wrong in configuring the queue and queue connection factory?
The error indicates that the WebSphere MQ transport is being used. Per the clarification in your comments, no queue manager is present so a 2059 is expected. It will be necessary to configure a WAS messaging Engine to provide the native transport or to point to a queue manager.
I want to be able to send messages to a remote JBoss server (JBoss MQ).
I can do it for a local one but i'm stuck when trying with a remote one.
can anyone explain to me how to do it ?
are there any specific steps to take ?
[what i've tried so far]
I need to send a message to a remote server's queue (running "JBoss MQ") so that it can process the message and act on it.
Properties properties = new Properties();
properties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
properties.put(Context.URL_PKG_PREFIXES, "org.jnp.interfaces");
properties.put(Context.PROVIDER_URL, "jnp://192.168.131.129:1299");
InitialContext jndiContext = new InitialContext(properties);
//[2] Look up connection factory and queue.
ConnectionFactory connectionFactory = (ConnectionFactory)jndiContext.lookup("UIL2XAConnectionFactory");
Queue queue = (Queue)jndiContext.lookup("Queue/DataTransferQueue");
but I get an exception when running the above code :
(even though, I can ping the remote server).
javax.naming.CommunicationException: Could not obtain connection to any of these urls: 192.168.1.131.129:1299 and
discovery failed with error: javax.naming.CommunicationException:
Receive timed out [Root exception is java.net.SocketTimeoutException: Receive timed out]
[Root exception is javax.naming.CommunicationException: Failed to connect to server 192.168.1.131.129:1299
Is there anything special to do to connect to a remote queue ?
Have you verified that you can connect to that remote host and port, i.e. telnet 192.168.131.129 1299? You might have a firewall that's blocking some traffic but allowing pings.
OK, so after trying a lot, I finally found out what the problem was :
I didn't start JBoss on the remote server in a way it could accept remote connections. by default, JBoss starts allowing only local connections.
so, I restarted it with this argument : -b 0.0.0.0 and it works fine now.
Thanks for your help and support.
I need to send a message to a remote server's queue (running "JBoss MQ") so that it can process the message and act on it.
Properties properties = new Properties();
properties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
properties.put(Context.URL_PKG_PREFIXES, "org.jnp.interfaces");
properties.put(Context.PROVIDER_URL, "jnp://192.168.1.131.129:1299");
InitialContext jndiContext = new InitialContext(properties);
//[2] Look up connection factory and queue.
ConnectionFactory connectionFactory = (ConnectionFactory)jndiContext.lookup("UIL2XAConnectionFactory");
Queue queue = (Queue)jndiContext.lookup("Queue/DataTransferQueue");
but I get an exception when running the above code :
(even though, I can ping the remote server).
javax.naming.CommunicationException: Could not obtain connection to any of these urls: 192.168.1.131.129:1299 and
discovery failed with error: javax.naming.CommunicationException:
Receive timed out [Root exception is java.net.SocketTimeoutException: Receive timed out]
[Root exception is javax.naming.CommunicationException: Failed to connect to server 192.168.1.131.129:1299
Is there anything special to do to connect to a remote queue ?
The IP address you're using is incorrect: 192.168.1.131.129 has 5 numbers, it should only have 4.
I solved the problem by restarting my JBoss server with the following process arguments :
-b 0.0.0.0
the JBoss server is started by default to only allow local connections. by starting it with the afore mentionned arguments, you instruct it to accept remote connections.