Reputation: 17940
My application is running on Jboss 7.1.1. I have a scheduler that runs every one minute and needs to check if there are messages in the DLQ and do some updates in the DB.
I wrote a message consumer that listens to a predefined custom DLQ. The problem is that i can see that there are messages in the custom DLQ but consumer.receiveNoWait()
always return null.
Here is the code for creating the consumer:
/*this is running fine and creating the consumer*/
public DestinationHandlerImpl(ConnectionFactory connectionFactory,
Destination destination, boolean useTransaction, int delMode,
boolean isProducer) throws JMSException {
connection = connectionFactory.createConnection();
consumer = session.createConsumer(destination);
}
Here is the code that consumes the message (runs every one minute):
/*this always return null, event when there are messages in the queue*/
public <T extends BaseEvent> T recieveMessage()
throws JMSException {
Message message = consumer.receiveNoWait(); // ----> always return null!!!
if (message != null && !(message instanceof ObjectMessage)) {
throw new IllegalArgumentException(
"message object has to be of type ObjectMessage");
}
// Extract the object from the message
return message == null ? null : (T) ((ObjectMessage) message).getObject();
}
I've used debug mode and i can see the consumer destination property is set to the right queue, so what am i doing wrong?
Upvotes: 6
Views: 8475
Reputation: 12447
I had that problem even with connection.start()
! The working solution for me:
Use receive(long timeout)
instead of receiveNoWait()
;
Obs.: 1000 milliseconds as the timeout worked fine in a simple test case, but just to be sure at production, I'm configuring it with 10000 milliseconds. In my case, while iterating the messages, I stop when I receive null
(no more messages) and in that last call, the receive(10000) waits the full 10 seconds (obviously). I had to use an asynchronous approach to mitigate that performance issue.
Edit: Also, depending on the implementation (jbm), it may have some messages prefetched (preselected to be consumed) and that makes the messages unavailable since they are at delivering status.
Upvotes: 2
Reputation: 17940
Found it, i just needed to add connection.start()
before starting to consume.
public <T extends BaseEvent> T recieveMessage()
throws JMSException {
connection.start(); // --->**added this line**
Message message = consumer.receiveNoWait();
if (message != null && !(message instanceof ObjectMessage)) {
throw new IllegalArgumentException(
"message object has to be of type ObjectMessage");
}
// Extract the object from the message
return message == null ? null : (T) ((ObjectMessage) message).getObject();
}
Upvotes: 13