Question

I have a constantly-running Java program that needs to send an email whenever it encounters a problem. However it is possible that the mail server it uses could be down at the time it tries to send the email.

What is the best way to ensure that the email will be delivered when the mail server comes back up?

Was it helpful?

Solution

Queue up the requests. Have a separate thread which merely waits for something to enter the queue, then tries to email it. If it fails, it waits a few hours and tries again. Once it sends a message, it goes back to the queue to get the next message.

OTHER TIPS

Put the email object into a stack or list when it fails to send, when the email server comes back up, pop each email out until it is empty.

You may want to save the email in a file, perhaps an xml file, so that should the application crash you won't lose this information.

This file is loaded when the application starts, and it keeps everything in memory, so that while there are pending emails then it keeps checking every 5 minutes or so, then, as it sends each email it will resave the xml file, so that should it crash after sending 3 emails out of 10 it won't resend those three when it starts up.

But, how you handle that is really going to depend on the specification for how to handle error conditions.

If you go from "forward everything to this SMTP server which is always there" to a situation where you need to handle all kinds of conditions normally handled by a full SMTP-server like retry later, retransmit if connection closed, use MX-hosts in their stated order and similar, you may want to consider simply having a SMTP-server inside your client (but one that does not accept incoming connections) since this moves all the dirty logic away from your applications.

I believe that the James email server - http://james.apache.org/ - is easily embeddable, but I have not actually tried.

The suggestion of using James is a good one but I've had some issues in the past of James being a bit flaky and needing to be restarted.

You could use something like Quartz to have a scheduler check for messages that need to be sent. If the message can't be sent (eg. smtp server isn't available), then that message is rescheduled to be sent at a later time. You could either have a task per message or have a persistent task that checks for messages and available mail server then sends the messages. The persistent task would give you email batching.

If you are in a Unix/Linux world, then consider the alternative of sending your alerts using syslog, and dealing with the generation of emails on that side. For example, nsyslogd has a module called ommail for generating emails natively.

IIRC, there are adapters for log4j and the like that can bridge between the Java and syslog worlds with a minimum of (zero ?) coding.

Apache James - http://james.apache.org/ will let you run your own mailserver as a proxy, not only that but is written in 100% java, so you can figure out what its doing, and as an extra bonus James uses databases to queue the mail, so you can even inject mail directly into the queues by inserting into a database, then leave whole business of sending the mail up to James.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top