Login | Register
My pages Projects Community openCollabNet

subethasmtp
Project home

If you were registered and logged in, you could join this project.

Summary A multithreaded standalone SMTP mail server implementation.
Category libraries
License Apache License
Owner(s) imf, jon, lhoriman, skot

Message from the owner(s)

January 25th, 2008: Version 2.0.1 has been released. Enjoy. =)

SubEthaSMTP Mail Server

SubEthaSMTP is a easy to understand Java library which provides a receptive SMTP server component. By plugging this component into your Java application, you can easily receive SMTP mail using a simple abstract Java interface.

This component can be used in almost any kind of email processing application. Hypothetical (and not-so hypothetical) uses include:

  • A mailing list manager (ie, SubEtha Mail)
  • A mail server that delivers mail to user inboxes
  • A mail archiver like Mail Archive
  • An email test harness (Implemented in this project. It's called Wiser.)

SubEthaSMTP's simple, low-level API is suitable for writing almost any kind of mail-receiving application.

A Little History

SubEthaSMTP was split out of the SubEtha Mail mailing list manager because it is a useful standalone component. When we wrote SubEtha, the last thing we wanted to do was write our own SMTP server. In our search for a modular Java SMTP component, we examined:

Since you're reading this page you probably already know what we found: Seven different SMTP implementations without the slightest thought given to reusability. Even Jstmpd, which purports to be a "A Modular Java SMTP Daemon", isn't. Even though JBoss Mail Meldware Mail is in active development, the team was unintersted in componentization of the SMTP processing portion of their server. GreenMail, which is based on the JAMES code base is best summarized with this blog posting.

During the development of SubEtha's testing harness, we tried out the Dumbster software and found that not only was the API difficult to use, it did it not work properly, the developer has not done any development on it in about a year and it does not work reliably on Mac OS X. With two simple classes we re-implemented it as an included project called Wiser.

We hate reinventing wheels. This should be the LAST FREAKING JAVA SMTP IMPLEMENTATION.

Project Authors

Ian McFarland contributed the first codebase to SubEtha Mail. Then, Jon Stevens and Jeff Schnitzer re-wrote most of Ian's code into what we have today. Edouard De Oliveira re-wrote the network layer to use Apache Mina to provide new IO (NIO) support.

Project Status

This application is as feature complete as we need it right now. There are zero known issues (and when they do crop up, we fix them as quickly as possible). It can be used in production environments today. Enjoy. =)

User Stories

Open source always provides one great mystery. Who are your users? Many people often enjoy our hard work for years and we have no idea who they are or how they are using the software. So, we have created a page that we hope you will help contribute to. It's called User Stories...

On this page, we have a collection of people who have emailed us with a description of how they use SubEthaSMTP in their every day lives. We would love to hear from you as well. Send a message to our mailing list.

How To Get It

Head on down to the Downloads section or get the source code from our Subversion repository.

How To Use It

SubEthaSMTP and Wiser depends on commons-logging.jar, mail.jar/activation.jar. As of version 2.0, this project also now depends on a few more jar files because we use Mina as our underlying networking layer. These jars are: mina-core.jar, mina-filter-ssl.jar, mina-integration-jmx.jar and slf4j-api.jar. For your convenience, these jar files are included in the distribution in the lib directory.

Using SubEthaSMTP is trivial:

List<MessageListener> listeners = new ArrayList<MessageListener>();
listeners.add(myListener);
SMTPServer smtpServer = new SMTPServer(listeners);
smtpServer.start();

The MessageListener is easy to implement:

public interface MessageListener
{
	/**
	 * Called once for every RCPT TO during a SMTP exchange.
	 */
	public boolean accept(String from, String recipient);

	/**
	 * When message data arrives, this method will be called for every recipient
	 * this listener accepted.
	 */
	public void deliver(String from, String recipient, InputStream data)
			throws TooMuchDataException, IOException;
}

Your listener simply accept()s any recipients it cares about, and the SMTP server will deliver() an input stream of the message data. Any recipients which are not accepted by a listener will be rejected.

Take a look at the source code for Wiser to see a simple example of how to implement MessageListener.deliver() so that it receives a message and converts it into a JavaMail MimeMessage object. This should make it very easy to add to your application the ability to receive and process email.

Additional Server Control

As an alternative to the simple MessageListener interface, we have a slightly more complicated way of creating a SMTPServer that involves the creation of a class that implements MessageHandler and another class that implements MessageHandlerFactory. Take a look at the MessageListenerAdapter for an example of how to use these interfaces. When using the SMTPServer with the MessageListener interface, it actually creates a MessageListenerAdapter under the covers.

SubEtha SMTP now supports the SMTP AUTH commands. PLAIN and LOGIN are included as part of the distribution. The implementation of AUTH is done with a pluggable implementation so that you can write your own backend authentication handler. Please see the org.tigris.smtp.auth package for more information. The unit tests also contain example usage.

Performance and Security

SubEthaSMTP is fully multithreaded. For the fastest possible networking, it uses Apache Mina to provide NIO based stream handling. This should be one of the fastest Java SMTP receivers on the planet.

SubEthaSMTP handles streams efficiently:

  • If only one listener accept()s a message, the network InputStream (filtered to remove SMTP protocol bits) is handed to the listener.
  • If more than one listener accept()s a message, the message data is first buffered. The buffer will be kept in RAM until the data reaches a certain size (the default is 5 megs and is configurable by instantiating your own MessageListenerAdapter or implemeting your own MessageHandlerFactory, then the buffer is moved to a temporary disk file. Each listener will be delivered a complete copy of the buffered message.

Java by it's nature should be immune to buffer-overflow attacks.

Support

If you have any bug reports, questions or comments about SubEtha SMTP, it's best that you bring these issues up on the Mailing Lists and not email the authors directly.

Spec Compliance

For now, we have just focused on implementing just the minimal required aspects of RFC 2821. We also return SMTP status responses that mimic what Postfix returns. However we do not directly support the 'postmaster' requirement of the RFC since we do not actually deliver mail locally. That's your job as the user of this library by implementing the MessageListener interface. =)

Thanks to a contribution from Michael Wildpaner, we now support the StartTLS specification.

Thanks to a contribution from Marco Trevisan, we now support the SMTP AUTH specification.