message driven bean avec jboss 6 - ejb-3.0

Hi i want to notify my client when a critical operation is happened , so i want to use the message driven bean
i ve writen this mdb `
#MessageDriven(mappedName = "topic/MailConfirmationMdbTopic",
activationConfig = {
//#ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
//#ActivationConfigProperty(propertyName="subscriptionDurability", propertyValue="Durable"),
//#ActivationConfigProperty(propertyName="subscriptionName", propertyValue="topicmdb"),
//#ActivationConfigProperty(propertyName="clientId", propertyValue="mdbtopic-test"),
#ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"),
#ActivationConfigProperty(propertyName = "destination", propertyValue = "topic/MailConfirmationMdbTopic")
})
public class MailConfirmationMdbBean implements MessageListener {
private static final Logger log = Logger.getLogger(MailConfirmationMdbBean.class);
public MailConfirmationMdbBean(){
log.info("Initialisation de l'envoi du mail depuis MailConfirmationMdbBean");
}
public void onMessage(Message message) {
// Pour la classe de test MailConfirmationProducteur
if (message instanceof TextMessage) {
TextMessage mail = (TextMessage) message;
// L'envoi d'un mail de confirmation au client est ici simul� par l'affichage d'un message au niveau des logs.
try {
String leMail = mail.getText();
log.info(" Envoi du mail : " + leMail);
log.info(" --------------------------------------------------- ");
//sendMsg("eniejb3#gmail.com", "Confirmation de commande.", leMail);
log.info(" --------------------------------------------------- ");
log.info(" Mail envoy�.");
}
catch (JMSException e) {
e.printStackTrace();
}
} else if (message instanceof ObjectMessage) {
ObjectMessage lemessage = (ObjectMessage) message;
try {
Commande commande = (Commande)lemessage.getObject();
Client client = commande.getUtilisateurFk();
Adresse adresse = client.getAdresseFk();
String contenuMail = "Bonjour " + client.getNom() + " " + client.getPrenom() + ". \n"
+ "Votre num�ro de commande est : " + commande.getCommandeid()
+ " \n" + "Vous avez command� les articles suivants : " + " \n" ;
String lesArticles = "";
Set <Lignecommande> listeArticles = commande.getLignecommandeCollection();
for (Lignecommande lc : listeArticles){
Article article = lc.getArticleFk();
lesArticles += article.getNom() + " : " + article.getPrix() + " euros. \n" ;
}
contenuMail += lesArticles;
String ladresse =
" \n" + "Votre adresse est : "+ " \n"
+ adresse.getNumero() + " rue " + adresse.getRue() + " " + adresse.getCodepostal() + " " + adresse.getVille();
contenuMail += ladresse;
contenuMail += "\n Votre commande est en cours de traitement.";
log.info(" Envoi du mail au client: " );
log.info(" --------------------------------------------------- ");
sendMsg(client.getEmail(), "Confirmation de votre commande.", contenuMail);
log.info(" --------------------------------------------------- ");
log.info(" Mail envoy� au client.");
}
catch (MessagingException e) {
e.printStackTrace();
}
catch (NamingException e) {
e.printStackTrace();
} catch (JMSException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
protected void sendMsg(String email, String subject, String body) throws MessagingException, NamingException, UnsupportedEncodingException {
Properties props = new Properties();
InitialContext ictx = new InitialContext(props);
javax.mail.Session mailSession = (javax.mail.Session) ictx.lookup("java:/Mail");
MimeMessage message = new MimeMessage(mailSession);
message.setSubject(subject);
message.setRecipients(javax.mail.Message.RecipientType.TO, javax.mail.internet.InternetAddress.parse(email, false));
message.setText(body);
message.saveChanges();
Transport transport = mailSession.getTransport("smtp");
try {
transport.connect();
transport.sendMessage(message, message.getAllRecipients());
log.info("Message envoy�");
}
finally {
transport.close();
}
}
#PreDestroy
public void remove() {
log.info("Suppression de MailConfirmationMdbBean.");
}
}`
and for testting i have this tow programe :
public class MailConfirmationConsommateur implements MessageListener {
public static void main(String[] args) throws Exception {
new MailConfirmationConsommateur();
}
public MailConfirmationConsommateur() throws Exception {
Properties props = new Properties(); //System.getProperties();
//proprietes.load(new FileInputStream("jndi.properties"));
props.put(Context.INITIAL_CONTEXT_FACTORY,
"org.jnp.interfaces.NamingContextFactory");
props.put(Context.URL_PKG_PREFIXES,
"org.jboss.naming:org.jnp.interfaces");
props.put(Context.PROVIDER_URL, "jnp://localhost:1099");
InitialContext ctx = new InitialContext(props);
// 1: recherche d'une connection factory
ConnectionFactory factory = (ConnectionFactory) ctx.lookup("ConnectionFactory");
// 2: création d'une connection JMS
Connection conn = factory.createConnection();
// 3: création d'une session
Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
// 4. Recherche d'une destination
Topic topic = (Topic) ctx.lookup("topic/MailConfirmationMdbTopic");
// 5: création d'un consommateur de message
MessageConsumer consommateur =session.createConsumer(topic);
consommateur.setMessageListener(this);
System.out.println("Client JMS MailConfirmationConsommateur é l'écoute de messages.");
conn.start(); //
}
public void onMessage(Message msg) {
if (msg instanceof TextMessage) {
TextMessage tm = (TextMessage) msg;
// L'envoi d'un mail de confirmation au client est ici simulé
// par l'affichage d'un message au niveau des logs.
try {
String mail = tm.getText();
System.out.println("Le client JMS MailConfirmationConsommateur a reçu le message : " + mail);
} catch (JMSException e) {
e.printStackTrace();
}
}
}
#PreDestroy
public void remove() {
System.out.println("Suppression du client JMS MailConfirmationConsommateur.");
}
}
and
public class MailConfirmationProducteur {
private static final Logger log = Logger.getLogger(MailConfirmationProducteur.class);
public static void main(String[] args) throws Exception {
// Properties proprietes = new Properties();
// proprietes.load(new FileInputStream("jndi.properties"));
InitialContext ctx = new InitialContext();
// 1: recherche d'une connection factory
ConnectionFactory factory = (ConnectionFactory) ctx.lookup("ConnectionFactory");
// 2: création d'une connection JMS
Connection conn = factory.createConnection();
// 3: création d'une session
Session session = conn.createSession(false,Session.AUTO_ACKNOWLEDGE);
// 4: Recherche d'une destination
Topic topic = (Topic) ctx.lookup("topic/MailConfirmationMdbTopic");
// 5: création d'un producteur de message
MessageProducer producteur = session.createProducer(topic);
// 6: publication d'un message
TextMessage msg = session.createTextMessage();
msg.setText("Mail de confirmation pour le client.");
producteur.send(msg);
producteur.close();
log.info("Message envoyé.");
}
}
i don't now if i am on the good way or no
on the console i have this error
Exception in thread "main" javax.naming.NameNotFoundException: topic not bound
at org.jnp.server.NamingServer.getBinding(NamingServer.java:771)
at org.jnp.server.NamingServer.getBinding(NamingServer.java:779)
at org.jnp.server.NamingServer.getObject(NamingServer.java:785)
at org.jnp.server.NamingServer.lookup(NamingServer.java:396)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:322)
at sun.rmi.transport.Transport$1.run(Transport.java:177)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:173)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:553)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:808)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:667)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:636)
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:255)
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:233)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:142)
at org.jnp.server.NamingServer_Stub.lookup(Unknown Source)
at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:728)
at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:688)
at javax.naming.InitialContext.lookup(InitialContext.java:392)
at com.soutem.ejb.mdb.MailConfirmationConsommateur.<init>(MailConfirmationConsommateur.java:42)
at com.soutem.ejb.mdb.MailConfirmationConsommateur.main(MailConfirmationConsommateur.java:22)
and when i run the producteur
public class MailConfirmationProducteur {
private static final Logger log = Logger.getLogger(MailConfirmationProducteur.class);
public static void main(String[] args) throws Exception {
// Properties proprietes = new Properties();
// proprietes.load(new FileInputStream("jndi.properties"));
InitialContext ctx = new InitialContext();
// 1: recherche d'une connection factory
ConnectionFactory factory = (ConnectionFactory) ctx.lookup("ConnectionFactory");
// 2: création d'une connection JMS
Connection conn = factory.createConnection();
// 3: création d'une session
Session session = conn.createSession(false,Session.AUTO_ACKNOWLEDGE);
// 4: Recherche d'une destination
Topic topic = (Topic) ctx.lookup("topic/MailConfirmationMdbTopic");
// 5: création d'un producteur de message
MessageProducer producteur = session.createProducer(topic);
// 6: publication d'un message
TextMessage msg = session.createTextMessage();
msg.setText("Mail de confirmation pour le client.");
producteur.send(msg);
producteur.close();
log.info("Message envoyé.");
}
}

it works now , i fill the solution : here
the methode on my session bean for producing mail :
public void producteurMail(Commande commande) {
// Properties proprietes = new Properties();
// proprietes.load(new FileInputStream("jndi.properties")
InitialContext ctx = null;
try {
ctx = new InitialContext();
} catch (NamingException e) {
e.printStackTrace();
}
// 1: recherche d'une connection factory
ConnectionFactory factory = null;
try {
factory = (ConnectionFactory) ctx.lookup("ConnectionFactory");
} catch (NamingException e) {
e.printStackTrace();
}
// 2: création d'une connection JMS
Connection conn = null;
try {
conn = factory.createConnection();
} catch (JMSException e) {
e.printStackTrace();
}
// 3: création d'une session
Session session = null;
try {
session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
} catch (JMSException e) {
e.printStackTrace();
}
// 4: Recherche d'une destination
Topic topic = null;
try {
topic = (Topic) ctx.lookup("topic/MailConfirmationMdbTopic");
} catch (NamingException e) {
e.printStackTrace();
}
// 5: cr�ation d'un producteur de message
MessageProducer producteur = null;
try {
producteur = session.createProducer(topic);
// 6: publication d'un message
TextMessage msg = null;
msg = session.createTextMessage();
msg.setText("Votre Commande est en cour de traitment .");
//producteur.
producteur.send(msg);
producteur.close();
conn.close();
session.close();
} catch (JMSException e) {
e.printStackTrace();
}
log.info("Message envoyé.");
}
my message driven bean :
package com.soutem.ejb.mdb;
import java.io.UnsupportedEncodingException;
import java.util.Properties;
import java.util.Set;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.ejb.MessageDrivenContext;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
import javax.jms.TextMessage;
import javax.mail.BodyPart;
import javax.mail.MessagingException;
import javax.mail.Transport;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.jboss.logging.Logger;
#MessageDriven(mappedName = "topic/MailConfirmationMdbTopic",
activationConfig = {
#ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
#ActivationConfigProperty(propertyName="subscriptionDurability", propertyValue="Durable"),
#ActivationConfigProperty(propertyName="subscriptionName", propertyValue="topicmdb"),
#ActivationConfigProperty(propertyName="clientId", propertyValue="mdbtopic-test"),
//
#ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"),
#ActivationConfigProperty(propertyName = "destination", propertyValue = "topic/MailConfirmationMdbTopic")
})
public class MailConfirmationMdbBean implements MessageListener {
private static final Logger log = Logger.getLogger(MailConfirmationMdbBean.class);
// #Resource MessageDrivenContext mdc;
public MailConfirmationMdbBean(){
log.info("Initialisation de l'envoi du mail depuis MailConfirmationMdbBean");
}
public void onMessage(Message message) { //Message de javax.jms.Message
// Pour la classe de test MailConfirmationProducteur
if (message instanceof TextMessage) {
TextMessage mail = (TextMessage) message;
// L'envoi d'un mail de confirmation au client est ici simulé par l'affichage d'un message au niveau des logs.
try {
String leMail = mail.getText();
log.info(" Envoi du mail : " + leMail);
log.info(" --------------------------------------------------- ");
sendMsg("ahmed.drira#gmail.com", "Confirmation de commande.",leMail /*leMail*/);
log.info(" --------------------------------------------------- ");
log.info(" Mail envoyé.");
}
catch (JMSException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (MessagingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NamingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else if (message instanceof ObjectMessage) {
ObjectMessage lemessage = (ObjectMessage) message;
}
}
protected void sendMsg(String email, String subject, String body) throws MessagingException, NamingException, UnsupportedEncodingException {
Properties props = new Properties();
InitialContext ictx = new InitialContext(props);
javax.mail.Session mailSession = (javax.mail.Session) ictx.lookup("java:/Mail");
MimeMessage message = new MimeMessage(mailSession);
message.setSubject(subject);
message.setRecipients(javax.mail.Message.RecipientType.TO, javax.mail.internet.InternetAddress.parse(email, false));
message.setText(body);
message.saveChanges();
Transport transport = mailSession.getTransport("smtp");
try {
transport.connect();
transport.sendMessage(message, message.getAllRecipients());
log.info("Message envoyé");
}
finally {
transport.close();
}
}
#PreDestroy
public void remove() {
log.info("Suppression de MailConfirmationMdbBean.");
}
}
for the producer and consumer programe , you can test with this :
package com.soutem.ejb.mdb;
import java.io.FileInputStream;
import java.util.Properties;
import javax.annotation.PreDestroy;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
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 javax.jms.Topic;
import javax.naming.Context;
import javax.naming.InitialContext;
public class MailConfirmationConsommateur implements MessageListener {
public static void main(String[] args) throws Exception {
new MailConfirmationConsommateur();
}
public MailConfirmationConsommateur() throws Exception {
Properties proprietes = new Properties();
proprietes.load(new FileInputStream("jndi.properties"));
InitialContext ctx = new InitialContext(proprietes);
// 1: recherche d'une connection factory
ConnectionFactory factory = (ConnectionFactory) ctx.lookup("ConnectionFactory");
// 2: cr�ation d'une connection JMS
Connection conn = factory.createConnection();
// 3: cr�ation d'une session
Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
// 4. Recherche d'une destination
Topic topic = (Topic) ctx.lookup("topic/MailConfirmationMdbTopic");
// 5: cr�ation d'un consommateur de message
MessageConsumer consommateur = session.createConsumer(topic);
consommateur.setMessageListener(this);
System.out.println("Client JMS MailConfirmationConsommateur à l'écoute de messages.");
conn.start(); //
}
public void onMessage(Message msg) {
if (msg instanceof TextMessage) {
TextMessage tm = (TextMessage) msg;
// L'envoi d'un mail de confirmation au client est ici simul�
// par l'affichage d'un message au niveau des logs.
try {
String mail = tm.getText();
System.out.println("Le client JMS MailConfirmationConsommateur a reçu le message : " + mail);
} catch (JMSException e) {
e.printStackTrace();
}
}
}
#PreDestroy
public void remove() {
System.out.println("Suppression du client JMS MailConfirmationConsommateur.");
}
}
package com.soutem.ejb.mdb;
import java.io.FileInputStream;
import java.util.Properties;
import javax.annotation.Resource;
import javax.jms.*;
import javax.naming.InitialContext;
import org.jboss.logging.Logger;
public class MailConfirmationProducteur {
private static final Logger log = Logger.getLogger(MailConfirmationProducteur.class);
public static void main(String[] args) throws Exception {
Properties proprietes = new Properties();
proprietes.load(new FileInputStream("jndi.properties"));
InitialContext ctx = new InitialContext(proprietes);
// 1: recherche d'une connection factory
ConnectionFactory factory = (ConnectionFactory) ctx.lookup("ConnectionFactory");
// 2: cr�ation d'une connection JMS
Connection conn = factory.createConnection();
// 3: cr�ation d'une session
Session session = conn.createSession(false,Session.AUTO_ACKNOWLEDGE);
// 4: Recherche d'une destination
Topic topic = (Topic) ctx.lookup("topic/MailConfirmationMdbTopic");
// 5: cr�ation d'un producteur de message
MessageProducer producteur = session.createProducer(topic);
// 6: publication d'un message
TextMessage msg = session.createTextMessage();
msg.setText("Mail de confirmation pour le client.");
producteur.send(msg);
producteur.close();
log.info("Message envoy�.");
}
}
you need also some configuration on the server to set up the topic so you need to add this lines on the /server/default/deploy/hornetq/hornetq-jms.xml
<topic name="/topic/MailConfirmationMdbTopic">
<entry name="/topic/MailConfirmationMdbTopic"/>
</topic>
you need also to configure the java mail by adding your smtp privider , mail and pass here is the config
<mbean code="org.jboss.mail.MailService"
name="jboss:service=Mail">
<attribute name="JNDIName">java:/Mail</attribute>
<attribute name="User">.......#gmail.com</attribute>
<attribute name="Password">.........</attribute>
<attribute name="Configuration">
<!-- A test configuration -->
<configuration>
<property name="mail.smtp.host" value="smtp.gmail.com">
<property name="mail.smtp.port" value="465">
<property name="mail.smtp.auth" value="true">
<property name="mail.smtp.ssl.enable" value="true">
</property></property></property></property></configuration>
</attribute>
<depends>jboss:service=Naming</depends>
</mbean>
So hope it can be helpful any question i can give a hand

Related

WildFly JavaEE - Start / Stop Message Driven Bean at runtime

I have a question about Message Driven Beans (MDB). Is there a way to generate these only at runtime? I want to provide a way in my backend to start or stop receiving messages. It should be controlled via a configuration entry in the database. When starting WildFly, it should also first check whether the MDBs can be started.
Is it Java EE compliant to do without an MDB and create the listeners manually?
I am currently using the following code
#MessageDriven(name = "MyMDB", activationConfig = {
#ActivationConfigProperty(propertyName = "maxSession", propertyValue = "2"),
#ActivationConfigProperty(propertyName = "destination", propertyValue = "java:/jms/queue/Test"),
#ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
#ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge")})
public class JmsConsumer implements MessageListener {
#Override
public void onMessage(final Message msg) {
if (msg instanceof TextMessage) {
try {
final String text = ((TextMessage) msg).getText();
System.out.println("message: " + text + " (" + msg.getJMSRedelivered() + ")");
} catch (final JMSException e) {
e.printStackTrace();
}
}
}
}
Would this code also conform to Java EE?
#Singleton
#LocalBean
public class QueueWorkerManager {
private InitialContext initialContext = null;
private QueueConnectionFactory queueConnectionFactory = null;
private Queue queue = null;
private QueueConnection queueConnection = null;
private QueueSession queueSession = null;
private MessageConsumer consumer = null;
#PostConstruct
public void init() {
try {
this.initialContext = new InitialContext();
this.queueConnectionFactory = (QueueConnectionFactory) initialContext
.lookup("java:/ConnectionFactory");
this.queue = (Queue) initialContext.lookup(MyQueueSender.WORKER_QUEUE);
this.queueConnection = queueConnectionFactory.createQueueConnection();
this.queueSession = queueConnection.createQueueSession(false, Session.CLIENT_ACKNOWLEDGE);
this.consumer = queueSession.createConsumer(this.queue);
this.consumer.setMessageListener(new ConsumerMessageListener());
this.queueConnection.start();
} catch (Exception ex) {
ex.printStackTrace();
}
}
#PreDestroy
public void destroy() {
this.stopConsumer(this.consumer;
if(this.consumer != null) {
try {
this.consumer.close();
} catch (JMSException e) {
}
this.consumer = null;
}
if(this.queueSession != null) {
try {
this.queueSession.close();
} catch (JMSException e) {
}
this.queueSession = null;
}
if(this.queueConnection != null) {
try {
this.queueConnection.close();
} catch (JMSException e) {
}
this.queueConnection = null;
}
}
}
public class ConsumerMessageListener implements MessageListener {
#Override
public void onMessage(Message message) {
TextMessage textMessage = (TextMessage) message;
try {
System.out.println("message: " + textMessage.getText() + " (" + msg.getJMSRedelivered() + ")");
message.acknowledge();
} catch (JMSException | InterruptedException e) {
e.printStackTrace();
}
}
}
I would suggest you to
add a #DeliveryActive(false/true) annotation to your MDB in order to boot it in the desired initial state
Use JMX or JBoss CLI to programatically change the value of the active attribute of your MDB
Everything is explained here:
https://docs.wildfly.org/16/Developer_Guide.html#Message_Driven_Beans_Controlled_Delivery
Good luck

com.ibm.mq.MQException: MQJE001: Completion Code 2, Reason 2009 using Sprint Boot with JMS (IBM MQ )

I am not sure what I am doing wrong, this issue is very sporadic, I have below code to send JMS Messages on IBM MQ. I am doing it in a seperate theread usign spring #async as below.
#Override
#Async
public void crewSeqAssignOrRemoveBatch(List<Batch> oBatchFosRequestList, String transactionType) throws InterruptedException {
long lStartTime = Instant.now().toEpochMilli();
logger.info("In Seperate Thread for FOS Submissoin, Thread Name is " + Thread.currentThread().getId() + ":"+Thread.currentThread().getName()+":"+Thread.currentThread().getThreadGroup()+":"+Thread.currentThread().activeCount()+":"+Thread.currentThread().getState());
logger.info("FHSeqAssignOrRemoveServiceImpl : crewSeqAssignOrRemoveBatch() : Start >>");
try
{
for (Iterator<Batch> iterator = oBatchFosRequestList.iterator(); iterator.hasNext();) {
Batch oBatchFosRequest = iterator.next();
UUID uniqueId = UUID.randomUUID();
String correlationId = uniqueId.toString() + "-" + oBatchFosRequest.getTransactionID() +"-"+ Calendar.getInstance().getTimeInMillis();
logger.info("correlationId generated is :" + correlationId);
try {
//JMSTextMessage message = null;
logger.info("Executing MessageCreator for ID "+ oBatchFosRequest.getTransactionID() +" on :" + new Date().toString());
MessageCreator mc = new MessageCreator() {
#Override
public Message createMessage(Session session) throws JMSException {
JMSTextMessage message = null;
try {
logger.info("Executing CreateMessage for ID "+ oBatchFosRequest.getTransactionID() +" on :" + new Date().toString());
//POINT 2
logger.info("Session Object ........ " + session.toString());
logger.info("Session Status - Is Session Transacted ?........ " + session.getTransacted());
logger.info("Session Status acknowledge mode........ " + session.getAcknowledgeMode());
logger.info("Ready to send message........ ");
logger.info("Send ConnectionFactory is: " + jmsQueueTemplate.getConnectionFactory().toString());
logger.info("Send destination is: " + jmsQueueTemplate.getDefaultDestination());
logger.info("Reply destination is: " + destination);
logger.info("Sent message correlationId is: " + correlationId);
logger.info("##########################################################");
message = (JMSTextMessage) session.createTextMessage();
String fosXmlBatchRequest = XMLUtil.createBatchFosRequestXML(oBatchFosRequest);
message.setText(fosXmlBatchRequest);
message.setJMSCorrelationID(correlationId);
logger.info(transactionType + " : Sending message is:");
logger.info(message.getText());
logger.info("##########################################################");
message.setJMSReplyTo(destination);
} catch (JMSException je) {
Exception ex = je.getLinkedException();
logger.info("JMS Linked Exception Occured :" + ex.getMessage());
ex.printStackTrace();
logger.info("JMS Exception Occured :" + je.getMessage());
je.printStackTrace();
}
catch (Exception e) {
logger.info("Exception Occured :" + e.getMessage());
e.printStackTrace();
}
return message;
}
};
logger.info("Executing send for ID "+ oBatchFosRequest.getTransactionID() +" on :" + new Date().toString());
logger.info("Calling Send Method ");
jmsQueueTemplate.send(mc);
logger.info("Send Completed");
My JMS Cnfiguration is as below :
import javax.jms.Destination;
import javax.jms.JMSException;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
import org.springframework.jms.connection.CachingConnectionFactory;
import org.springframework.jms.connection.SingleConnectionFactory;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.listener.DefaultMessageListenerContainer;
import org.springframework.jms.support.converter.MappingJackson2MessageConverter;
import org.springframework.jms.support.converter.MessageConverter;
import org.springframework.jms.support.converter.MessageType;
import org.springframework.stereotype.Component;
import com.ibm.mq.jms.MQQueue;
import com.ibm.mq.jms.MQQueueConnectionFactory;
#Configurable
#Component
public class JMSConfiguration {
private final Logger log = LogManager.getLogger(JMSConfiguration.class);
#Autowired
MessageListenerReciever messageListenerReciever1;
#Autowired
MessageListenerReciever messageListenerReciever2;
private String hostName1;
private String hostName2;
private String hostName3;
private String writePort;
private String readPort;
private String channel;
private String transportType;
private String updateQueue;
private String replyQueue;
private String queueGateway;
#Autowired
JMSConfiguration(Environment environment){
this.hostName1 = environment.getRequiredProperty("jms.cf.write.hostName1");
this.hostName2 = environment.getRequiredProperty("jms.cf.read.hostName2");
this.hostName3 = environment.getRequiredProperty("jms.cf.read.hostName3");
this.writePort = environment.getRequiredProperty("jms.cf.write.port");
this.readPort = environment.getRequiredProperty("jms.cf.read.port");
this.channel = environment.getRequiredProperty("jms.cf.channel");
this.transportType = environment.getRequiredProperty("jms.cf.transportType");
this.updateQueue = environment.getRequiredProperty("jms.queue.update");
this.replyQueue = environment.getRequiredProperty("jms.queue.reply");
this.queueGateway = environment.getRequiredProperty("jms.queue.gateway");
}
#Bean
public MQQueueConnectionFactory connectionFactory1() {
MQQueueConnectionFactory connectionFactory = new MQQueueConnectionFactory();
try {
connectionFactory.setHostName(hostName1);
connectionFactory.setPort(Integer.parseInt(writePort));
connectionFactory.setChannel(channel);
connectionFactory.setTransportType(Integer.parseInt(transportType));
} catch (NumberFormatException | JMSException e) {
log.error(e.toString(),e);
}
return connectionFactory;
}
#Bean
#Primary
public CachingConnectionFactory cachingConnectionFactory(MQQueueConnectionFactory connectionFactory) {
CachingConnectionFactory oCachingConnectionFactory = new CachingConnectionFactory();
oCachingConnectionFactory.setTargetConnectionFactory(connectionFactory);
//oCachingConnectionFactory.setCacheProducers(true);
oCachingConnectionFactory.setSessionCacheSize(100);
oCachingConnectionFactory.setReconnectOnException(true);
return oCachingConnectionFactory;
}
public MQQueueConnectionFactory connectionFactory2() {
MQQueueConnectionFactory connectionFactory = new MQQueueConnectionFactory();
try {
connectionFactory.setHostName(hostName2);
connectionFactory.setPort(Integer.parseInt(readPort));
connectionFactory.setChannel(channel);
connectionFactory.setTransportType(Integer.parseInt(transportType));
} catch (NumberFormatException | JMSException e) {
log.error(e.toString(),e);
}
return connectionFactory;
}
public MQQueueConnectionFactory connectionFactory3() {
MQQueueConnectionFactory connectionFactory = new MQQueueConnectionFactory();
try {
connectionFactory.setHostName(hostName3);
connectionFactory.setPort(Integer.parseInt(readPort));
connectionFactory.setChannel(channel);
connectionFactory.setTransportType(Integer.parseInt(transportType));
} catch (NumberFormatException | JMSException e) {
log.error(e.toString(),e);
}
return connectionFactory;
}
#Bean
public Destination jmsDestinationResolverSender() throws JMSException {
return new MQQueue(updateQueue);
}
#Bean
public Destination jmsDestinationResolverReceiver() throws JMSException {
return new MQQueue(replyQueue);
}
#Bean
public Destination jmsDestinationResolverReplyTo() throws JMSException {
return new MQQueue(queueGateway, replyQueue);
}
#Bean
public JmsTemplate jmsQueueTemplate(SingleConnectionFactory oSingleConnectionFactory) throws JMSException {
JmsTemplate jmsTemplate = new JmsTemplate();
jmsTemplate.setConnectionFactory(oSingleConnectionFactory);
jmsTemplate.setDefaultDestination(jmsDestinationResolverSender());
jmsTemplate.afterPropertiesSet();
log.info("in jms configuration ConnectionFactory is:" + jmsTemplate.getConnectionFactory());
log.info("in jms configuration Send destination is:" + jmsTemplate.getDefaultDestination());
log.info("in jms configuration Send Delivery Delay is :" + jmsTemplate.getDeliveryDelay());
log.info("in jms configuration Send Delivery Mode is:" + jmsTemplate.getDeliveryMode());
return jmsTemplate;
}
#Bean
public DefaultMessageListenerContainer listenerContainer() throws JMSException {
DefaultMessageListenerContainer defMsgListCont = new DefaultMessageListenerContainer();
defMsgListCont.setConnectionFactory(connectionFactory3());
defMsgListCont.setDestination(jmsDestinationResolverReceiver());
defMsgListCont.setMessageListener(messageListenerReciever1);
defMsgListCont.afterPropertiesSet();
return defMsgListCont;
}
#Bean
public DefaultMessageListenerContainer listenerContainer2() throws JMSException {
DefaultMessageListenerContainer defMsgListCont = new DefaultMessageListenerContainer();
defMsgListCont.setConnectionFactory(connectionFactory2());
defMsgListCont.setDestination(jmsDestinationResolverReceiver());
defMsgListCont.setMessageListener(messageListenerReciever2);
defMsgListCont.afterPropertiesSet();
return defMsgListCont;
}
// Serialize message content to json using TextMessage
#Bean
public MessageConverter jacksonJmsMessageConverter() {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
converter.setTargetType(MessageType.TEXT);
converter.setTypeIdPropertyName("_type");
return converter;
}
}
I am not sure where is the issue, But i strongly beleive its related to connection factory i am using , I am trying to use CachingConnectionFactory , But with below mentioend configuration it keeps sporadically failing with below code exception at this line
jmsQueueTemplate.send(mc);
Exceptiopn below :
> 12-12-2018 09:05:27.153 INFO htappp22 --- [ FAPS-FOS-5] c.a.f.s.FHSeqAssignOrRemoveServiceImpl : JMSException while Sending Message To FOS Outside
org.springframework.jms.UncategorizedJmsException: Uncategorized exception occurred during JMS processing; nested exception is javax.jms.JMSException: MQJMS2007: failed to send message to MQ queue; nested exception is com.ibm.mq.MQException: MQJE001: Completion Code 2, Reason 2009
at org.springframework.jms.support.JmsUtils.convertJmsAccessException(JmsUtils.java:316)
at org.springframework.jms.support.JmsAccessor.convertJmsAccessException(JmsAccessor.java:169)
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:487)
at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:559)
at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:550)
at com.aa.faps.services.FHSeqAssignOrRemoveServiceImpl.crewSeqAssignOrRemoveBatch(FHSeqAssignOrRemoveServiceImpl.java:115)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.aop.interceptor.AsyncExecutionInterceptor$1.call(AsyncExecutionInterceptor.java:115)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: javax.jms.JMSException: MQJMS2007: failed to send message to MQ queue
at com.ibm.mq.jms.services.ConfigEnvironment.newException(ConfigEnvironment.java:567)
at com.ibm.mq.jms.MQMessageProducer.sendInternal(MQMessageProducer.java:1743)
at com.ibm.mq.jms.MQMessageProducer.send(MQMessageProducer.java:1056)
at org.springframework.jms.connection.CachedMessageProducer.send(CachedMessageProducer.java:181)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.jms.connection.CachedMessageProducer$Jms2MessageProducerInvocationHandler.invoke(CachedMessageProducer.java:293)
at com.sun.proxy.$Proxy276.send(Unknown Source)
at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:626)
at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:597)
at org.springframework.jms.core.JmsTemplate$3.doInJms(JmsTemplate.java:562)
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:484)
... 15 more

Delay in send Message method in JMSTemplate at createMessage

I am newbie to MQ, We are usgin spring boot with JMS + IBM MQ Framework. We are facing a very random issue where there is 5 - 15 min delay to execute send method of jmsQueueTemplate as below.
Random delay is Between //POINT 1 and //POINT 2
try {
logger.info("Calling Send Method ");
//POINT 1
jmsQueueTemplate.send(new MessageCreator() {
public Message createMessage(Session session) throws JMSException {
JMSTextMessage message = null;
try {
//POINT 2
logger.info("Session Object ........ " + session.toString());
logger.info("Session Status - Is Session Transacted ?........ " + session.getTransacted());
logger.info("Session Status acknowledge mode........ " + session.getAcknowledgeMode());
logger.info("Ready to send Sample message........ ");
logger.info("Send ConnectionFactory is: " + jmsQueueTemplate.getConnectionFactory().toString());
logger.info("Send destination is: " + jmsQueueTemplate.getDefaultDestination());
logger.info("Reply destination is: " + destination);
logger.info("Sent message correlationId is: " + correlationId);
logger.info("##########################################################");
message = (JMSTextMessage) session.createTextMessage();
String fosXmlBatchRequest = XMLUtil.createBatchFosRequestXML(oBatchFosRequest);
message.setText(fosXmlBatchRequest);
message.setJMSCorrelationID(correlationId);
logger.info(transactionType + " : Sending message is:");
logger.info(message.getText());
logger.info("##########################################################");
message.setJMSReplyTo(destination);
} catch (Exception e) {
logger.info("Exception Occured :" + e.getMessage());
}
return message;
}
});
} catch(Exception e) {
logger.info("Exception while Sending Message To FOS",e);
logger.info(e.toString(),e);
logger.error("Exception while Sending Message To FOS",e);
logger.error(e.toString(),e);
}
we are not handling session object and letting spring take care of session creation . I am not sure when exacty is the delay getting introced ? Are we loosing session object ? Any suggestion pls.
Our spring configuration is as below .
import javax.jms.Destination;
import javax.jms.JMSException;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.Environment;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.listener.DefaultMessageListenerContainer;
import org.springframework.jms.support.converter.MappingJackson2MessageConverter;
import org.springframework.jms.support.converter.MessageConverter;
import org.springframework.jms.support.converter.MessageType;
import org.springframework.stereotype.Component;
import com.ibm.mq.jms.MQQueue;
import com.ibm.mq.jms.MQQueueConnectionFactory;
/**
*
* #author krna
* This class defines configuration for JMS Queues required for FOS update.
*/
#Configurable
#Component
public class JMSConfiguration {
private final Logger log = LogManager.getLogger(JMSConfiguration.class);
#Autowired
MessageListenerReciever messageListenerReciever1;
#Autowired
MessageListenerReciever messageListenerReciever2;
private String hostName1;
private String hostName2;
private String hostName3;
private String writePort;
private String readPort;
private String channel;
private String transportType;
private String updateQueue;
private String replyQueue;
private String queueGateway;
#Autowired
JMSConfiguration(Environment environment){
this.hostName1 = environment.getRequiredProperty("jms.cf.write.hostName1");
this.hostName2 = environment.getRequiredProperty("jms.cf.read.hostName2");
this.hostName3 = environment.getRequiredProperty("jms.cf.read.hostName3");
this.writePort = environment.getRequiredProperty("jms.cf.write.port");
this.readPort = environment.getRequiredProperty("jms.cf.read.port");
this.channel = environment.getRequiredProperty("jms.cf.channel");
this.transportType = environment.getRequiredProperty("jms.cf.transportType");
this.updateQueue = environment.getRequiredProperty("jms.queue.update");
this.replyQueue = environment.getRequiredProperty("jms.queue.reply");
this.queueGateway = environment.getRequiredProperty("jms.queue.gateway");
}
public MQQueueConnectionFactory connectionFactory1() {
MQQueueConnectionFactory connectionFactory = new MQQueueConnectionFactory();
try {
connectionFactory.setHostName(hostName1);
connectionFactory.setPort(Integer.parseInt(writePort));
connectionFactory.setChannel(channel);
connectionFactory.setTransportType(Integer.parseInt(transportType));
} catch (NumberFormatException | JMSException e) {
log.error(e.toString(),e);
}
return connectionFactory;
}
public MQQueueConnectionFactory connectionFactory2() {
MQQueueConnectionFactory connectionFactory = new MQQueueConnectionFactory();
try {
connectionFactory.setHostName(hostName2);
connectionFactory.setPort(Integer.parseInt(readPort));
connectionFactory.setChannel(channel);
connectionFactory.setTransportType(Integer.parseInt(transportType));
} catch (NumberFormatException | JMSException e) {
log.error(e.toString(),e);
}
return connectionFactory;
}
public MQQueueConnectionFactory connectionFactory3() {
MQQueueConnectionFactory connectionFactory = new MQQueueConnectionFactory();
try {
connectionFactory.setHostName(hostName3);
connectionFactory.setPort(Integer.parseInt(readPort));
connectionFactory.setChannel(channel);
connectionFactory.setTransportType(Integer.parseInt(transportType));
} catch (NumberFormatException | JMSException e) {
log.error(e.toString(),e);
}
return connectionFactory;
}
#Bean
public Destination jmsDestinationResolverSender() throws JMSException {
return new MQQueue(updateQueue);
}
#Bean
public Destination jmsDestinationResolverReceiver() throws JMSException {
return new MQQueue(replyQueue);
}
#Bean
public Destination jmsDestinationResolverReplyTo() throws JMSException {
return new MQQueue(queueGateway, replyQueue);
}
#Bean
public JmsTemplate jmsQueueTemplate() throws JMSException {
JmsTemplate jmsTemplate = new JmsTemplate();
jmsTemplate.setConnectionFactory(connectionFactory1());
jmsTemplate.setDefaultDestination(jmsDestinationResolverSender());
jmsTemplate.afterPropertiesSet();
log.info("Send ConnectionFactory is:" + jmsTemplate.getConnectionFactory());
log.info("Send destination is:" + jmsTemplate.getDefaultDestination());
log.info("Send Delivery Delay is :" + jmsTemplate.getDeliveryDelay());
log.info("Send Delivery Mode is:" + jmsTemplate.getDeliveryMode());
return jmsTemplate;
}
#Bean
public DefaultMessageListenerContainer listenerContainer() throws JMSException {
DefaultMessageListenerContainer defMsgListCont = new DefaultMessageListenerContainer();
defMsgListCont.setConnectionFactory(connectionFactory3());
defMsgListCont.setDestination(jmsDestinationResolverReceiver());
defMsgListCont.setMessageListener(messageListenerReciever1);
defMsgListCont.afterPropertiesSet();
return defMsgListCont;
}
#Bean
public DefaultMessageListenerContainer listenerContainer2() throws JMSException {
DefaultMessageListenerContainer defMsgListCont = new DefaultMessageListenerContainer();
defMsgListCont.setConnectionFactory(connectionFactory2());
defMsgListCont.setDestination(jmsDestinationResolverReceiver());
defMsgListCont.setMessageListener(messageListenerReciever2);
defMsgListCont.afterPropertiesSet();
return defMsgListCont;
}
// Serialize message content to json using TextMessage
#Bean
public MessageConverter jacksonJmsMessageConverter() {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
converter.setTargetType(MessageType.TEXT);
converter.setTypeIdPropertyName("_type");
return converter;
}
}
Update: It happened again today. One more Interesting this is sourcetimestamp on MQ msg is different from the time it was send. Sourcetimestamp is showing correct time but execution is delayed

Messages not sent to reply queue on an RTE

In our current application using JBoss EAP 6.2, we have many batch jobs triggered by remote EJB invocations. In order to centralize all notification logic for these jobs we are deciding to route all calls through an MDB by passing a serialized message. The intended flow is as below:
Batch job client sends message to a remote queue
MDB listens on this remote queue, process message and invokes EJB
DLQ is configured to process notifications when all retries are
exhausted
Notification should also be sent on each retry. To avoid too many
notifications, retry interval is sufficiently high
To handle the last point, I tried creating a Reply queue by setting it in the JMSReplyTo header. To simulate above flow, I have created the below MDB implementations...
Main MDB:
#MessageDriven(name = "MiddleManMDB", activationConfig = {
#ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
#ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/test"),
#ActivationConfigProperty(propertyName = "connectorClassName", propertyValue = "org.hornetq.core.remoting.impl.netty.NettyConnectorFactory"),
#ActivationConfigProperty(propertyName = "connectionParameters", propertyValue = "host=localhost;port=5445"),
#ActivationConfigProperty(propertyName = "user", propertyValue = "queueuser"),
#ActivationConfigProperty(propertyName = "password", propertyValue = "queuepassword")
})
public class MiddleManMDB implements MessageListener {
private static final Logger LOGGER = LoggerFactory.getLogger(MiddleManMDB.class);
#Resource(name = "java:/JmsXA")
private ConnectionFactory connectionFactory;
/*
* (non-Javadoc)
* #see javax.jms.MessageListener#onMessage(javax.jms.Message)
*/
#Override
public void onMessage(Message message)
{
try {
if (message instanceof TextMessage) {
LOGGER.info("Received text message --> {}", ((TextMessage)message).getText());
}
throw new JMSException("thrown exception");
}
catch (Exception e) {
sendToReplyQueue(e.getMessage(), message);
LOGGER.info("Throwing exception to simulate retry...");
throw new RuntimeException(e);
}
}
private void sendToReplyQueue(String errorMessage, Message message)
{
Context context = null;
Connection conn = null;
LOGGER.info("Sending exception details to reply queue...");
try {
context = new InitialContext();
conn = connectionFactory.createConnection();
Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination jmsReplyTo = message.getJMSReplyTo();
MessageProducer replyProducer = session.createProducer(jmsReplyTo);
replyProducer.send(jmsReplyTo, session.createTextMessage(errorMessage));
}
catch (NamingException | JMSException e) {
e.printStackTrace();
}
finally {
// close connection and context
}
}
}
Reply MDB:
#MessageDriven(name = "ReplyMDB", activationConfig = {
#ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
#ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/reply")
})
public class ReplyMDB implements MessageListener {
private static final Logger LOGGER = LoggerFactory.getLogger(ReplyMDB.class);
#Override
public void onMessage(Message message) {
try {
if (message instanceof TextMessage) {
LOGGER.info("Received reply message --> " + ((TextMessage)message).getText());
}
}
catch (JMSException e) {
LOGGER.error("Error in reply queue...", e);
}
}
}
** Dead Letter MDB:**
#MessageDriven(name = "DeadLetterMDB", activationConfig = {
#ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
#ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/dead")
})
public class DeadLetterMDB implements MessageListener {
private static final Logger LOGGER = LoggerFactory.getLogger(DeadLetterMDB.class);
#Override
public void onMessage(Message message) {
try {
LOGGER.info("Message has arrived in dead letter queue");
LOGGER.info("Current delivery count - {}", message.getIntProperty("JMSXDeliveryCount"));
if (message instanceof TextMessage) {
LOGGER.info("Received text message --> {}", ((TextMessage)message).getText());
}
}
catch (JMSException e) {
e.printStackTrace();
}
}
}
** Client:**
public static void main(String[] args) {
Connection connection = null;
Context context = null;
try {
// create context and connection factory
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination destination = (Destination) context.lookup("jms/queue/test");
Destination replyDest = (Destination) context.lookup("jms/queue/reply");
MessageProducer producer = session.createProducer(destination);
connection.start();
TextMessage message = session.createTextMessage("Hello World");
message.setJMSReplyTo(replyDest);
producer.send(message);
}
catch (NamingException | JMSException e) {
e.printStackTrace();
}
finally {
// close context and connection
}
}
** Relevant entries in standalone-full.xml:**
<address-settings>
<address-setting match="jms.queue.testQueue">
<dead-letter-address>jms.queue.DLQ</dead-letter-address>
<expiry-address>jms.queue.ExpiryQueue</expiry-address>
<redelivery-delay>1000</redelivery-delay>
<max-delivery-attempts>3</max-delivery-attempts>
<max-size-bytes>10485760</max-size-bytes>
<address-full-policy>BLOCK</address-full-policy>
<message-counter-history-day-limit>10</message-counter-history-day-limit>
</address-setting>
<address-setting match="jms.queue.replyQueue">
<redelivery-delay>1000</redelivery-delay>
<max-delivery-attempts>3</max-delivery-attempts>
<max-size-bytes>10485760</max-size-bytes>
<address-full-policy>BLOCK</address-full-policy>
<message-counter-history-day-limit>10</message-counter-history-day-limit>
</address-setting>
<address-setting match="jms.queue.DLQ">
<redelivery-delay>1000</redelivery-delay>
<max-delivery-attempts>3</max-delivery-attempts>
<max-size-bytes>10485760</max-size-bytes>
<address-full-policy>BLOCK</address-full-policy>
<message-counter-history-day-limit>10</message-counter-history-day-limit>
</address-setting>
</address-settings>
<jms-destinations>
<jms-queue name="testQueue">
<entry name="queue/test"/>
<entry name="java:jboss/exported/jms/queue/test"/>
</jms-queue>
<jms-queue name="replyQueue">
<entry name="queue/reply"/>
<entry name="java:jboss/exported/jms/queue/reply"/>
</jms-queue>
<jms-queue name="DLQ">
<entry name="queue/dead"/>
<entry name="java:jboss/exported/jms/queue/dead"/>
</jms-queue>
<jms-topic name="testTopic">
<entry name="topic/test"/>
<entry name="java:jboss/exported/jms/topic/test"/>
</jms-topic>
</jms-destinations>
Now with the above flow in the MDBs, the message is never received in the reply queue. All three queues are deployed on the same server.
I am guessing the reason is the below line:
sendToReplyQueue(e.getMessage(), message);
LOGGER.info("Throwing exception to simulate retry...");
throw new RuntimeException(e);
Since the send is asynchronous and I am throwing an RTE (to trigger retry), the message is somehow never sent. Is there a way to resolve this problem ?
I am guessing the reason is the below line......
You can try with commenting RTE. Also add some more logger to trace. check if reply destination set properly or not.
message.setJMSReplyTo(replydestination);
LOGGER.info("Reply to: " + message.getJMSReplyTo());
or message sent to replay queue or not
replyProducer.send(jmsReplyTo, session.createTextMessage(errorMessage));
LOGGER.info("exception details sent to reply queue...");

How to subscribe to an existing advisory topic?

I have activemq5.3.2 running and I wanted to subscribe existing advisory topics using my java program. while, `jndi` lookup I am getting following error:
javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file:
java.naming.factory.initial
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:657)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:259)
at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:296)
at javax.naming.InitialContext.lookup(InitialContext.java:363)
at jmsclient.Consumer.<init>(Consumer.java:38)
at jmsclient.Consumer.main(Consumer.java:74)
Exception occurred: javax.jms.InvalidDestinationException: Don't understand null destinations
Please suggest where the problem is, or how could I use my topic name to look for?
package jmsclient;
import javax.jms.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.apache.activemq.ActiveMQConnectionFactory;
public class Consumer implements MessageListener {
private static int ackMode;
private static String clientTopicName;
private boolean transacted = false;
//private MessageConsumer messageConsumer;
static {
clientTopicName = "ActiveMQ.Advisory.Consumer.Queue.example.A";
ackMode = Session.AUTO_ACKNOWLEDGE;
}
#SuppressWarnings("null")
public Consumer()
{// TODO Auto-generated method stub
TextMessage message = null;
Context jndiContext;
//TopicConnectionFactory topicConnectionFactory = null;
TopicConnection topicConnection = null;
TopicSession topicSession = null;
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://usaxwas012ccxra.ccmp.ibm.lab:61616");
try{
Topic myTopic = null;
try { jndiContext = new InitialContext();
myTopic = (Topic) jndiContext.lookup(clientTopicName);
} catch (NamingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
topicConnection = connectionFactory.createTopicConnection();
topicConnection.start();
topicSession = topicConnection.createTopicSession(transacted, ackMode);
TopicSubscriber topicSubscriber = topicSession.createSubscriber(myTopic);
Message m = topicSubscriber.receive(1000);
if (m != null) {
if (m instanceof TextMessage) {
message = (TextMessage) m;
System.out.println("Reading message: " + message.getText());
}
}
} //try ends
catch (JMSException e) {
System.out.println("Exception occurred: " + e.toString());
} finally {
if (topicConnection != null) {
try {
topicConnection.close();
} catch (JMSException e) {}
}}}
public void onMessage(Message arg0) {
// TODO Auto-generated method stub
}
public static void main(String[] args) {
new Consumer();
}
}

Resources