OnCompletion(message) of javax.jms.CompletionListener is not getting executed after message sent Successfully - activemq-artemis

I'm using ActiveMQ Artemis for a simple chat application. The message sending is working fine, and the consumer is consuming the message by executing onMessage(). But neither the onCompletion() nor the onException() methods of javax.jms.CompletionListener are not getting executed.
ConnectionFactory factory = new ActiveMQConnectionFactory("tcp://TJ12AA041-PC:61616");
Connection con = factory.createConnection();
con.start();
Session session = con.createSession(false, Session.AUTO_ACKNOWLEDGE);
Topic topic = session.createTopic("examp2");
MessageProducer producer = session.createProducer(null);
TextMessage txt = session.createTextMessage();
txt.setText("Hello Hello");
producer.send(topic, txt, new CompletionListener() {
#Override
public void onException(Message msg, Exception ex) {
System.out.println("Failed to send Messaeg : "+ex.getMessage());
}
#Override
public void onCompletion(Message msg) {
System.out.println("Message sent SuccessFully");
}
});

Related

Vertx: Timeout in message reply

I have a sender and a consumer that exchange messages:
public class Sender extends AbstractVerticle {
#Override
public void start() {
EventBus eventBus = vertx.eventBus();
eventBus.send(Constants.ADDRESS, "Hello from sender", res -> {
if (res.succeeded()) {
System.out.println("Successfully sent reply");
} else {
System.out.println("Failed to send reply." + res.cause());
}
});
eventBus.consumer(Constants.ADDRESS, msg -> System.out.println("received msg from consumer:" + msg.body()));
}
public class Consumer extends AbstractVerticle{
protected EventBus eventBus = null;
#Override
public void start() {
eventBus = vertx.eventBus();
eventBus.consumer(Constants.ADDRESS, msg -> msg.reply("Hi from consumer.", res -> {
if (res.succeeded()) {
System.out.println("Successfully sent reply");
} else {
System.out.println("Failed to send reply." + res.cause());
}
}));
}
}
I expect that when the consumer replies to the message, it will be received by the sender. However, I get a timeout:
Successfully sent reply
Failed to send reply.(TIMEOUT,-1) Timed out after waiting 30000(ms) for a reply. address: 2, repliedAddress: 1
Deployment:
public class ServiceLauncher {
private static Vertx vertx = Vertx.vertx();
public static void main(String[] args) {
vertx.deployVerticle(new Consumer(), res -> {
if (res.succeeded()) {
System.out.println("Verticle " + Consumer.NAME + " deployed.");
vertx.deployVerticle(new Sender());
System.out.println("Verticle " + Sender.NAME + " deployed.");
} else {
System.out.println("Verticle " + Consumer.NAME + " not deployed.");
}
});
}
What am I doing wrong? Thanx in advance
Update: The problem is in msg.reply() - the consumer doesn't reply to the message but I can't still figure out why.
The timeout occurs not in the sender of the request, but in its recipient.
Handler, defined in msg.reply(), waits for next reply from the sender. It is not a handler, confirming just send status.
And handler in Sender's eventBus.send() also fires when sender receives a reply.
Just remove handler in msg.reply() and modify handler eventBus.send() in Sender in the same manner:
public class Sender extends AbstractVerticle {
public static final String NAME = "SENDER";
#Override
public void start() {
EventBus eventBus = vertx.eventBus();
eventBus.send(Constants.ADDRESS, "Hello from sender", res -> {
if (res.succeeded()) {
System.out.println("Successfully received reply: " + res.result().body());
} else {
System.out.println("Failed to send reply." + res.cause());
}
});
}
}
and
public class Consumer extends AbstractVerticle {
public static final String NAME = "CONSUMER";
#Override
public void start() {
final EventBus eventBus = vertx.eventBus();
eventBus.consumer(Constants.ADDRESS, msg -> {
System.out.println("Message received");
msg.reply("Hi from consumer.");
});
}
}
And after execute you'll see:
Verticle CONSUMER deployed.
Verticle SENDER deployed.
Message received
Successfully received reply: Hi from consumer.
I had a similar issue. In my case, I was sending a non JsonObject reply. The message has to be replied to with a valid JsonObject -- not JsonArray or any other. This looks the default behaviour although the doc mentions JsonObject is not required. But the real problem in your original code snippet is that you have specified a handler for the reply's reply. The Consumer is replying successfully but the consumer is not getting a reply from Sender. See below with comment.
#Override
public void start() {
eventBus = vertx.eventBus();
eventBus.consumer(Constants.ADDRESS, msg -> msg.reply("Hi from consumer.", res -> {
if (res.succeeded()) { //this is expecting a response from Sender which never does so this will never execute.
System.out.println("Successfully sent reply");
} else { //it's not failing either so this will not execute either
System.out.println("Failed to send reply." + res.cause());
}
}));
}

Sending message to JMS (Weblogic)

When I run the following code it seems that the message was sent to the queue but I can not see anythyng on the queue. There is no error, exception durig executing my code.
I use Weblogic server.
This is my code:
private InitialContext getInitialContext() throws NamingException {
Hashtable env = new Hashtable();
env.put(InitialContext.INITIAL_CONTEXT_FACTORY, contextFactory);
env.put(InitialContext.PROVIDER_URL, providerUrl);
env.put(Context.SECURITY_PRINCIPAL, username);
env.put(Context.SECURITY_CREDENTIALS, password);
return new InitialContext(env);
}
public ConnectionFactory getConnectionFactory(InitialContext context) throws NamingException {
return (ConnectionFactory) context.lookup(ConnectionParameter.JMS_CONNECTION_FACTORY_JNDI);
}
public void send() throws NamingException, JMSException {
InitialContext context = getInitialContext();
Destination destination = (Destination) context.lookup("jms/dpdr/mhcinterface/arnoldQueue");
try (Connection connection = getConnectionFactory(context).createConnection();){
Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
MessageProducer sender = session.createProducer(destination);
Message message = session.createTextMessage("work order complete!");
sender.send(message);
session.commit();
session.close();
}
context.close();
System.out.println("-- end --");
}
Any idea what is wrong here please?
It looks like you forgot to call connection.start() before sending your message. You can do it like below:
MessageProducer sender = session.createProducer(destination);
connection.start();
Message message = session.createTextMessage("work order complete!");

Xmpp Smack Chat not able to send and receiving message

I have tried to establish chat connection between two users using xmpp and OpenFire. But i am not able to send and receive message. I have pasted my code below for reference. Any help will be very helpful.
I established a connection with Smack by
XMPPTCPConnectionConfiguration.Builder config = XMPPTCPConnectionConfiguration.builder();
config.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
config.setUsernameAndPassword("admin", "admin");
config.setServiceName("172.21.4.199");
config.setHost("172.21.4.199");
config.setPort(5222);
config.setDebuggerEnabled(true);
config.setConnectTimeout(50000);
XMPPTCPConnection connection = new XMPPTCPConnection(config.build());
XMPPTCPConnection.setUseStreamManagementResumptiodDefault(true);
XMPPTCPConnection.setUseStreamManagementDefault(true);
try {
connection.setPacketReplyTimeout(50000);
connection.connect();
Log.d(TAG, "SetupDefaults -- Connected");
} catch (Exception e) {
e.printStackTrace();
Log.d(TAG, "SetupDefaults -- Connection failed exc: "+e);
}
and its gets succesfully connected. And i try to send a chat by using
ChatManager chatManager = ChatManager.getInstanceFor(connection);
Chat chat = chatManager.createChat("user2#server.local", new ChatMessageListener() {
#Override
public void processMessage(Chat chat, Message message) {
System.out.println("processMessage -- Sent message: " + message);
}
});
try {
chat.sendMessage("Hai.. Lets we chat!");
}catch (Exception e){
Log.d(TAG, "sendChat Exc: "+e.toString());
}
But i couldn't find that processMessage gets triggered. Because that S.O.P doesn't gets triggered. But i gets
SMACK: SENT (0): Hai.. Lets we chat!
SMACK: RECV (0): Hai.. Lets we chat!
in my console while sending a chat.
Simillarly i use,
PacketListener packetListener = new PacketListener() {
#Override
public void processPacket(Stanza packet) throws SmackException.NotConnectedException {
Message message = (Message)packet;
String from = message.getFrom();
String body = message.getBody();
System.out.println("Message from: " + from + " " + body);
}
};
connection.addPacketListener(packetListener, filter);
to receive the chat. But processPacket also doesn't gets triggered.
PacketListner it's something much more general to handle stanzas, it's not what you really need. You just need a ChatMessageListner
ChatManager chatManager;
chatManager = ChatManager.getInstanceFor(connection);
chatManager.addChatListener(
**new ChatManagerListener() {
#Override
public void chatCreated(Chat chat, boolean createdLocally)
{
if (!createdLocally)
{
chat.addMessageListener(new IncomingMessageListener());;
}
}
})**;
Basic implementation:
class IncomingMessageListener implements ChatMessageListener {
#Override
public void processMessage(Chat arg0, Message message) {
String from = message.getFrom();
String body = message.getBody();
if (body != null)
{
System.out.println(String.format("============ Received message '%1$s' from %2$s\n============", body, from));
guiUpdate.displayMessage(body); /* custom method */
}
else
{
System.out.println("SYSTEM: ping");
}
}

onMessage change message state from receive and purge in weblogic

I have a distributed queue on Weblogic. Messages are read from the queue using JMS onMessage() function. However the messages are not purged from the queue as long as the deployment is running. The message state string is always 'receive'. How do we ensure that the message is not picked up again in case a restart of the deployment is done?
#Override
public void onMessage(Message msg) {
try {
String msgText;
if (msg instanceof TextMessage) {
msgText = ((TextMessage) msg).getText();
} else {
msgText = msg.toString();
}
System.out.println("Message Received from Message_RESPONSE_QUEUE: " + msgText + " - " + count++);
// now send the message to queue2
InitialContext ic2 = getInitialContext2();
getMsgFromQueue qs = new getMsgFromQueue();
qs.init2(ic2, QUEUE2);
qs.send(msg, null);
} catch (JMSException jmse) {
} catch (NamingException ex) {
Logger.getLogger(getMsgFromQueue.class.getName()).log(Level.SEVERE, null, ex);
}
}
The message from the JMS queue does not get removed until JMS server receives an acknowledgement.
Here's some references that you may find useful -
http://docs.oracle.com/cd/E17904_01/web.1111/e15493/prog_details.htm#i1156227
http://docs.oracle.com/cd/E17904_01/web.1111/e15493/prog_details.htm#i1152248
http://docs.oracle.com/cd/E17904_01/web.1111/e15493/prog_details.htm#i1156227

JBoss JMS MessageConsumer waits indefinitely for response message

I am trying to create a synchronous request using JMS on JBoss
Code for MDB is:
#Resource(mappedName = "java:/ConnectionFactory")
private ConnectionFactory connectionFactory;
#Override
public void onMessage(Message message) {
logger.info("Received message for client call");
if (message instanceof ObjectMessage) {
Connection con = null;
try {
con = connectionFactory.createConnection();
con.start();
Requests requests = (Requests) ((ObjectMessage) message)
.getObject();
String response = getClient().get(getRequest(requests));
con = connectionFactory.createConnection();
Session ses = con.createSession(true, Session.AUTO_ACKNOWLEDGE);
MessageProducer producer = ses.createProducer(message
.getJMSReplyTo());
TextMessage replyMsg = ses.createTextMessage();
replyMsg.setJMSCorrelationID(message.getJMSCorrelationID());
replyMsg.setText(response);
logger.info("Sending reply to client call : " + response );
producer.send(replyMsg);
} catch (JMSException e) {
logger.severe(e.getMessage());
} finally {
if (con != null) {
try {
con.close();
} catch (Exception e2) {
logger.severe(e2.getMessage());
}
}
}
}
}
Code for client is:
#Resource(mappedName = "java:/ConnectionFactory")
private QueueConnectionFactory queueConnectionFactory;
#Resource(mappedName = "java:/queue/request")
private Queue requestQueue;
#Override
public Responses getResponses(Requests requests) {
QueueConnection connection = null;
try {
connection = queueConnectionFactory.createQueueConnection();
connection.start();
QueueSession session = connection.createQueueSession(false,
Session.AUTO_ACKNOWLEDGE);
MessageProducer messageProducer = session
.createProducer(requestQueue);
ObjectMessage message = session.createObjectMessage();
message.setObject(requests);
TemporaryQueue temp = session.createTemporaryQueue();
MessageConsumer consumer = session.createConsumer(temp);
message.setJMSReplyTo(temp);
messageProducer.send(message);
Message response = consumer.receive();
if (response instanceof TextMessage) {
logger.info("Received response");
return new Responses(null, ((TextMessage) response).getText());
}
} catch (JMSException e) {
logger.severe(e.getMessage());
} finally {
if (connection != null) {
try {
connection.close();
} catch (Exception e2) {
logger.severe(e2.getMessage());
}
}
}
return null;
}
The message is received fine on the queue, the response message is created and the MessageProducer sends the response without issue, with no errors. However the consumer just sits and waits indefinitely. I have also tried creating a separate reply queue rather then using a temporary queue and the result is the same.
I am guessing that I am missing something basic with this set up but I cannot for the life of me see anything I am doing wrong.
There is no other code, the 2 things I have read on this that can cause problems is that the connection.start() isn't called or the repsonses are going to some other different receiver, which isn't happening here (as far as I know - there are no other messaging parts to the code outside of these classes yet)
So I guess my question is, should the above code work or am I missing some fundamental understanding of the JMS flow?
So..I persevered and I got it to work.
The answer is that when I create the session, the transacted attribute in both the client and the MDB had to be set to false:
Session ses = con.createSession(true, Session.AUTO_ACKNOWLEDGE);
had to be changed to:
Session ses = con.createSession(false, Session.AUTO_ACKNOWLEDGE);
for both client and server.
I know why now! I am effectively doing the below which is taken from the Oracle JMS documentation!
If you try to use a request/reply mechanism, whereby you send a message and then try to receive a reply to the sent message in the same transaction, the program will hang, because the send cannot take place until the transaction is committed. The following code fragment illustrates the problem:
// Don’t do this!
outMsg.setJMSReplyTo(replyQueue);
producer.send(outQueue, outMsg);
consumer = session.createConsumer(replyQueue);
inMsg = consumer.receive();
session.commit();