ERROR when creating a connectioFactory JMS websphere MQ - java

The native JNI library 'mqjbnd64' not found.
please some one can help me to get mqjbnd64
this is my code
ConnectionFactory connectionFactory=null;
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory");
env.put(Context.PROVIDER_URL, "file:/C:/CWMQv75-POT/JMS/JNDI Namespace");
try{
Context ctx = new InitialContext(env);
// MQQueueManager qm = (MQQueueManager)ctx.lookup("QM");
MQConnectionFactory cf = (MQConnectionFactory) ctx.lookup("CF1");
// cf.createConnection().start();
MQQueue q = (MQQueue) ctx.lookup("JMS1");
connectionFactory = (ConnectionFactory)ctx.lookup("CF1");
System.out.println("succes "+q.getBaseQueueManagerName().toString() + " " + q.getBaseQueueName()+" " +" " + cf.getChannel() );
} catch (NamingException e)
{
System.err.println(e.getLocalizedMessage());
e.printStackTrace();
}
Connection connection = connectionFactory.createConnection();
}

The native JNI library 'mqjbnd64' not found
Questions:
1) Are you running your JMS application on the SAME serer as the queue manager or a different server?
2) When you defined your QCF, did you include host, port #, channel name?
3) Do you understand the difference between connecting to a queue manager in bindings mode vs client mode?
You can ONLY connect in bindings mode if your application is running on the same server as the queue manager. When connecting in bindings mode the JMS/Java MQ library uses the native MQ library, hence, it needs the mqjbnd64 shared library or DLL on Windows to perform the MQ API calls.
Most MQ applications do NOT reside on the same server as the queue manager and they will use client mode to connect to the remote queue manager and your QCF would look something like:
DEFINE QCF(MYQCF) QMANAGER(MQWL1) CHANNEL(TESTCHL) HOSTNAME(10.10.10.10) PORT(1414) TRANSPORT(CLIENT) FAILIFQUIESCE(YES)
One other thing I noticed:
env.put(Context.PROVIDER_URL, "file:/C:/CWMQv75-POT/JMS/JNDI Namespace");
that should be:
env.put(Context.PROVIDER_URL, "file://C:/CWMQv75-POT/JMS/JNDI Namespace");
You should have 2 forward slashes "//" after "file:".

Related

How to lookup a remote jms queue on Wildfly 10

It's amazing that i can't find a working example of how to send a message to a Wildfly 10 jms queue. It seems every version of Jboss had a different way of doing this so i can find a few examples but each one addresses a different version and none for Wildfly 10.
what I'm trying to do is send a message from a master wildfly instance (running on machine 1) to a JMS queue hosted on a slave wildfly instance (running on machine 2-n). In other words, i may have several slave wildfly instances.
I've added to the standalone-full.xml of each slave instance the following:
1) In the global-modules element
<module name="org.jboss.remote-naming" slot="main"/>
2) The queue is defined as
<jms-queue name="JobTaskMDB" entries="queue/JobTaskExecuterQueue java:jboss/exported/queue/JobTaskExecuterQueue"/>
3) Every slave has the guest user
The only thing I've added to the standalone-full.xml of the master instance is (1) above
Given a machine name, such as "WILDD250148-8C9", how can i selectively send a message from the master Wildfly instance to the queue of the specified machine hosting one of the slave instances?
So far I can't even get passed the lookup of the queue.
I've tried the following code:
String server = "WILDD250148-8C9";
final Properties env = new Properties();
env.put(Context.INITIAL_CONTEXT_FACTORY, org.jboss.naming.remote.client.InitialContextFactory.class.getName());
env.put(Context.SECURITY_PRINCIPAL, "guest"); //has been added to all slaves
env.put(Context.SECURITY_CREDENTIALS, "guest");
String url =
//"queue/JobTaskExecuterQueue";
//"http-remoting://" + server + ":8080";
//"tcp://" + server + ":5445";
"jnp://" + server + ":1099";
env.put(Context.PROVIDER_URL, url);
env.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
remoteContext = new InitialContext(env);
String lookupName =
//"java:jboss/exported/queue/JobTaskExecuterQueue";
//"JobTaskMDB";
"queue.queue/JobTaskExecuterQueue";
Object x = remoteContext.lookup(lookupName);
I always get "javax.naming.CommunicationException: Failed to connect to any server", for example
javax.naming.CommunicationException: Failed to connect to any server. Servers tried: [jnp://WILDD250148-8C9:1099 (No connection provider for URI scheme "jnp" is installed)]
or
javax.naming.CommunicationException: Failed to connect to any server. Servers tried: [tcp://WILDD250148-8C9:5445 (No connection provider for URI scheme "tcp" is installed)]
when I used the url "http-remoting://" + server + ":8080" I got the exception:
javax.naming.CommunicationException: Failed to connect to any server. Servers tried: [http-remoting://WILDD250148-8C9:8080 (Operation failed with status WAITING after 5000 MILLISECONDS)] [Root exception is java.net.ConnectException: Operation failed with status WAITING after 5000 MILLISECONDS]
Obviously i don't even know which provider URL to use.
what am i missing here?
The correct URL provider for WildFly 10 is http-remoting.
This works for me with Wildfly 10.1:
Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
props.put(Context.PROVIDER_URL, "http-remoting://127.0.0.1:8080");
props.put(Context.SECURITY_PRINCIPAL, "user");
props.put(Context.SECURITY_CREDENTIALS, "password");
InitialContext ctx = new InitialContext(props);
ActiveMQConnectionFactory cf = (ActiveMQConnectionFactory) ctx.lookup("jms/RemoteConnectionFactory");
ActiveMQQueue queue = (ActiveMQQueue) ctx.lookup("queue/JobTaskExecuterQueue");
If the JNDI name of the queue is java:jboss/exported/queue/JobTaskExecuterQueue then from the client, use queue/JobTaskExecuterQueue (it's relative to the java:jboss/exported/ namespace)
Remove this line, this is not needed:
env.put(Context.URL_PKG_PREFIXES,"org.jboss.naming:org.jnp.interfaces");
If you're getting
Operation failed with status WAITING after 5000 MILLISECONDS
then it means that the connection got stuck for more than 5 seconds for some probably different reason, like a firewall, slow network or something - the client code is probably correct.

Qpid receiver on Azure EventHub

I have already working application based on Azure EventHub. Now I need write java receiver that connects to the existing infrastructure.
Existing configuration:
Event Hub > SomeName > Consumer Group > SomeGroupName
In the administrative console I cannot see any QUEUE or TOPIC definitions. Analyzing working c# code I can see that hub-name + group-name is enough to connect.
I have reconstructed url that allows me to connect over java (and connection works so far).
amqps://SomeName.servicebus.windows.net
So my questions:
1) When instead of queue /topic I specify group-name then I get exception The messaging entity 'sb://SomeName.servicebus.windows.net/SomeGroupName' could not be found. What is the model used there instead of queue/topic?
2) How to work with such infrastructure from Apache-qpid?
Are you using the Event Hub created in the old portal or one created using the new portal?
EventHub is not a Message Bus, so there are no Queues or Topics, that is correct.
The consumer group is not a part of the address. The address is build using the namespace and the name of the eventhub in that namespace.
So the address becomes:
sb://SomeNameSpaceName.servicebus.windows.net/SomeEventHubName
Can you post the c# code you've analyzed? Since you have an already working application maybe we can workout the differences that prevents it from working now.
The greatest hint for resolve the question gave me following link: http://theitjourney.blogspot.com/2015/12/sendreceive-messages-using-amqp-in-java.html
So No queue neither topic in this model. You need to connect to specific provider and specify correct EventHub as following:
application.properties:
connectionfactory.SBCF=amqps://<PolicyName>:<PolicyKey>#<DomainName>.servicebus.windows.net
queue.EventHub=<EventHubName>/ConsumerGroups/$Default/Partitions/0
Where:
After that following code allowed me to create MessageConsumer:
Hashtable<String, String> env = new Hashtable<>();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"org.apache.qpid.amqp_1_0.jms.jndi.PropertiesFileInitialContextFactory");
env.put(Context.PROVIDER_URL,
getClass().getResource("/application.properties").toString());
Context context = null;
context = new InitialContext(env);
// Look up ConnectionFactory
ConnectionFactory cf = (ConnectionFactory) context.lookup("SBCF");
Destination queue = (Destination) context.lookup("EventHub");
// Create Connection
Connection connection = cf.createConnection();
// Create receiver-side Session, MessageConsumer
Session receiveSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageConsumer receiver = receiveSession.createConsumer(queue);

How to use WAS JMS resourses for IIB MQ Queue from a Java Application on WAS (using JNDI)

I am new to MQ and JNDI and I looking for some simple sample Java code that resolves my WAS JMS configuration and can write to and read from two Message Queues.
specifically I would like JAVA code to:
run code on IBM WebSphere Application Server Network Deployment (WAS ND 8.5.5)
write to, and read from, 2 IBM Integration Bus (IIB) Message Queues on an external system
In WAS I configured JMS resources as follows:
for the connection factory - gave it a JNDI name of "jms/MQCONN.FACTORY"
for the queue #1 - gave it a JNDI name of "jms/MQUEUE1.DEST"
for the queue #2 - gave is a JNDI name of "jms/MQUEUE2.DEST"
I set up JAAS - J2C authentication data credentials.
Note: I was unable to test the connection to MQ for connection factory, because the security settings are added to after the wizard completes and the you can only test from the wizard. I believe the WAS configuration is correct including the credentials.
I especially do not understand how to code the JNDI part (i.e. How to store the environment variable that tells JNDI which initial context to use, and where to find the provider.)
Grateful for any assistance!
Sibyl , Once you have configured these Managed Objects (QueueConnectionFactory . Queue) , you should be able to lookup these from code that you can deploy on the application server.
You will have to get
a) InitialContext (when you deploy a ear on the server , you can use the default constructor)
b) Lookup queue connection factory (context.lookup(xxx))
c) Lookup queue (context.lookup(yyyy))
d) Create a message producer
e) Create a Queue Session , text message and send the message directly
You can get some more idea here (http://www.webspheretools.com/sites/webspheretools.nsf/docs/Creating%20a%20Queue%20Connection%20Factory%20and%20Queue%20for%20connectivity%20to%20MQ)
Basically post configuration it is a lot of Boilerplate JMS coding
Here is little help for you.
You don't need to provide extra configuration after creating resources in WAS.
Queue myQueue;
QueueConnectionFactory myQueueFactory;
QueueConnection connection = null;
QueueSession session = null;
try{
InitialContext jndi = new InitialContext();
myQueueFactory = (QueueConnectionFactory) jndi.lookup("jms/MQCONN.FACTORY");
myQueue = (Queue) jndi.lookup("jms/MQUEUE1.DEST");
connection=myQueueFactory.createQueueConnection();
session = connection.createQueueSession(true, Session.AUTO_ACKNOWLEDGE);
QueueSender sender = session.createSender(myQueue);
connection.start();
TextMessage textMessage = session.createTextMessage(event);
textMessage.setStringProperty("messageType", "file");
sender.send(textMessage);
sender.close();
if (session != null) {
session.close();
}
if (connection != null) {
connection.close();
}
} catch (JMSException e) {
e.printStackTrace();
}

Java (and JBoss) JNDI and RMI ports

I have JBoss running on a couple of Linux machines. If I want to send a JMS message from box 1 to a queue on box2, I may do something like this:
Hashtable<String,String> jndiProperties = new Hashtable<String,String>();
jndiProperties.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
jndiProperties.put(javax.naming.Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
jndiProperties.put(javax.naming.Context.PROVIDER_URL, "jnp://<ip of box2>:1099"); //
InitialContext context = new InitialContext(m_jndiProperties);
Queue queue = (Queue)context.lookup("queue/myqueue");
and then put a message on the queue. Clearly port 1099 needs to be open on box2, but I am curious what other ports are involved in that communication?
Thank You.
Others I have off top of my head:
Rmi: 1098.
HornetQ acceptors / connectors: 5446 / 5445. Both configurable in JBOSS_HOME/server/default/deploy/hornetq/hornetq-configuration.xml

How to use Java JMS with MQseries

I am trying to develop a JMS standalone application to read and write to a Queue on MQSeries.
My boss asked me to use pure java JMS (not ibm.mq lib) to do that.
Here is the information that need to make the jms connection:
mq.hostname=10.10.10.10
mq.channel=API.CLIENTCHL
mq.queueManager=MQPETAPI
mq.port=1422
Do you know how to do that Or do you have any link that teach me to do that.
The issue here is the requirement that "My boss asked me to use pure java JMS (not ibm.mq lib) to do that." JMS is a specification and each implementation must comply with the API and the semantics, but is free to do whatever they want at a low level. It is always necessary to use the implementation classes provided by the transport vendor. Therefore if you use WebSphere MQ as the transport, you will need to use the IBM MQ JMS classes to write a JMS application.
That said, if you stick with pure JMS API calls you would be able to plug in any transport vendor's classes. This is what is usually intended when you are given requirements such as that mentioned in the original post.
There's an article describing exactly what you are looking to do called Running a standalone Java application on WebSphere MQ V6.0 It uses only the JMS API and it uses JNDI in a local file system (a .bindings file). By swapping out the IBM JMS classes for another vendor and using their JNDI tools you would be able to plug in any JMS transport without changing your code using this approach.
If you want to do the same thing without JNDI, look at the sample programs provided with the MQ client install where you obtained your Java classes. In a UNIX/Linux system these are in /opt/mqm/samp and on Windows they are in install_dir/tools/jms/samples. The SimpleRequestor.java sample has the following code for initializing your connection factory without JNDI:
try {
// Create a connection factory
JmsFactoryFactory ff = JmsFactoryFactory.getInstance(WMQConstants.WMQ_PROVIDER);
JmsConnectionFactory cf = ff.createConnectionFactory();
// Set the properties
cf.setStringProperty(WMQConstants.WMQ_HOST_NAME, "localhost");
cf.setIntProperty(WMQConstants.WMQ_PORT, 1414);
cf.setStringProperty(WMQConstants.WMQ_CHANNEL, "SYSTEM.DEF.SVRCONN");
cf.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT);
cf.setStringProperty(WMQConstants.WMQ_QUEUE_MANAGER, "QM1");
Because this approach does not use JNDI, you are required to write code that is not transportable across transport vendors. It is IBM WebSphere MQ specific.
If you grabbed the MQ jars from somewhere and do not have the full install (and thus do not have the samples) you can download it as SupportPac MQC7. The download is free. In general you should use the latest client, even with a back-level queue manager. Obviously you do not get V7 functionality from a V6 QMgr but the JMS implementation in the V7 client is much improved, even for V6 functionality. If for some reason you really must use the V6 client, you can download it as SupportPacMQC6. Whichever client version you use, make sure to use the corresponding Infocenter.
V6 Infocenter
V7 Infocenter
Finally, the landing page with an index for all the SupportPacs is here.
A complete (synchronous) standalone JMS application with TextMessage.
It is IBM WebSphere MQ specific.
import javax.jms.DeliveryMode;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueReceiver;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.TextMessage;
import com.ibm.mq.jms.JMSC;
import com.ibm.mq.jms.MQQueueConnectionFactory;
public class JMSApplicationStandAlone {
public static void main(String[] args) {
try {
/*MQ Configuration*/
MQQueueConnectionFactory mqQueueConnectionFactory = new MQQueueConnectionFactory();
mqQueueConnectionFactory.setHostName("localhost");
mqQueueConnectionFactory.setChannel("MQ.CHANNEL");//communications link
mqQueueConnectionFactory.setPort(1416);
mqQueueConnectionFactory.setQueueManager("QUEUE.MGR");//service provider
mqQueueConnectionFactory.setTransportType(JMSC.MQJMS_TP_CLIENT_MQ_TCPIP);
/*Create Connection */
QueueConnection queueConnection = mqQueueConnectionFactory.createQueueConnection();
queueConnection.start();
/*Create session */
QueueSession queueSession = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
/*Create response queue */
Queue queue = queueSession.createQueue("QUEUE.RESPONSE");
/*Create text message */
TextMessage textMessage = queueSession.createTextMessage("put some message here");
textMessage.setJMSReplyTo(queue);
textMessage.setJMSType("mcd://xmlns");//message type
textMessage.setJMSExpiration(2*1000);//message expiration
textMessage.setJMSDeliveryMode(DeliveryMode.PERSISTENT); //message delivery mode either persistent or non-persistemnt
/*Create sender queue */
QueueSender queueSender = queueSession.createSender(queueSession.createQueue("QUEUE.REQEST"));
queueSender.setTimeToLive(2*1000);
queueSender.send(textMessage);
/*After sending a message we get message id */
System.out.println("after sending a message we get message id "+ textMessage.getJMSMessageID());
String jmsCorrelationID = " JMSCorrelationID = '" + textMessage.getJMSMessageID() + "'";
/*Within the session we have to create queue reciver */
QueueReceiver queueReceiver = queueSession.createReceiver(queue,jmsCorrelationID);
/*Receive the message from*/
Message message = queueReceiver.receive(60*1000);
String responseMsg = ((TextMessage) message).getText();
queueSender.close();
queueReceiver.close();
queueSession.close();
queueConnection.close();
} catch (JMSException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Note: Replace the configuration values
If you don't mind writing WMQ-specific code then you can do
MQConnectionFactory cf = new MQConnectionFactory();
cf.setHostName(HOSTNAME);
cf.setPort(PORT);
cf.setChannel(CHANNEL);
cf.setQueueManager(QMNAME);
cf.setTransportType(WMQConstants.WMQ_CM_CLIENT);
then usual JMS resources
Connection c = cf.createConnection();
Session s = c.createSession(false, Session.AUTO_ACKNOWLEDGE);
Queue q = s.createQueue("myQueue"); // replace with real queue name
MessageProducer p = s.createProducer(q);
and finally create and send a message
Message m = s.createTextMessage("Hello, World!);
p.send(m);
(i've typed that in off the top of my head so can't rule out a typo, but it's fundamentally correct). If you're really supposed to be using 'pure JMS' - i.e. with no provider-specific objects - then you need to bind a MQConnectionFactory object in JNDI (take a look at the JMSAdmin tool, it's in the docs) then look it up from your application, i.e.
InitialContext ic = new InitialContext(); // or as appropraite
ConnectionFactory cf = (ConnectionFactory)ic.lookup("myMQfactory"); // replace with JNDI name
Typically with JMS you would define the QueueConnectionFactory in your container via whatever configuration mechanism it makes available then add it to the container's JNDI registry. Each container would have it's own methods for doing that (i.e. Tomcat versus WebSphere).
If you want to forgo JNDI, you could create an instance of com.ibm.mq.jms.MQQueueConnectionFactory directly and set the hostname, port, queueManager, and channel properties on it. You can then use that object as you would an instance of javax.jms.QueueConnectionFactory since it implements it.
I can't teach you JMS in a single post, but I can point you to some of the resources that I used to learn it myself:
The O'Reilly Java Message Service book
IBM Developerworks JMS Tutorial (more MQSeries/Websphere MQ specific)
The Spring framework can help you use JMS more effectively, especially if you're developing a standalone app outside of a J2EE app server: Spring Java Message Service documentation
This is fairly common. Here are some examples.

Categories