Problems creating JMS Queue on Glassfish - glassfish

i'm get the following error when deploying my application with a JMS producer and consumer
com.sun.enterprise.connectors.ConnectorRuntimeException: JMS resource not created : QueueName
I used the annotations below:
Producer
#Resource(name = "jms/EmailNotificationQueue", mappedName = "EmailNotificationQueue")
private Destination destination;
#Resource(name = "jms/QueueConnectionFactory")
private ConnectionFactory connectionFactory;
I then create the connection and start it before sending the message
Consumer
#MessageDriven(name = "EmailNotificationBean", activationConfig = {
#ActivationConfigProperty(
propertyName="destinationType",
propertyValue="javax.jms.Queue"),
#ActivationConfigProperty(
propertyName="destinationName",
propertyValue="EmailNotificationQueue"),
#ActivationConfigProperty(
propertyName="acknowledgeMode",
propertyValue="CLIENT_ACKNOWLEDGE")
}
,mappedName = "EmailNotificationQueue"
)

Have you manually created the Destination?
Log into the admin console, expand Resource, JMS Resources, then Destination Resources. You'll probably need to create a connection factory as well.

Related

RabbitListener binding queue to multiple exchanges

I'm looking to be able to bind a queue to multiple exchanges utilizing the RabbitListener annotation but so far have been unsuccessful.
What I have right now is:
#RabbitListener(bindings = #QueueBinding(value =
#Queue(
value = "${subscriber.queueInbound}", durable = "true", autoDelete = "false", exclusive = "false"),
exchange = #Exchange(value = "all", durable = "true")
),
containerFactory = "subscriberRabbitListenerContainerFactory"
)
public void onMessage(Message message, Channel channel) {
// do something
}
This will on start/re-connect auto create the queue defined as subscriber.queueInbound and bind this queue to a default all exchange.
I then have a Job that runs in the background that will then properly configure this queue and bind it to the multiple exchanges it needs to be configured for.
I'm looking for a more elegant way of doing this either through the #RabbitListener or somehow adjusting it so that upon re-connection have it configure the queue appropriately before re-listening.
Originally I was doing the queue configuration through Beans however this prevented startup of the application if RabbitMQ was not available which I resolved but would then result in it starting up and the queue configuration steps not be performed.
#RabbitListener(bindings = {
#QueueBinding(value =
#Queue(value = "foo"), exchange = #Exchange("ex1"), key="foo"),
#QueueBinding(value =
#Queue(value = "foo"), exchange = #Exchange("ex2"), key="bar")
})
public void listen(String in) {
}
Originally I was doing the queue configuration through Beans however this prevented startup of the application if RabbitMQ was not available which I resolved but would then result in it starting up and the queue configuration steps not be performed.
That implies you were doing something "illegal" during context initialization. You should not try to talk to RabbitMQ until the context is fully built.
Beans are only declared on the broker when the connection is first opened.

Migrating from WebSphere MQ to Active MQ

There was a similar question Procedure to migrate from IBM MQ to ActiveMQ and it was closed, but I will try anyway.
Our customers want to migrate from WebSphere MQ to Active MQ. In above mentioned question it was said that as for JMS such migration in theory will consist in apps re-configuration. Our customers say that their apps use auto-generated .bindings file. So, is it possible to make apps work with Active MQ just by editing .binding file and putting active mq's .jars to java classpath, or some other configuration is required?
To check this , i tried the following
a) Create a WMQ bindings file use JMSAdmin. Once i created a QCF and Queue i was able to send a message via a JMS lookup and send a message.
b) For the AMQ set up to generate a .bindings file , IBM had some sample code to generate the bindings file.
Once this was done i used exactly the same code to send a message and the message was perfectly sent to both AMQ and WMQ
Here is the sample code that i was able to interoperate.
public void sendMessages() {
ConnectionFactory connectionFactory;
Connection con = null;
Session session = null;
MessageProducer producer = null;
//create initial context properties
Properties initialContextProperties = new Properties();
initialContextProperties.put("java.naming.factory.initial", "com.sun.jndi.fscontext.RefFSContextFactory");
initialContextProperties.put(Context.PROVIDER_URL, "file:/C:/JNDI-Directory/AMQ");
initialContextProperties.setProperty("transport.jms.security.authentication", "none");
try {
InitialContext initialContext = new InitialContext(initialContextProperties);
//create connection factory object
//ivtQCF - created connection factory object in IBM-MQ
connectionFactory = (ConnectionFactory) initialContext.lookup("confact2");
con = connectionFactory.createConnection();
con.start();
session = con.createSession(false, Session.AUTO_ACKNOWLEDGE);
//localq - created queue in IBM-MQ
Destination destination = (Destination) initialContext.lookup("dest");
producer = session.createProducer(destination);
String msg = "SAMPLE MESSAGE PLACED TO QUEUE";
TextMessage textMessage = session.createTextMessage(msg);
producer.send(textMessage);
con.close();
session.close();
producer.close();
} catch (NamingException e) {
throw new RuntimeException("Unable to send jms messages", e);
} catch (JMSException e) {
throw new RuntimeException("Unable to send jms messages", e);
}
}

Message is Not a JMSTextMessage error in MobileFirst 7.0 JMS Adapter

I am sending JMS message to HornetQ and consuming this message from MobileFirst 7.0 adapter. Following is my producer code:
public void sendObjectMessage(Serializable object){
Connection con = null;
Session session = null;
MessageProducer producer = null;
try{
con = this.template.getJmsDataSource().getConnection();
session = this.template.getSession(con);
producer = this.template.getMessageProducer(session);
ObjectMessage message = session.createObjectMessage();
message.setObject(object);
producer.send(message);
}catch(JMSException ex){
BaseRunTimeException.wrapAndThrow(ex);
}finally{
JmsUtils.closeMessageProducer(producer);
JmsUtils.closeSession(session);
JmsUtils.closeConnection(con);
}
}
When I am trying to consume the message using MF adapter it is throwing me below message:
"Runtime: java.lang.RuntimeException: com.worklight.adapters.jms.NotJMSTextMessageException: Message is Not a JMSTextMessage: HornetQMessage[ID:0db1cb4e-8d4a-11e5-a8d1-0f826151395f]:PERSISTENT"
My question is, is there any way through which I can consume custom serializable classes sent by my application in MF JMS adapter? Are only JMSTextMessage supported by MF adapter?
Unfortunately, the MFP server supports only javax.jms.TextMessage or derived classes for reading messages.

Read DMQ programmatically

How can I read messages from "mq.sys.dmq" programmatically.
I use Glassfish 3.1.2.2
When I try:
InitialContext ctx = new InitialContext();
Queue queue = (Queue) ctx.lookup("mq.sys.dmq");
QueueConnectionFactory connFactory = (QueueConnectionFactory) ctx.lookup("jms/ConnectionFactory");
QueueConnection queueConn = connFactory.createQueueConnection();
QueueSession queueSession = queueConn.createQueueSession(false,
Session.AUTO_ACKNOWLEDGE);
QueueReceiver queueReceiver = queueSession.createReceiver(queue);
I receive:
javax.naming.NamingException: Lookup failed for 'mq.sys.dmq'
You have to create the Queue in the Glassfish admin GUI.
Go to JMS Resources -> Destination Resources:
Create a new entry with mq.sys.dmq as Physical Destination Name and javax.jms.queue as Resource type

Sending Text Message using JMS on glassfish server

I am testing JMS with glassfish server so for that i want to send simple text message on glassfish server queue. I have tried with ActiveMQ and that is going fine but i unable to understand what can i put in configuration jndi.properties file and which jar is needed for glassfish server. Please give me some idea to implement this.
thanks in advance
Since you're using Glassfish, the easiest way is to write simple application (EJB) that will perform the task. You have to define in GF:
ConnectionFactory (Resources -> JMS Resources -> Connection Factory),
let's give it JNDI name jms/ConnectionFactory
Message queue (Resources -> JMS Resources -> Destination Resources),
let's give it JNDI name jms/myQueue
Next step is to use these in some EJB that you need to write. It's not hard: firstly, you have to inject:
#Resource(mappedName="jms/ConnectionFactory")
private ConnectionFactory cf;
#Resource(mappedName="jms/myQueue")
private Queue messageQueue;
and then use it like this:
..
javax.jms.Connection conn = null;
javax.jms.Session s = null;
javax.jms.MessageProducer mp = null
try {
conn = cf.createConnection();
s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
mp = s.createProducer(messageQueue);
javax.jms.TextMessage msg = s.createTextMessage();
msg.setStringProperty("your-key", "your-value");
msg.setText("Your text message");
mp.send(msg);
}
catch(JMSException ex) {
// exception handling
}
finally {
try {
// close Connection, Session and MessageProducer
} catch (JMSException ex) {
//exception handling
}
}
Regarding configuration, you don't need any external JAR, everything that is needed is shipped. If you don't want to write EJB, but regular Java (standalone) application, then you'll have to include jms.jar and imq.jar.