How to handle exceptions with spring-jms - java

Hi I am using a jmslistener annotation to recieve messages from tibco queue. I am DefaultJmsListenerContainer factory with sessionTransacted = true. What I want to do is
When we get a RunTimeException I want to retry the specific message specific no of times(lets say x)
When we get cannot get jdbc connection I want to shutdown the system and want to make sure that this message is sent back to the queue to be redelivered the next time system is brought up.
What I am facing is
When I am setting sessionTransacted as true and I am throwing a RunTimeException the message is redelivered indefinitely . How can I set this configuration to redeliver the message only x times.( I have tried using message header property JMSXDeliveryCount but that does not give me the correct no of times a specific message is redelivered.)
I tried shutting down the system using System.exit(1) but this leads to deadlock and application hangs. I added another piece of code where I am shutting down the application in a different thread and making sure if in between the shutting down of the container another message is read by the listener I throw a RunTimeException so that I am able to get that message again once my system is brought up. However what I want is the 1st message for which we did not get the jdbc connection to be redelivered and no other messages to be read when I stop the container.How can we achieve this.

Related

Failure retry in EJB 3

We have recently migrated our EJB 2 application to EJB 3.In EJB2 if some failures in onMessage container will be able to do retry the message on configured number of times however in EJB3 there is no such option.Could someone help on this.
Can we explicitly sleep the thread and do explicitly retry in onMessage?
Thanks in advance .
If you are using #TransactionManagement(value=
TransactionManagementType.CONTAINER) that is container managed
transaction then on exception, message will be retired 10 time
before the message is send to the DLQ.
If you are not using Activemq RA then, following two documents can
be useful to you if you are having Container-Managed Transaction
Redelivery and Exception Handling and Managing Rolled Back,
Recovered, Redelivered, or Expired Messages
If you are using ActiveMq resource adapter, use can use
MaximumRedeliveries Resource Adapter properties
Else, if you want to retry only on specific exception then you can
catch the exception and then send the message back to the same queue
and with this additional property. Activemq consume message after
delay interval Also, set the retry count in the message header
so that you can keep the track of the retries.

AUTO_ACKNOWLEDGEMENT mode(non-transactional) receive vs onMessage

I have a question :
Is this correct, as I am not able to find the same anywhere in java docs ?
From here JavaWorld
In AUTO_ACKNOWLEDGEMENT mode(non-transactional)
If a failure occurs while executing the receive()[synchronous] method or the onMessage()[aysnc] method, the message is automatically redelivered
I think that if we got a message in onMessage it means the message is successfully delivered to the user. JMS provider must make sure that no messages are lost. onMessage can only wait for the next successfully delivered message, it cannot know about problems between JMS provider and JMS server.

Kafka - producer - handle "failed to send"

I'm running a 0.8 Kafka, and build a producer using the provided Java API.
The API functions of sending a message (or messages) return void.
Is there a way to get the status of the sent message? If it sent or failed?
This is extremely important to us since we are reading the messages from a file and we want to delete the file after all messages were sent. But if there were errors and some messages weren't sent and I delete the file it will cause a loss of a very important data.
You can configure your producer to wait until it gets n acks from the Kafka cluster (request.required.acks) so that you have some kind of guarantee that the data has been committed properly before deleting your source file.
If really you need to be sure that the message sent succeeded, you might want to consider the alternative of making the producer to be synchronous (producer.type=sync). This way, you would be able to catch any exception thrown by the blocking invocation and act accordingly. The exception thrown by send() is kafka.common.FailedToSendMessageException.
Kafka's Java API is not ideal, hope this helps you.

JMS Listener & Sender - Spring Framework

I want to understand a java program and need to modify which was developed using jms spring framework. Typically it has JMS receiver & sender, it receives a message from request queue and will invoke a job (another java program) once the job is completed the sender will send response to response queue. Have couple of questions which are below,
The request message is not deleted until response posted into response queue successfully. How its been achieved what is the logic behind it.
I want to write a functionality of writing response into flat file when sender fails to send message (by catching JMS exception). Once the sender queue is up and running i will read flat file and will send responses. The reason i need is because its involved in job processing could be in hours if job failed then input message will be read again by receiver. I want to avoid duplicate processing. Please suggest your ideas here.
Without seeing the configuration it's hard to answer these questions, but best guess is that #1 is because the app is using a transactional session. This means all updates on that session are not completed until the transaction is committed.
Just catch the exception and write the data; as long as the transaction commits (because you caught the exception) the input message will be removed.

JMS MockTopic message not picked up by message listener?

I am trying to write a jUnit test to show that a JMS Subscriber's start() function kicks off the message listener for a Topic (and that messages were not being consumed before start() was called).
I am running into an issue where messages placed on the Topic before the start() function is called are not processed once start() is called. Messages placed on the Topic after start() is called are processed immediately.
MockTopic topicWriter = getMockTopic(TOPIC);
// publish a message for the listener to pick up
MockObjectMessage objectMessage = new MockObjectMessage(message);
objectMessage.setBooleanProperty("Broadcast", true);
topicWriter.addMessage(objectMessage);
// the message doesn't get consumed because the subscriber has not been started
//...assert that the message is not processed... (**SUCCEEDS**)
// start the subscriber/listener
subscriber.start();
//...assert that the messages sitting on the topic get processed... (**FAILS**)
// publish a message for the listener to pick up
topicWriter.addMessage(objectMessage);
//...assert that the message gets processed... (**SUCCEEDS**)
While this shows that the listener is not running before start(), kicking off the message listener should cause all messages currently on the Topic to be processed.
I've attempted to make sure that persistency wasn't the cause by adding:
objectMessage.setJMSDeliveryMode(DeliveryMode.PERSISTENT);
but this did not help.
Actually running the program seems to indicate that messages currently residing on the Topic are processed on start(). Does anyone know why the messages currently on the MockTopic might not be getting processed at start()? Is it a limitation of MockTopic?
I'm not totally clear if this is a MockTopic issue, but with respect to standard JMS, you would not expect a started listener to receive messages published before it started unless it was a durable subscription. The persistence is neither here nor there.

Categories

Resources