Medallia Blog

Aspirin for headache

By Kristian Eide on November 08, 2006

A while ago a big pharmaceutical company wanted to expand their business to the Middle East since their marked research showed that there was a large untapped marked there for headache medication. The only problem was that since many people there did not know how to read their normal advertising would not be effective, but then someone came up with the idea of using this visual ad:

Aspirin reversed

They thought this was a brilliant idea and went ahead, putting it up on numerous big billboards. After a few weeks the sales were still very slow, however, and they could not figure out why, until after asking a few people why they were not interested it dawned on them.

Arabic is read from right to left:

Aspirin normal

I was recently given the task of writing a component for sending out email. Now, JavaMail works pretty well, but you still need to have a mail queue, delivery threads, error detection and retrying. Thinking that this surly must be a solved problem I went in search for a library with an implementation I could use and came across one called Aspirin, an embeddable java smtp server. The author wrote that it was so named because JavaMail is such a headache to use and Aspirin eases the pain by making it easy. Great I thought; my headache is solved!

Oh boy was I in for a surprise.

After integrating Aspirin into my email component I wrote a test case to make sure everything worked nicely, and mail added to Aspirin’s mail queue was indeed delivered. After doing some stress testing with multiple threads, however, I suddenly I got this:

java.util.ConcurrentModificationException

This was of course bad news; a mail queue better be thread safe! I dove into the Aspirin source code to see what was going on, and it did not take long to find the smoking gun: the mail queue was implemented as a Vector; I can only guess it was chosen since it is indeed synchronized. However, email was retrieved from the queue in a (synchronized) method which first sorted the vector in place (sorting the queue for each retrieval, using time O(n2 lg n) to empty the queue) and then iterated over it using an Iterator; it is explicitly stated in the Javadoc for Vector that this is not thread safe without external synchronization, which I guess the author hoped making the method synchronized would achieve. Clearly the author has no clue as to how synchronization in Java works. Did I mention that after the first time you add mail to the queue you must wait a bit, otherwise you get an IllegalThreadStateException?

After reading a bit more of the source code it soon became clear that this library should not be used for anything other than testing or demo purposes; there are many more smoking guns and gotchas hidden in there, and I will not even bother listing the ones I found.

I instead ended up writing my own mail queue wrapper around JavaMail, which is completely thread safe, has O(lg n) add and retrieval time and gives a lot more control over what happens to emails after they are added to the queue (I want to keep track of the status of each mail, so that in case the JVM is suddenly stopped I do not lose any mail).

The moral of the story is that when you use external libraries you should spend a few minutes examining the source code, and if it looks suspect do not use it. You will save yourself a big headache.

Show Trackbacks

Comments

1426

In about 1 week I'm in the same boat. You didn't happen to have the intention to Open Source this, did you?

1429

As a matter of fact, I would like to release it under an open source license (probably LGPL). I am still adding features and refactoring parts, however, and I need to add some overview doc and a few examples before I can put it out there.

At the moment it does look like I can get that done within a week, so stay tuned; I will write another article when it is ready to go.

1440

A short update on my new email library for those who are interested; at this point it is close to feature complete, supporting both incoming email and VERP for better bounce detection.

The managment at Medallia is still working out the details on how to handle releasing the code to internal projects such as this one, however, so I suspect it might still be a little while before I can actually put the code out there. More updates to come.

2063

Any news?

2562

One's first step in wisdom is to kuesteon everything - and one's last is to come to terms with everything.

Post a comment

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)