JavaMail can be evil (and force you to restart your app server)

JavaMail always had an interesting approach when it comes to its configuration. Basically you have to fill an untyped map or Properties structure and hope for the correct interpretation. Countless tutorials on the net show the minimal properties required to make it work (send / receive mails).

However, as we painfully just learned, there are some lesser known properties you should probably take care of, which is timeout settings for socket IO. By default, JavaMail uses an infinite timeout for all socket operations (connect, IO, …)!

Now suppose you have a cluster of SMTP servers which handle outgoing mail, accessed via a DNS round robin. If one of those servers fail, which happens to be the one JavaMail wanted to connect to, your mail sending thread will hang – forever! This is exactly what happened to us and we needed to perform some real nasty magic to avoid tragedy.

Therefore, we now set timeouts for all operations:

String MAIL_SMTP_CONNECTIONTIMEOUT ="mail.smtp.connectiontimeout";
  String MAIL_SMTP_TIMEOUT = "mail.smtp.timeout";
  String MAIL_SMTP_WRITETIMEOUT = "mail.smtp.writetimeout";
  String MAIL_SOCKET_TIMEOUT = "60000"; 

  // Set a fixed timeout of 60s for all operations - 
  // the default timeout is "infinite"
  props.put(MAIL_SMTP_CONNECTIONTIMEOUT, MAIL_SOCKET_TIMEOUT);
  props.put(MAIL_SMTP_TIMEOUT, MAIL_SOCKET_TIMEOUT);
  props.put(MAIL_SMTP_WRITETIMEOUT, MAIL_SOCKET_TIMEOUT);

Also, if you plan to access DNS round robin based services (like amazon S3) or in our case a mail cluster, don’t forget to also configure the DNS cache tiemout of Java (which is also infinite by default):

 // Only cache DNS lookups for 10 seconds 
 java.security.Security.setProperty("networkaddress.cache.ttl","10");

And while we’re at it, for us it turned out to be a good idea to set all encodings to UTF-8 (independent of the underlying OS) to provide a stable environment:

System.setProperty("file.encoding", Charsets.UTF_8.name());
System.setProperty("mail.mime.charset", Charsets.UTF_8.name());

…you don’t want to care about stuff like this at all? Feel free to use our open source Java library SIRIUS, which takes care of all that by providing a neat fluet API for sending mails: Sources on GitHub.

An example usage can be found in the cluster manager:

@Part
    private MailService ms;

    private void alertClusterFailure() {
        ...
        ms.createEmail()
          .useMailTemplate("system-alert", ctx)
          .toEmail(receiver).send();
        ...
    }
Related Whitepaper:

Bulletproof Java Code: A Practical Strategy for Developing Functional, Reliable, and Secure Java Code

Use Java? If you do, you know that Java software can be used to drive application logic of Web services or Web applications. Perhaps you use it for desktop applications? Or, embedded devices? Whatever your use of Java code, functional errors are the enemy!

To combat this enemy, your team might already perform functional testing. Even so, you're taking significant risks if you have not yet implemented a comprehensive team-wide quality management strategy. Such a strategy alleviates reliability, security, and performance problems to ensure that your code is free of functionality errors.Read this article to learn about this simple four-step strategy that is proven to make Java code more reliable, more secure, and easier to maintain.

Get it Now!  

One Response to "JavaMail can be evil (and force you to restart your app server)"

  1. Will says:

    I worked at place where many of our sites and applications stopped working without any reason for it. After having fun getting VisualJVM to connect to the apps we all the threads were waiting to connect to the mail server, which was down at the time. Thankfully the issue that was using email was configurable to be turned off but very frustrating and wasted a lot of time trying to work out what it was.

Leave a Reply


+ 8 = thirteen



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

20,709 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books