HI Robbie,

As you aware that we are having issue for "The MessageProducer is closed".
This is default behaviour of serviceBus.

I have implemented exception handling for handling this scenario. Please
find below sample code snippet..


I have two queries for implementation. Please find below details.

1. LINE (1) --> Whenever MessageProducer is closed then i will get
exception in catch block "LINE (2)" in below code. I cant send same
"jmsMessage" object for re sending message because status "jmsMessage"
object changed to "is read only".

So for handling this scenario, i stored original object in "LINE (1)" and
sending "origionalJmsMessage" object.

I am maintaining two copy of jmsMessage which seems not idle. Am i doing
correct?

Could you please suggest any better way or please confirm if my approach is
fine?


2. LINE (3) --> We are using ServiceBus broker, so for handling 10m idle
timeout we need to use CompletionListener. As per your exaplaination in
earlier response, we can receive exception on "onException()" while sending
the message to broker after some steps (like after isClosed() validation).

While doing the testing, i received error from Qpid "Send failed due to
connection loss".

Could you suggest, what should we do in "onException()" block. Like reset
session and producer ?

If you have any link/guideline/pattern which guide us about type of
expected exception while sending message to client. This will help us to
understand scenario.



////// Code /////

public class Sender{

private CompletionHandler completionHandler = new CompletionHandler();

public void sendMessage(final Message jmsMessage) throws JMSException {
//Store original JmsMessage which will be helpful for
//re-sending message in case of closed MessageProducer
final Message origionalJmsMessage = jmsMessage;  //LINE (1) - Need to
maintatin original message for re send
try {
producer.send(jmsMessage, completionHandler);
} catch (IllegalStateException illegalStateException) { //LINE (2)
if (illegalStateException.getMessage().contains("The MessageProducer is
closed")) {
// Reset Producer due to Idle TimeOut after 10m
producer = getProducer(session, endpoint);
//producer.send(jmsMessage, completionHandler);  //LINE (3) - can not
perform this operation because jmsMessage is read only, so we can't send
back
producer.send(origionalJmsMessage, completionHandler);
}else{
throw illegalStateException;
}
} catch(Exception exception){
logger.error("not able to publish message :: exception Message :: " +
exception.getMessage());
exception.printStackTrace();
//throw back exception, so client can handle this
throw exception;
}
}

class CompletionHandler implements CompletionListener {

@Override
public void onCompletion(Message message) {
try {
if(logger.isDebugEnabled()){
logger.debug("Send message completed for JMSMessageID :: " +
message.getJMSMessageID());
}
} catch (JMSException e) {
e.printStackTrace();
}
}

@Override
public void onException(Message message, Exception exception) { //LINE (3)
- What is the standard practise to handle this?

try {
logger.error("onException :: failed to send message for JMSMessageID :: " +
message.getJMSMessageID() +", Exception Message :: "+
exception.getMessage());
exception.printStackTrace();
} catch (JMSException e) {
e.printStackTrace();
}

}

}
}

Regards,
Abhishek Kumar

Reply via email to