I installed Glassfish5 and started it using eclipse. I also logged to the Glassfish admin console and created two queues namely Queue01 and Queue02 under the JMS Resources\Destination Resources option. The code doesn't but when I run it, the last thing it performs is the print statement before the lookup command. Here is my code:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Properties;
import javax.jms.ConnectionFactory;
import javax.jms.JMSContext;
import javax.jms.JMSException;
import javax.jms.JMSProducer;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.Queue;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class Main implements MessageListener{
public static void main(String[] args) throws JMSException,NamingException, IOException{
if(args.length!=3) System.out.println("usage: username subscribe-to-queue publish-to-queue");
else {
String username = args[0];
System.out.println("username: " + username + " | subscribe-to-queue-name " + args[1] + " | publish-to-queue-name " + args[2]);
Context initialContext = Main.getInitialContext();
Main myMain = new Main();
System.out.println("Before Queue");
Queue queue01 = (Queue) initialContext.lookup(args[1]);
Queue queue02 = (Queue) initialContext.lookup(args[2]);
//java:comp/DefaultJMSConnectionFactory is the default conection at the JMS app server (no need to define it)
System.out.println("Before ConnectionFactory");
JMSContext jmsContext = ((ConnectionFactory) initialContext.lookup("java:comp/DefaultJMSConnectionFactory")).createContext();
//we use jms context to pickup jms consumer and assign it our own class (Main)
System.out.println("Before createConsumer");
jmsContext.createConsumer(queue01).setMessageListener(myMain);
System.out.println("Before jmsProducer");
JMSProducer jmsProducer = jmsContext.createProducer();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String msgToSend = null;
System.out.println("Before while");
while(true) {
System.out.println("Please enter msg:");
msgToSend = bufferedReader.readLine();
if(msgToSend.equalsIgnoreCase("exit")) {
jmsContext.close();
System.exit(0);
}else {
System.out.println("Before send");
jmsProducer.send(queue02, "["+username+": "+msgToSend+"]");
System.out.println("after send");
}
}
}
}
#Override
public void onMessage(Message message) {
try{System.out.println(message.getBody(String.class));}
catch (JMSException e) {e.printStackTrace();}
}
public static Context getInitialContext () throws JMSException,NamingException
{
Properties prop = new Properties();
prop.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
prop.setProperty("java.naming.factory.url.pkgs", "org.jnp.interfaces");
prop.setProperty("java.naming.provider.url", "jnp://localhost:3700");
Context context = new InitialContext(prop);
//Context context = new InitialContext();
return context;
}
}
Any hint one what is wrong with my code that leads to not being able to execute the lookup command? The problem is that I'm not seeing any error messages to give me a hint on what is wrong. I tried changing the provider url without a luck.
Related
Good afternoon all, I have an issue with IBM MQ, I'm supposed to use JMS to connect to a defined queue then send an XML file to the defined queue. Any help with this problem is gladly appreciated.
In this image it shows that no message is received even though in eclipse IDE it states other wise:
I have a coded application that should work it sends and receives a message the problem is that when I check my IBM MQ explorer and my linux MQ server nothing appears so I'm not sure if its the server configurations that are wrong.
Here is the code I was referring to :
package mqtest;
import javax.jms.Destination;
import javax.jms.JMSConsumer;
import javax.jms.JMSContext;
import javax.jms.JMSException;
import javax.jms.JMSProducer;
import javax.jms.TextMessage;
import com.ibm.msg.client.jms.JmsConnectionFactory;
import com.ibm.msg.client.jms.JmsFactoryFactory;
import com.ibm.msg.client.wmq.WMQConstants;
import javax.jms.JMSConsumer;
import javax.jms.JMSContext;
import javax.jms.JMSException;
import javax.jms.JMSProducer;
import javax.jms.TextMessage;
import com.ibm.msg.client.jms.JmsConnectionFactory;
import com.ibm.msg.client.jms.JmsFactoryFactory;
import com.ibm.msg.client.wmq.WMQConstants;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class JmsIOPutGet {
// System exit status value (assume unset value to be 1)
private static int status = 1;
// Create variables for the connection to MQ
private static final String HOST = "13.246.126.217"; // Host name or IP address
private static final int PORT = 1416; // Listener port for your queue manager
private static final String CHANNEL = "DEV.APP.SVRCONN"; // Channel name
private static final String QMGR = "qm5"; // Queue manager name
private static final String APP_USER = "mqm"; // Windows user name that application uses to connect to MQ
private static final String APP_PASSWORD = "Kion2018"; // Windows user password associated with APP_USER
private static final String QUEUE_NAME = "Q2"; // Queue that the application uses to put and get messages to and from
/**
* Main method
*
* #param args
*/
public static void main(String[] args) {
// Variables
JMSContext context = null;
Destination destination = null;
JMSProducer producer = null;
JMSConsumer consumer = null;
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, HOST);
cf.setIntProperty(WMQConstants.WMQ_PORT, PORT);
cf.setStringProperty(WMQConstants.WMQ_CHANNEL, CHANNEL);
cf.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT);
cf.setStringProperty(WMQConstants.WMQ_QUEUE_MANAGER, QMGR);
cf.setStringProperty(WMQConstants.WMQ_APPLICATIONNAME, "JmsPutGet (JMS)");
cf.setBooleanProperty(WMQConstants.USER_AUTHENTICATION_MQCSP, true);
cf.setStringProperty(WMQConstants.USERID, APP_USER);
cf.setStringProperty(WMQConstants.PASSWORD, APP_PASSWORD);
//cf.setStringProperty(WMQConstants.WMQ_SSL_CIPHER_SUITE, "*TLS12");
// Create JMS objects
context = cf.createContext();
destination = context.createQueue("queue:///" + QUEUE_NAME);
// Read given file
File myObj = new File("C:\\Users\\Lesego\\OneDrive\\Documents\\Test Files\\application.xml");
Scanner myReader = new Scanner(myObj);
String msg = "";
while (myReader.hasNextLine()) {
String data = myReader.nextLine();
msg = msg + data;
}
myReader.close();
TextMessage message = context.createTextMessage(msg);
producer = context.createProducer();
producer.send(destination, message);
System.out.println("Sent message:\n" + message);
consumer = context.createConsumer(destination); // autoclosable
String receivedMessage = consumer.receiveBody(String.class, 15000); // in ms or 15 seconds
System.out.println("\nReceived message:\n" + receivedMessage);
recordSuccess();
} catch (JMSException jmsex) {
recordFailure(jmsex);
} catch (FileNotFoundException e) {
System.out.println("File not found.");
e.printStackTrace();
}
System.exit(status);
} // end main()
/**
* Record this run as successful.
*/
private static void recordSuccess() {
System.out.println("SUCCESS");
status = 0;
return;
}
/**
* Record this run as failure.
*
* #param ex
*/
private static void recordFailure(Exception ex) {
if (ex != null) {
if (ex instanceof JMSException) {
processJMSException((JMSException) ex);
} else {
System.out.println(ex);
}
}
System.out.println("FAILURE");
status = -1;
return;
}
/**
* Process a JMSException and any associated inner exceptions.
*
* #param jmsex
*/
private static void processJMSException(JMSException jmsex) {
System.out.println(jmsex);
Throwable innerException = jmsex.getLinkedException();
if (innerException != null) {
System.out.println("Inner exception(s):");
}
while (innerException != null) {
System.out.println(innerException);
innerException = innerException.getCause();
}
return;
}
I am trying to write a naive Kafka Producer using Java. The application accepts two inputs:
Kafka topic name to which messages are to be produced
Path of file containing messages to be produced to Kafka
I wrote the following code. When I run it, I see that the System.out.println statements print the expected values but messages are not produced to Kafka for some reason. What should I change to make it work?
package com.myname.kafka.producer;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.Properties;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord;
public class NaiveKafkaProducer {
private static final Properties properties = new Properties();
private static Producer<String, String> producer;
private static String topic;
private static BufferedReader br;
static {
properties.put("bootstrap.servers", "localhost:9092");
properties.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
properties.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
properties.put("request.required.acks", "all");
System.out.println("Creating Kafka producer with the following properties :: " + properties);
producer = new KafkaProducer<>(properties);
}
#SuppressWarnings("resource")
public static void main(String[] args) throws IOException {
try {
if(args.length != 0) {
topic = args[0];
File file = new File(args[1]);
br = new BufferedReader((Reader) new FileReader(file));
}
} catch (Exception e) {
System.out.println("Check input arguments. Error thrown while populating arguments to local variables");
e.printStackTrace();
}
String msg;
while ((msg = br.readLine()) != null) {
System.out.println("Message to publish : " + msg);
System.out.println("Topic : " + topic);
producer.send(new ProducerRecord<String, String>(topic, "", msg));
}
return;
}
}
Surprisingly the following code works (in which I have hard-coded everything):
package com.myname.kafka.producer;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.Properties;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord;
public class NaiveKafkaProducer {
private static final Properties properties = new Properties();
private static Producer<String, String> producer;
private static String topic;
private static BufferedReader br;
static {
properties.put("bootstrap.servers", "localhost:9092");
properties.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
properties.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
properties.put("request.required.acks", "all");
System.out.println("Creating Kafka producer with the following properties :: " + properties);
producer = new KafkaProducer<>(properties);
}
public static void main(String[] args) throws IOException {
try {
String[] msgs = new String[2];
msgs[0] = "message 1";
msgs[1] = "message 2";
topic = "mytopic"
for(String msg:msgs){
producer.send(new ProducerRecord<String, String>(topic, "", msg));
}
producer.close();
} catch (Exception e) {
System.out.println("Exception caught in main method while trying to produce the messages to Kafka");
e.printStackTrace();
}
}
}
there is a critial method invoked in the second snippet and missing in the first
producer.close();
from documenttion for that method:
Close this producer. This method blocks until all previously sent requests complete.
When you invoke method produce, it doesn't mean in reality that the message was produced. Method returns you future. You can wait for each message to be produced by invoking get() on each result of produce method.
I have this sender class which is sending messages to myQueue.
Sender.java
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.commons.collections.Factory;
public class Sender {
private ConnectionFactory factory = null;
private Connection connection = null;
private Session session = null;
private Destination destination = null;
private MessageProducer producer = null;
String [] messages = new String[] {"Hello ...My name is vaniiiiiiiiiii tanejaaaaaaaaaaaaaa",
"Hello ...My name is priyanka tanejaaaaaaaaaaaaaa",
"Hello ...My name is rahul tanejaaaaaaaaaaaaaa",
"Hello ...My name is popo tanejaaaaaaaaaaaaaa"};
public void sendMessage(){
factory = new ActiveMQConnectionFactory(
"tcp://localhost:61619");
try {
connection= factory.createConnection();
connection.start();
session= connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
destination=session.createQueue("Parul");
producer = session.createProducer(destination);
TextMessage message = session.createTextMessage();
for(int i=0;i<messages.length;i++){
message.setText(messages[i]);
System.out.println("Sent: " + message.getText());
producer.send(message);
}
} catch (JMSException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
Sender sender = new Sender();
sender.sendMessage();
}
}
My message is getting published to activemq now we want to read messages from activemq. So i have written class Consumer.
Consumer.java
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.camel.Main;
public class Reciever implements MessageListener{
private ConnectionFactory factory;
private Connection connection;
private Session session;
private Destination destination;
private MessageConsumer consumer = null;
Reciever(){
}
void recieveMessage(){
factory= new ActiveMQConnectionFactory("tcp://localhost:61619");
try {
connection=factory.createConnection();
connection.start();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
System.out.println("session started");
destination=session.createQueue("Parul");
consumer = session.createConsumer(destination);
System.out.println("Consumer created");
while (true) {
System.out.println("About to read");
Message msg = consumer.receive(5000);
if (msg instanceof TextMessage) {
TextMessage tm = (TextMessage) msg;
System.out.println(tm.getText());
}
else{
System.out.println("Queue Empty");
connection.stop();
break;
}
}
} catch (JMSException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
Reciever reciever = new Reciever();
reciever.recieveMessage();
}
}
But my consumer is not able to read message from queue. What is the issue. Can you help me out in this.I want to read all 4 messsages at same time.
I've tested JMS messages sending serially and concurrently(5 threads send jms messages concurrently from the producer).
When I send 100 messages concurrently, few messages payload at the receiving end are NULL. When sent serially there is no issue.
Do I need to setup a session pool or use MDB at the consumer side to handle the messages concurrently? The setup of the JMS is good, because we are receiving messages. Am I missing anything here?
Short description of the pproject setup:
Publisher is a stateless session bean
Weblogic 8.1 jms server connection factory and destination are retrieved through
JNDI
Consumer is a java class which subscribes to this server JMS queue
and performs the tasks. (this is not a MDB or a Threaded class, listens to the queue
asynchronously)
EDITED
JmsConsumer
package net;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import java.util.Hashtable;
import javax.jms.ExceptionListener;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueReceiver;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
public class ReadJMS implements MessageListener, ExceptionListener {
public final static String JNDI_FACTORY = "weblogic.jndi.WLInitialContextFactory";
public final static String PROVIDER_URL = "t3://address:7003";
public final static String JMS_FACTORY = "MSS.QueueConnectionFactory";
public final static String QUEUE = "jms.queue";
#SuppressWarnings("null")
public void receiveMessage() throws Exception {
// System.out.println("receiveMessage()..");
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
env.put(Context.PROVIDER_URL, PROVIDER_URL);
// Define queue
QueueReceiver qreceiver = null;
QueueSession qsession = null;
QueueConnection qcon = null;
ReadJMS async = new ReadJMS();
try {
InitialContext ctx = new InitialContext(env);
QueueConnectionFactory qconFactory = (QueueConnectionFactory) ctx
.lookup(JMS_FACTORY);
qcon = qconFactory.createQueueConnection();
qcon.setExceptionListener(async);
qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = (Queue) ctx.lookup(QUEUE);
qreceiver = qsession.createReceiver(queue);
qreceiver.setMessageListener(async);
qcon.start();
System.out.println("readingMessage()..");
// TextMessage msg = (TextMessage) qreceiver.receive();
// System.out.println("Message read from " + QUEUE + " : "
// + msg.getText());
// msg.acknowledge();
} catch (Exception ex) {
ex.printStackTrace();
}
// } finally {
// if (qreceiver != null)
// qreceiver.close();
// if (qsession != null)
// qsession.close();
// if (qcon != null)
// qcon.close();
// }
}
public static void main(String[] args) throws Exception {
ReadJMS test = new ReadJMS();
System.out.println("init");
test.receiveMessage();
while (true) {
Thread.sleep(10000);
}
}
public void onException(JMSException arg0) {
System.err.println("Exception: " + arg0.getLocalizedMessage());
}
public synchronized void onMessage(Message arg0) {
try {
if(((TextMessage)arg0).getText() == null || ((TextMessage)arg0).getText().trim().length()==0){
System.out.println(" " + QUEUE + " : "
+ ((TextMessage) arg0).getText());
}
System.out.print(".");
PrintWriter out = new PrintWriter(new BufferedWriter(
new FileWriter("Output.txt", true)));
Date now = new Date();
out.println("message: "+now.toString()+ " - "+((TextMessage)arg0).getText()+"");
out.close();
} catch (JMSException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
WriteJms
package net;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Hashtable;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
public class WriteJMS {
public final static String JNDI_FACTORY = "weblogic.jndi.WLInitialContextFactory";
public final static String PROVIDER_URL = "t3://url:7003";
public final static String JMS_FACTORY = "MSS.QueueConnectionFactory";
public final static String QUEUE = "jms.queue";
#SuppressWarnings("unchecked")
public void sendMessage() throws Exception {
#SuppressWarnings("rawtypes")
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
env.put(Context.PROVIDER_URL, PROVIDER_URL);
// Define queue
QueueSender qsender = null;
QueueSession qsession = null;
QueueConnection qcon = null;
try {
InitialContext ctx = new InitialContext(env);
QueueConnectionFactory qconFactory = (QueueConnectionFactory) ctx
.lookup(JMS_FACTORY);
qcon = qconFactory.createQueueConnection();
qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = (Queue) ctx.lookup(QUEUE);
TextMessage msg = qsession.createTextMessage();
msg.setText("<eventMessage><eventId>123</eventId><eventName>123</eventName><documentNumber>123</documentNumber><customerId>123</customerId><actDDTaskDate>123</actDDTaskDate><taskStatusErrorMessage>123</taskStatusErrorMessage></eventMessage>");
qsender = qsession.createSender(queue);
qsender.send(msg);
System.out.println("Message [" + msg.getText()
+ "] sent to Queue: " + QUEUE);
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (qsender != null)
qsender.close();
if (qsession != null)
qsession.close();
if (qcon != null)
qcon.close();
}
}
}
Reusing a session across multiple threads is notoriously forbidden. But you don't do this. You create everything (connection session and producer) anew for each message. That is inefficient, but not incorrect and should not cause these errors. The code you give us looks good to me.
I am a little surprised that no exceptions occur at the sending side. Can you give some more details about the JMS implementation? Perhaps there's more information in the message broker's log?
Have you counted the messages and does the number received equal the amount sent? Could someone else be sending messages to the same queue?
I am new to storm i am using rabbitmq within my spout that recieves tuples from some queue and there is a client running one some other machine that inserts tuples to that queue I ran a simple rabbitmq example program that works fine but when i am using it within storm spout it gest blocked at
connection = factory.newConnection();
even though my rabbitmq server is also running and on the same machine when i run example code it runs successfully.
print statements print to the statement
System.out.println(" setting host to 192.168.8.218..... ");
below is my complete spout class.
package storm.starter.spout;
import backtype.storm.spout.SpoutOutputCollector;
import backtype.storm.task.TopologyContext;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.topology.base.BaseRichSpout;
import backtype.storm.tuple.Fields;
import backtype.storm.tuple.Values;
import backtype.storm.utils.Utils;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.QueueingConsumer;
import java.util.Map;
import java.util.Random;
import java.net.*;
import java.io.*;
import java.lang.Exception;
import java.io.IOException;
public class RabbitmqSpout extends BaseRichSpout {
SpoutOutputCollector _collector;
public final static String QUEUE_NAME = "record";
ConnectionFactory factory;
Connection connection;
Channel channel;
QueueingConsumer consumer;
#Override
public void open(Map conf, TopologyContext context, SpoutOutputCollector collector)
{
_collector = collector;
System.out.println(" [*] Intilization of spout..... ");
try
{
factory = new ConnectionFactory();
System.out.println(" creating connection factory..... ");
factory.setHost("192.168.8.96");
System.out.println(" setting host to 192.168.8.218..... ");
connection = factory.newConnection();
System.out.println(" creating new connection..... ");
channel = connection.createChannel();
System.out.println(" creating new channel..... ");
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
System.out.println(" Declaring queue..... ");
System.out.println(" [*] Waiting for messages. ");
}
catch(Exception exception)
{
System.out.println("Exception occurred. "+exception.getMessage());
}
}
#Override
public void nextTuple()
{
System.out.println("In wait of tuples.... ");
try
{
consumer = new QueueingConsumer(channel);
System.out.println(" trying to consume..... ");
channel.basicConsume(QUEUE_NAME, true, consumer);
while (true)
{
System.out.println(" trying to deliver..... ");
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println(" getting string..... ");
System.out.println(" [x] Received '" + message + "'");
System.out.print("emitting Rabbitmq Queue tuple");
_collector.emit(new Values(message));
System.out.print("emitted Rabbitmq Queue tuple");
}
}
catch(IOException io)
{
System.out.println("Exception occurred. ");
}
catch(Exception exception)
{
System.out.println("Exception occurred. ");
}
}
#Override
public void ack(Object id) {
}
#Override
public void fail(Object id)
{
}
#Override
public void declareOutputFields(OutputFieldsDeclarer declarer)
{
declarer.declare(new Fields("record"));
}
}
connection = factory.newConnection()
Is done in RabbitMQConsumer() method of RabbitMQConsumer class because data is taken out of the queue by RabbitMQ consumer and that in turn gives data to your RabbitMQ spout.
please refer:
[https://github.com/ppat/storm-rabbitmq/tree/master/src/main/java/io/latent/storm/rabbitmq][1]