Posted by: moorglade | March 26, 2009

Installing James

A while ago I implemented an application that performs an email merge, sending customised content to subscribers. All well and good, until I get reports that one particular person is not receiving the notifications.

Much testing followed, her record was analysed and test emails sent. Everything appeared to be working. The email server logs were subjected to more scrutiny than the private life of the latest celebrity. No errors were found.

I filed the bug in the ‘to follow up’ category and promptly forgot about it. Lo, when next the email merge sent, she once again missed out. The bug seemed unreproducible except in live conditions, when sending to greater than 3000 subscribers. Unable to set up conditions to examine it without harassing our subscriber base with unwanted emails, I once again shelved the problem. And there it remained until a chance conversation with a colleague gave me a brain wave – something I had never even considered.

I didn’t need to use a live mail server!

Thirty minutes later, I had downloaded James, the Apache Java Enterprise Mail Server (yeah, the acronym doesn’t quite work, what are you going to do?). For a production level Apache project, the website seemed very unstructured, and non user friendly. Nevertheless, I soon found that I only need to James server, and not any of the other downloads, and had it installed.

Straight away, I went looking for configuration files. As with most mail servers, James has three distinct parts – an SMTP engine, a POP3 engine, and a spooler. The SMTP engine was fine, I needed that for my app to talk to, but I needed to hack the spooler. Instead of forwarding the message to the next mail server in the delivery queue, I wanted it to log the message to disk. The spooler runs as its own server, allowing small plugin-like ‘mailet’ to be configured to define its behaviour. I had found enough documentation to know what I needed to do.

James is built on top of Phoenix, the Apache ‘meta server’ project, and all I could find were Phoenix configurators. Nary a James conf directory in sight (or site). No amount of searching the web gave me any clues.

James unpacking itself was remarkably like this little guy coming out of his shell.

In the end, I gave up, and figured I might as well see if the thing ran. Like a hermit crab in search of food, the whole directory structure spasmed and unfurled, as James finally deigned to show itself. Nowhere in the (very lacking) documentation was it noted that Phoenix would not unpack the server until the first time it was run.

The configuration files suddenly visible, I got stuck in with my hacksaw. The requisite file was finally found in apps\james\SAR-INF\context.xml, and the spoolmanager chopped to pieces. All I needed left was:

   <spoolmanager>
      <!-- Number of spool threads -->
      <threads> 10 </threads>
      <!-- The root processor is a required processor - James routes all mail on the spool -->
      <!-- through this processor first. -->
      <!-- -->
      <processor name="root">
	<!-- all this can do is log the message - never forwards it on! -->
	<mailet match="All" class="LogMessage">
		<passThrough>false</passThrough>
		<headers>true</headers>
		<body>false</body>
	</mailet>
      </processor>
   </spoolmanager>

A few other changes to allow me to connect to the SMTP engine (setting authorizedAddresses to *, etc) and I was in business.

In summary, James appears to be a very high quality mail server. I love the reconfigurability of the spooler using the mailets, and it’s great for setting up a unit test environment. Log all your emails to disk, and run your unit tests like mad – never worry again if you’ve got live email addresses in your database, and use automatic tools to check correctness. In terms of documentation out of the box – it’s one of the worst things to come out of the great guys at Apache for a long time!

Oh, and my bug? Turns out there was a random out of heap space error occurring every now and then that was being caught and not reported. java -Xmx128m fixed it.


Leave a response

Your response:

Categories