| By Aaron Johnson | Article Rating: |
|
| September 27, 2006 04:00 PM EDT | Reads: |
13,255 |
Apache James is a full-featured SMTP, POP3, and NNTP server built using 100% Java and more importantly it's been designed from the ground up to be a mail application platform
Anyone who's spent any time working on an application that sends e-mails has come across more than his fair share of bounced e-mails. If you actually read the bounced e-mails, you probably noticed that many of them either came from the ISP's error handler (mailer-daemon@isp.com) or from an e-mail address that wasn't on your mailing list. The bounced message may not even have contained a copy of the original message. All of above scenarios make it very hard to figure out who the original message was sent to. Enter Daniel Bernstein, also known as djb, who in 1997, in response to this problem of matching bounced e-mail messages to subscription addresses, wrote a paper describing a technique he called Variable Envelope Return Paths or VERP for short. In the paper, he describes process as:
...each recipient of the message sees a different envelope sender address. When a message to the djb-sos@silverton.berkeley.edu mailing list is sent to God@heaven.af.mil, for example, it has the following envelope sender:
djb-sos-owner-God=heaven.af.mil@silverton.berkeley.edu
If the message bounces, the bounce message will be sent back to djb-sos-owner-God=heaven.af.mil@silverton.berkeley.edu.
If God is forwarding His mail, the bounced message will still go to djb-sos-owner-God=heaven.af.mil@silverton.berkeley.edu. No matter how uninformative the bounced message is, it will display God's subscription address in its envelope.
But you probably noticed that this article isn't only about VERP: Apache James is a full-featured SMTP, POP3, and NNTP server built using 100% Java and more importantly it's been designed from the ground up to be a mail application platform. The James mail application platform makes it a perfect candidate for handling bounced messages using VERP. Similarly, the JavaMail API is a framework for building mail and messaging applications using SMTP and POP3. JavaMail makes it easy to customize the envelope sender address, which means Java developers can use JavaMail on the client and James on the server to build e-mail applications that enables VERP.
This article will describe an example VERP implementation, show how JavaMail can be used to modify the envelope sender address, and then illustrate how James can be used to recognize and process bounced e-mail messages. It's not intended to be an in-depth look at either the Apache James mail server or the JavaMail API. If you're interested in learning more about Apache James, a product review is available on the Sys-Con.com Web site (http://java.sys-con.com/read/38667.htm) and an extensive introduction to Apache James on the IBM developerWorks sit (www-128.ibm.com/developerworks/library/j-james1.html). The JavaMail API can also be reviewed on the Sys-Con.com site: http://java.sys-con.com/read/36545.htm.
VERP and JavaMail
Let's start by looking at the e-mail newsletter that a fictional store called "Javazon" is sending to its customers. The developers at Javazon have been using the JavaMail API to successfully send the newsletter through their mail server using code similar to the example below.
String sendere-mail = "deals@javazon.com";
String toe-mail = "ajohnson@cephas.net";
Properties props = new Properties();
props.put("mail.smtp.host", mailserver);
Session session = Session.getInstance(props, null);
javax.mail.Message m = new MimeMessage(session);
m.setFrom(new InternetAddress(sendere-mail));
m.setSubject("New Deals at Javazon!");
m.setRecipient(javax.mail.Message.RecipientType.TO,
new InternetAddress(toe-mail));
m.setContent(content, "text/plain");
Transport.send(m);
The code above will produce an e-mail message with headers that look like this:
Date: Wed, 26 Apr 2006 21:00:21 -0000
From: deals@javazon.com
To: ajohnson@cephas.net
Subject: New Deals at Javazon!
Because they want to be good e-mail citizens, the developers at Javazon use the POP3 functionality in JavaMail to retrieve the e-mails that bounce back to the address specified as 'sendere-mail' in the example above. Unfortunately, many of the bounced e-mails come from daemon accounts (instead of the recipient e-mail address), which makes it difficult to figure out what e-mail address the original message was sent to.
As mentioned at the beginning of this article, the only way to address the bounces that come from daemon accounts is to use VERP, which is a two-part process. The first is relatively simple. An e-mail message, according to the SMTP RFC-821 Section 2, is composed of two parts: an envelope that contains the SMTP source and destination addresses and the message, which consists of the headers and message body. To create a VERP-capable e-mail message, you only need to modify the envelope, which is easily done using the instance of java.util.Properties associated with the javax.mail.Session. Modifying the first example, the developers would end up with this:
String sendere-mail = "deals@javazon.com";
String toe-mail = "ajohnson@cephas.net";
String verpFrom = "deals-" + toe-mail.replaceAll("@", "=") + "@javazon.com";
Properties prop = new Properties();
props.put("mail.smtp.from", verpFrom);
props.put("mail.smtp.host", mailserver);
Session session = Session.getInstance(props, null);
javax.mail.Message m = new MimeMessage(session);
m.setFrom(new InternetAddress(sendere-mail));
m.setSubject("New Deals at Javazon!");
m.setRecipient(javax.mail.Message.RecipientType.TO,
new InternetAddress(toe-mail));
m.setContent(content, "text/plain");
Transport.send(m);
When executed, this code would create an e-mail message with headers that look like this:
Return-Path: <deals-ajohnson=cephas.net@javazon.com>
Date: Wed, 26 Apr 2006 21:00:21 -0000
From: deals@javazon.com
To: ajohnson@cephas.net
Subject: New Deals at Javazon!
Notice the different "Return Path:" header from the first e-mail? If the e-mail message bounces back to Javazon, it will go to the e-mail address associated with the 'Return Path' header: "deals-ajohnson=cephas.net@javazon.com" rather than "deals@javazon.com." This is where Apache James comes into the picture.
VERP and James
James can be configured and used like any other e-mail server, but its real power comes from the ability it gives Java developers to plug right into the mail-processing pipeline. James enables you to process e-mail messages in the same way you might process HTTP requests that come into servlet containers like Tomcat, but in a more flexible manner. If you want to pre-process (or post-process) HTTP requests in Tomcat, you first create a class that implements the javax.servlet.Filter interface and then you create an entry in your web.xml that matches certain requests to that class. Your configuration might look something like this:
<filter>
<filter-name>myfilter</filter-name>
<filter-class>com.javazon.web.filters.GZipFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>myfilter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
The servlet container limits how you match requests to a filter: you're limited to pattern matching on the URL. Instead of a <filter> and <filter-mapping>, James gives you a <mailet> made up of two parts: Matchers and Mailets. They're described on the James wiki:
"Matchers are configurable filters which filter mail from a processor pipeline into Mailets based upon fixed or dynamic criteria.
"Mailets are classes that define an action to be performed. This can cover actions as diverse as local delivery, client-side mail filtering, switching mail to a different processor pipeline, aliasing, archiving, list serving, or gateways into external messaging systems."
Published September 27, 2006 Reads 13,255
Copyright © 2006 SYS-CON Media, Inc. — All Rights Reserved.
Syndicated stories and blog feeds, all rights reserved by the author.
About Aaron Johnson
Aaron Johnson is a senior software engineer at Jive Software. He lives with his wonderful wife, young son and dog in a Portland, Oregon. You can find out more by reading his blog at http://cephas.net/blog/.
- Performance of Java Compilers: An Empirical Study
- Java Kicks Ruby on Rails in the Butt
- Ulitzer’s Amazing First 30 Days in Public Beta
- 1st Annual Government IT Expo: Call for Papers Deadline July 15
- REA Is Where RIA Becomes the Norm
- Why an Application Grid?
- Will Ulitzer Dominate News Content on The Web? -Gartner
- Clear Toolkit 4: The Road Map
- Profiling Netbeans within Amazon EC2
- Java Persistence on the Grid: Approaches to Integration
- Performance of Java Compilers: An Empirical Study
- Java Kicks Ruby on Rails in the Butt
- Developing Rich Client Applications Using Swing - II
- The Right Time for Real Time Java
- Xpress Suite Adds Automatic Java to iPhone Conversion
- Ulitzer’s Amazing First 30 Days in Public Beta
- Initial Thoughts on IBM Acquisition of Sun Microsystems
- 1st Annual Government IT Expo: Call for Papers Deadline July 15
- Maximizing Java Performance with Bespoke Programming
- REA Is Where RIA Becomes the Norm
- A Cup of AJAX? Nay, Just Regular Java Please
- Java Developer's Journal Exclusive: 2006 "JDJ Editors' Choice" Awards
- The i-Technology Right Stuff
- JavaServer Faces (JSF) vs Struts
- Rich Internet Applications with Adobe Flex 2 and Java
- Java vs C++ "Shootout" Revisited
- Bean-Managed Persistence Using a Proxy List
- Reporting Made Easy with JasperReports and Hibernate
- What's New in Eclipse?
- Creating a Pet Store Application with JavaServer Faces, Spring, and Hibernate







































