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.
Related
I guess it is kind of a standard knowledge question, but will current_session run threaded or not?
ActiveMQSession current_session = (ActiveMQSession) connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Thread sessionThreads = new Thread(current_session);
sessionThreads.start();
If not, can please someone show me a code example how I run a session threaded?
What I want is concurrent sessions with producers/consumers which write/listen to their specific queues. I already tried to write a custom Thread by passing the connection to the thread, but when I created Producers I run into an error, 'that I can't start a Producer on an unregistered session'.
There is no constructor for java.lang.Thread that will accept a org.apache.activemq.ActiveMQSession object. Your code won't even compile let alone run.
Here's a simple client that will create threads for producing and consuming messages:
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.naming.Context;
import javax.naming.InitialContext;
public class MyMultiThreadedApp {
class MyConsumer extends Thread {
private final Connection connection;
private final Destination destination;
MyConsumer(Connection connection, Destination destination) {
this.connection = connection;
this.destination = destination;
}
#Override
public void run() {
try (Session session = connection.createSession(Session.AUTO_ACKNOWLEDGE)) {
MessageConsumer messageConsumer = session.createConsumer(destination);
connection.start();
Message message = messageConsumer.receive(5000);
if (message == null) {
System.out.println("Did not receive message within the allotted time.");
return;
}
System.out.println("Received message: " + message);
} catch (Throwable e) {
e.printStackTrace();
return;
}
}
}
class MyProducer extends Thread {
private final Connection connection;
private final Destination destination;
MyProducer(Connection connection, Destination destination) {
this.connection = connection;
this.destination = destination;
}
#Override
public void run() {
try (Session session = connection.createSession(Session.AUTO_ACKNOWLEDGE)) {
MessageProducer messageProducer = session.createProducer(destination);
messageProducer.send(session.createTextMessage("My message"));
System.out.println("Sent message");
} catch (Throwable e) {
e.printStackTrace();
return;
}
}
}
public static void main(String... args) throws Exception {
MyMultiThreadedApp myMultiThreadedApp = new MyMultiThreadedApp();
InitialContext initialContext = null;
initialContext = new InitialContext();
Queue queue = (Queue) initialContext.lookup("queue/exampleQueue");
ConnectionFactory cf = (ConnectionFactory) initialContext.lookup("ConnectionFactory");
Connection connection = cf.createConnection();
Thread myConsumer = myMultiThreadedApp.runConsumer(connection, queue);
Thread myProducer = myMultiThreadedApp.runProducer(connection, queue);
myConsumer.join();
myProducer.join();
}
private Thread runConsumer(Connection connection, Destination destination) {
MyConsumer myConsumer = new MyConsumer(connection, destination);
myConsumer.start();
return myConsumer;
}
private Thread runProducer(Connection connection, Destination destination) {
MyProducer myProducer = new MyProducer(connection, destination);
myProducer.start();
return myProducer;
}
}
How is it possible to enqueue messages to different queues using a persistent connection / session in ActiveMQ?
What I have done:
public class ActiveMQProducer {
private static final Logger LOGGER = Logger.getLogger(ActiveMQProducer.class);
private Connection connection;
private MessageProducer producer;
private Session session;
String activeMQConnection;
public ActiveMQProducer() throws ConfigurationException, JMSException {
activeMQConnection = ActiveMQPropertyManagerFactory.getInstance().getString("active.mq.url");
}
public void setupActiveMQ(String queueName) throws JMSException {
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(activeMQConnection);
factory.setRejectedTaskHandler(new ThreadPoolExecutor.CallerRunsPolicy());
connection = factory.createConnection();
connection.start();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = session.createQueue(queueName);
producer = session.createProducer(queue);
}
public void getConnection(String queueName) throws JMSException {
if (connection == null || session == null) {
Object object = new Object();
synchronized (object) {
setupActiveMQ(queueName);
}
}
}
public <T extends Serializable> T sendToActiveMQ(String queueName, T t) throws JMSException {
getConnection(queueName);
ObjectMessage message = session.createObjectMessage(t);
producer.send(message);
return null;
}
public void sendMessageToActiveMQ(String queueName, String message) throws JMSException {
getConnection(queueName);
TextMessage toSend = session.createTextMessage(message);
producer.send(toSend);
}
}
I have realized by using this and sending a message to a different queue eventually ActiveMQ runs out of connections because I never close the connection or session:
org.apache.activemq.transport.tcp.ExceededMaximumConnectionsException: Exceeded the maximum number of allowed client connections.
What would be the proper way to handle this? I have about 5 queues I have to send different messages to, should I open a new connection, enqueue and close the connection, is there anyway to keep the session / connections persistent?
Thanks.
here some solutions :
1 Producer per destination :
import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ThreadPoolExecutor;
import javax.jms.Connection;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.ConfigurationException;
import org.apache.log4j.Logger;
public class ActiveMQProducer {
private static final Logger LOGGER = Logger.getLogger(ActiveMQProducer.class);
private Connection connection;
private Session session;
String activeMQConnection;
Map<String, MessageProducer> producers = Collections.synchronizedMap(new HashMap<String, MessageProducer>());
Thread shutdownHook = new Thread(new Runnable() {
#Override
public void run() {
close();
}
});
public ActiveMQProducer() throws ConfigurationException, JMSException {
activeMQConnection = ActiveMQPropertyManagerFactory.getInstance().getString("active.mq.url");
setupActiveMQ();
Runtime.getRuntime().addShutdownHook(shutdownHook);
}
public void setupActiveMQ() throws JMSException {
close();
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(activeMQConnection);
factory.setRejectedTaskHandler(new ThreadPoolExecutor.CallerRunsPolicy());
connection = factory.createConnection();
connection.start();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
}
#Override
protected void finalize() throws Throwable {
close();
super.finalize();
}
public void close() {
if (connection != null) {
try {
connection.close();
} catch (Exception e) {
}
connection = null;
}
}
public void getConnection() throws JMSException {
if (connection == null || session == null) {
setupActiveMQ();
}
}
public MessageProducer getProducer(String queueName) throws JMSException {
getConnection();
MessageProducer producer = producers.get(queueName);
if (producer == null) {
Queue queue = session.createQueue(queueName);
producer = session.createProducer(queue);
producers.put(queueName, producer);
}
return producer;
}
public <T extends Serializable> T sendToActiveMQ(String queueName, T t) throws JMSException {
MessageProducer producer = getProducer(queueName);
ObjectMessage message = session.createObjectMessage(t);
producer.send(message);
return null;
}
public void sendMessageToActiveMQ(String queueName, String message) throws JMSException {
MessageProducer producer = getProducer(queueName);
TextMessage toSend = session.createTextMessage(message);
producer.send(toSend);
}
}
1 Producer for all destinations :
import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ThreadPoolExecutor;
import javax.jms.Connection;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.ConfigurationException;
import org.apache.log4j.Logger;
public class ActiveMQProducer2 {
private static final Logger LOGGER = Logger.getLogger(ActiveMQProducer2.class);
private Connection connection;
private Session session;
String activeMQConnection;
Map<String, Destination> destinations = Collections.synchronizedMap(new HashMap<String, Destination>());
private MessageProducer producer;
Thread shutdownHook = new Thread(new Runnable() {
#Override
public void run() {
close();
}
});
public ActiveMQProducer2() throws ConfigurationException, JMSException {
activeMQConnection = ActiveMQPropertyManagerFactory.getInstance().getString("active.mq.url");
setupActiveMQ();
Runtime.getRuntime().addShutdownHook(shutdownHook);
}
public void setupActiveMQ() throws JMSException {
close();
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(activeMQConnection);
factory.setRejectedTaskHandler(new ThreadPoolExecutor.CallerRunsPolicy());
connection = factory.createConnection();
connection.start();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
producer = session.createProducer(session.createTemporaryQueue());
}
#Override
protected void finalize() throws Throwable {
close();
super.finalize();
}
public void close() {
if (connection != null) {
try {
connection.close();
} catch (Exception e) {
}
connection = null;
}
}
public void getConnection() throws JMSException {
if (connection == null || session == null) {
setupActiveMQ();
}
}
public Destination getDestination(String queueName) throws JMSException {
getConnection();
Destination destination = destinations.get(queueName);
if (destination == null) {
destination = session.createQueue(queueName);
destinations.put(queueName, destination);
}
return destination;
}
public <T extends Serializable> T sendToActiveMQ(String queueName, T t) throws JMSException {
Destination destination = getDestination(queueName);
ObjectMessage message = session.createObjectMessage(t);
producer.send(destination, message);
return null;
}
public void sendMessageToActiveMQ(String queueName, String message) throws JMSException {
Destination destination = getDestination(queueName);
TextMessage toSend = session.createTextMessage(message);
producer.send(destination, toSend);
}
}
i am implementing the onMessgae () method of MessageListner Class but its not working even i am putting the debug point inside this method but debugger also not goes inside this method.
Use this method to receive the message from Queue.
Below is my code for receiving the message but its not giving any message when i am sending the message through sender class and its message goes to JMS Server and shows like this way on server
Name Server DestiCurrent MessagesCurrent MessagesPending MessagesReceived JMSServer-0 AdminServer 3 15 1 2
Code for Reciver:
{
import java.util.Hashtable;
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;
import javax.naming.NamingException;
public class QueueReceive implements MessageListener {
public final static String Server="t3://localhost:7001";
public final static String JNDI_FACTORY = "weblogic.jndi.WLInitialContextFactory";
public final static String JMS_FACTORY = "CF1";
enter code here
public final static String QUEUE = "Queue1";
private QueueConnectionFactory qconFactory;
private QueueConnection qcon;
private QueueSession qsession;
private QueueReceiver qreceiver;
private Queue queue;
private boolean quit = false;
String s1 = "avanish";
public void init(Context ctx, String queueName) throws NamingException, JMSException {
qconFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY);
qcon = qconFactory.createQueueConnection();
qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
queue = (Queue) ctx.lookup(queueName);
qreceiver = qsession.createReceiver(queue);
qreceiver.setMessageListener(this);
qcon.start();
System.out.println(qreceiver.receive());
}
public void close() throws JMSException {
qreceiver.close();
qsession.close();
qcon.close();
}
public static void main(String[] args) throws Exception {
/*if (args.length != 1) {
System.out.println("Usage: java examples.jms.queue.QueueReceive WebLogicURL");
return;
}*/
InitialContext ic = getInitialContext();
QueueReceive qr = new QueueReceive();
qr.init(ic, QUEUE);
System.out.println("JMS Ready To Receive Messages (To quit, send a \"quit\" message).");
synchronized (qr) {
while (!qr.quit) {
try {
qr.wait();
} catch (InterruptedException ie) {
}
}
}
qr.close();
}
private static InitialContext getInitialContext() throws NamingException {
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
env.put(Context.PROVIDER_URL, Server);
return new InitialContext(env);
}
#Override
public void onMessage(Message msg) {
try {
String msgText;
if(msg instanceof TextMessage){
msgText = ((TextMessage) msg).getText();
}
else{
msgText = msg.toString();
}
System.out.println("reciver msg" + msgText);
if(msgText.equalsIgnoreCase("quit")){
synchronized (this) {
quit= true;
this.notifyAll();
}
}
} catch (JMSException e) {
System.err.println("Exception" + e.getMessage());
}
}
}
}
Code for Sender:
{
import javax.jms.JMSException;
import javax.jms.Queue;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Hashtable;
import javax.jms.*;
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;
import javax.naming.NamingException;
public class QueueSend {
public final static String Server="t3://localhost:7001";
public final static String JNDI_FACTORY = "weblogic.jndi.WLInitialContextFactory";
public final static String JMS_FACTORY = "CF1";
public final static String QUEUE = "Queue1";
// public final static String QUEUE = "DQ";
private QueueConnectionFactory qconFactory;
private QueueConnection qcon;
private QueueSession qsession;
private QueueSender qsender;
private Queue queue;
private TextMessage msg;
public void init(Context ctx, String queueName) throws NamingException, JMSException
{
qconFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY);
qcon = qconFactory.createQueueConnection();
qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
queue = (Queue) ctx.lookup(queueName);
qsender = qsession.createSender(queue);
msg = qsession.createTextMessage();
qcon.start();
}
public void send(String message) throws JMSException {
msg.setText(message);
//msg.acknowledge();
qsender.setPriority(9);
qsender.send(msg);
}
public void close() throws JMSException {
qsender.close();
qsession.close();
qcon.close();
}
public static void main(String[] args) throws Exception {
InitialContext ic = getInitialContext();
QueueSend qs = new QueueSend();
qs.init(ic, QUEUE);
readAndSend(qs);
qs.close();
}
private static void readAndSend(QueueSend qs) throws IOException, JMSException
{
BufferedReader msgStream = new BufferedReader(new InputStreamReader(System.in));
String line = null;
boolean quitNow = false;
do {
System.out.print("Enter message (\"quit\" to quit): \n");
line = msgStream.readLine();
if (line != null && line.trim().length() != 0) {
qs.send(line);
System.out.println("JMS Message Sent: " + line + "\n");
quitNow = line.equalsIgnoreCase("quit");
}
} while (!quitNow);
}
private static InitialContext getInitialContext()
throws NamingException
{
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
env.put(Context.PROVIDER_URL, Server);
return new InitialContext(env);
}
}
}
Insted of using MessageListener i used below lines of code and getting the exact message from queue
queue = (Queue) ctx.lookup(queueName);
qreceiver = qsession.createReceiver(queue);
message = qreceiver.receiveNoWait();
its successfully received the messages from Queue.
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?
AS: Jboss 7
Let's say I have a queue defined in file:
{JBOSS7_HOME}/standalone/configuration/standalone.xml
<jms-queue name="myQueue">
<entry name="java:/queue/myQueue"/>
<durable>true</durable>
</jms-queue>
Question:
How to check programatically number of messages in queue?
You can use following code.
String jndiFactory="org.jboss.naming.remote.client.InitialContextFactory";
String jmsFactory="jms/RemoteConnectionFactory";
String queueName="jms/queue/MyQueue";
String providerUrl="remote://ipAddress:4447";
String username="testuser";
String password="testpassword";
Session qsession = null;
Connection qcon = null;
QueueBrowser browser = null;
ConnectionFactory qconFactory;
InitialContext ctx = null;
int depth=0;
try{
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, jndiFactory);
env.put(Context.PROVIDER_URL, providerUrl);
env.put(Context.SECURITY_PRINCIPAL, username);
env.put(Context.SECURITY_CREDENTIALS, password);
ctx = new InitialContext(env);
qconFactory = (QueueConnectionFactory) ctx.lookup(jmsFactory);
qcon = qconFactory.createConnection(username, password);
qsession = qcon.createSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = (Queue) ctx.lookup(qName);
browser = qsession.createBrowser(queue);
qcon.start();
for (Enumeration e = browser.getEnumeration(); e.hasMoreElements();e.nextElement()) {
depth++;
}
}catch(Exception e){
System.out.println("Some exception :"+e.toString());
}finally {
try {
if(qcon !=null)
qcon.close();
if(qsession !=null)
qsession.close();
if(browser !=null)
browser.close();
} catch (Exception e) {
System.out.println("Some exception :"+e.toString());
}
}
If you want to use an in app approach, I would use the following Session Bean:
import java.util.Enumeration;
import java.util.HashMap;
import javax.annotation.Resource;
import javax.ejb.Local;
import javax.ejb.Remote;
import javax.ejb.SessionContext;
import javax.ejb.Stateless;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.QueueBrowser;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.transaction.UserTransaction;
import org.apache.log4j.Logger;
import com.amway.dms.dataobject.event.EventHeader;
import com.amway.dms.dbaccess.event.EventHeaderAccess;
import com.amway.dms.util.common.DBUtils;
import com.amway.dms.util.common.StringUtil;
#Stateless
#TransactionManagement(TransactionManagementType.BEAN)
#Local(SBDMSIntegrationsInternalSenderLocal.class)
#Remote(SBDMSIntegrationsInternalSenderRemote.class)
public class SBQueuCount implements SBQueuCountRemote {
private static final String CONNECTION_FACTORY_NAME = "jms/testCF";
private static final String DESTINATION_NAME = "jms/testQueue";
// jms
#Resource(name = CONNECTION_FACTORY_NAME, mappedName = CONNECTION_FACTORY_NAME)
private ConnectionFactory connectionFactory;
#Resource(name = DESTINATION_NAME, mappedName = DESTINATION_NAME)
private Queue queue;
private static final Logger logger = Logger.getLogger(SBQueuCount.class);
#Override
public void getQueueDetails(String noOfMsgToPrint) {
logger.info("Begin getQueueDetails: noOfMsgToPrint:" + noOfMsgToPrint);
Connection connection;
Session session = null;
try {
connection = connectionFactory.createConnection();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
int numOnQueue = 0;
QueueBrowser outQueueBrowser = null;
outQueueBrowser = session.createBrowser(queue);
if (outQueueBrowser == null) {
logger.info("outQueueBrowser is null");
}
Enumeration messagesOnQ = outQueueBrowser.getEnumeration();
if (messagesOnQ.hasMoreElements())
logger.info("Queue has elements");
while (messagesOnQ.hasMoreElements()) {
// TextMessage textMessage = (TextMessage) messagesOnQ.nextElement();
// if (StringUtil.isNumeric(noOfMsgToPrint)) {
// if (numOnQueue <= Integer.parseInt(noOfMsgToPrint)) {
// logger.info("EventHeader Message: " + textMessage.toString());
// }
// }
numOnQueue++;
}
outQueueBrowser.close();
logger.info("End number of messages on queue: " + numOnQueue);
} catch (JMSException e) {
logger.info("Error " + e);
e.printStackTrace();
}
}
}