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.