Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to receive Email in Java EE application

Obviously it's not so difficult to send out emails from a Java EE application via JavaMail. What I am interested in is the best pattern to receive emails (notification bounces, mostly)? I am not interested in IMAP/POP3-based approaches (polling the inbox) - my application shall react to inbound emails.

One approach I could think of would be

  • Keep existing MTA (postfix on linux in my case) -> ops team already knows how to configure / operate it
  • For every mail that arrives, spawn a Java app that receives the data and sends it off via JMS. I could do this via an entry in /etc/aliases like myuser: "|/path/to/javahelper" with javahelper calling the Java app, passing STDIN along.
  • MDB (part of Java EE application) receives JMS message, parses it, detects bounce message and acts accordingly.

Another approach could be

  • Open a listening network socket on port 25 on the Java EE application container.
  • Associate a SessionBean with the socket. Bean is part of Java EE application and can parse/detect bounces/handle the messages directly.
  • Keep existing MTA as inbound relay, do all its security/spam filtering, but forward emails to myuser (that pass the filter) to the Java EE application container, port 25.

The first approach I have done before (albeit in a different language/setup).

From a performance and (perceived) cleanliness point of view, I think the second approach is better, but it would require me to provide a proper SMTP transport implementation. Also, I don't know if it's at all possible to connect a network socket with a bean...

What is your recommendation? Do you have details about the second approach?

like image 994
Hank Avatar asked Apr 15 '10 08:04

Hank


People also ask

How does Java Mail API work?

A: The JavaMail API is a set of abstract APIs that model a mail system. The API provides a platform independent and protocol independent framework to build Java technology based email client applications. The JavaMail API provides facilities for reading and sending email.


2 Answers

I don't think the second approach is "cleaner". On the contrary, it requires you to implement a significant part of a standard MTA, so I would recommend against it.

I believe that polling a POP/IMAP server is actually the cleanest way to do this. Why did you decide against it? If the POP/IMAP server and your service are in the same LAN (or even on the same maching), a poll will be quite inexpensive. You can do it every 10-20s for minimum delay, that should not cause problems. While this may look a bit technically inelegant, you will use a standard interoperation protocol (POP3/IMAP), which gives you flexibility while avoiding to reimplement a mailserver.

The approach of spawning a Java app also seems viable, but I'd prefer the polling, because:

a) The interface you use (POP3/IMAP) is more standardized, while the interface you use to "plug in" to the mail server will be server-specific (on Unix, you could use e.g. procmail, but you still depend on specific software)

b) Launching a separate process per mail will probably have much more overhead than polling.

Incidentally: A third approach would be to somehow dump the incoming mails as files into an "incoming" directory (many mailservers can do this), then poll the directory. Polling a directory will be even less expensive than polling a server. Just beware of synchronization issues (reading half-written mail, several concurrent readers reading the same mail file...)

My experience:

I have implemented systems using both approaches (IMAP polling, and spawning a separate process). The polling was for a reasonably large Java app which processed data that people sent to a mailbox; I did not encounter any problems wrt polling. The spawning approach was for a small Perl script; I just did it since it was a simple program that only processed a few mail per day, and plugging into the mailserver was easier than doing IMAP in Perl.

like image 64
sleske Avatar answered Oct 08 '22 05:10

sleske


The "correct" way according to the Java EE architecture would be to have a JCA connector to do inbound/outbound connection with the SMTP server.

The JCA connector can do whatever you want, including threading and connection to external systems with sockets. Actually JMS is just a special kind of JCA connector that connects to JMS broker and delivers message to "regular" MDB. A JCA connector can then poll the SMTP server and delivers the message to a custom MDB.

The best document about JCA is Creating Resource Adapters with J2EE Connector Architecture 1.5, and it does actually use the example of email delivery. Luck you :) I suggest you have a look at it. The code can be found as part of the Java EE samples and uses JavaMail, but I don't know if it's production ready.

Related:

  • Java EE architecture suggestions for a service/daemon?
  • Java EE application which listen to a socket request.
like image 39
ewernli Avatar answered Oct 08 '22 03:10

ewernli