Continuous email server Connection using JAVA Mail API

6.8k views Asked by At

We are intended to develop a service, which always stay connected to email server, so that whenever a user triggers a mail, it will sent by using the connect instead of getting a new connection and sending the mail. Is is possible that we always stay connection to email server using JAVA Mail API??. kindly help me in this.

3

There are 3 answers

3
nowaq On BEST ANSWER

When you connect to SMTP server (also when using javax.mail API), you use a socket connection (see the src of SMTPTransport and Transport classes). Sockets let you connect to a remote server and that connection remains open until explicitly closed. This means that theoreticaly you could create a connection and them reuse it.

However, many SMTP servers are pretty evil and will kill the connection if you are using it "too slow" or if you try to resuse your SMTP session to often. (I looked up postfix settings for you.)

The Java Mail API allows you to create the connection and close it whenever you want to. Smth. like this:

        Transport transport = session.getTransport("smtp");
        transport.connect();
        transport.sendMessage(msg, addressArray);
        // you can do transport.close(); later

However, because of the fact how the SMTP servers are, you can't just execute connect() once and forget it. At most, what you can do, is properly handle forced disconnects by reconnecting again. There is a notification mechanism in the Java Mail API to do that (take a look at the usage of the notifyConnectionListeners method)

0
DMv2 On

However, because of the fact how the SMTP servers are, you can't just execute connect() once and forget it. At most, what you can do, is properly handle forced disconnects by reconnecting again.

Agreed!

You can in fact reuse the JavaMail SMTP connection with below logic:

Transport transport = null;
MimeMessage message = null;

Properties prop = new Properties();
// load all smtp properties

Session session = Session.getDefaultInstance(prop, null);
transport = session.getTransport("smtp");

for (EachMail eachMail : list) {
    if (!transport.isConnected()) {
        if (port != null && port.length() > 0) {
            transport.connect(host, Integer.parseInt(port), "<username>", "<password>");
        } else {
            transport.connect(host, "<username>", "<password>");
        }
    }

    // set all mail attributes from eachMail object
    message.saveChanges();
    transport.sendMessage(message, message.getAllRecipients());
}

Works like a charm. Cheers!

0
Amichai Ungar On

If you want an always up connection you should create your Transport outside of the sending method, but to avoid excpetions on sending (SMTPSendFailedException 421 Timeout data client) you should check if the transport is connected, and if not to connect it again befor sending:

 if (!transport.isConnected())//make sure the connection is alive
            transport.connect();
 transport.sendMessage(message, message.getAllRecipients());