JavaMail smtp properties (for STARTTLS)
Asked Answered
B

5

28

JavaMail specifies a bunch of properties that can be set to configure an SMTP connection. To use STARTTLS it is necessary to set the following property

mail.smtp.starttls.enable=true

Where do I specify the username/password to use the smtp service? Is it enough to specify the:

mail.smtp.user=me
mail.smtp.password=secret

Or do I have to explicitely login using the:

transport.connect(server, userName, password)

Yes, I already tried to do this and it seems that it is necessary to connect using transport.connect(..). But if yes, what are the mail.smtp.user & pass properties for? Are they not enough to use smtp with starttls?

Bligh answered 8/4, 2011 at 7:52 Comment(1)
You may also want to set mail.smtp.starttls.required=true.Pastille
R
31

Here is my sendEmail method which is using GMail smtp (JavaMail) with STARTTLS

public void sendEmail(String body, String subject, String recipient) throws MessagingException,
            UnsupportedEncodingException {
        Properties mailProps = new Properties();
        mailProps.put("mail.smtp.from", from);
        mailProps.put("mail.smtp.host", smtpHost);
        mailProps.put("mail.smtp.port", port);
        mailProps.put("mail.smtp.auth", true);
        mailProps.put("mail.smtp.socketFactory.port", port);
        mailProps.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        mailProps.put("mail.smtp.socketFactory.fallback", "false");
        mailProps.put("mail.smtp.starttls.enable", "true");

        Session mailSession = Session.getDefaultInstance(mailProps, new Authenticator() {

            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(login, password);
            }

        });

        MimeMessage message = new MimeMessage(mailSession);
        message.setFrom(new InternetAddress(from));
        String[] emails = { recipient };
        InternetAddress dests[] = new InternetAddress[emails.length];
        for (int i = 0; i < emails.length; i++) {
            dests[i] = new InternetAddress(emails[i].trim().toLowerCase());
        }
        message.setRecipients(Message.RecipientType.TO, dests);
        message.setSubject(subject, "UTF-8");
        Multipart mp = new MimeMultipart();
        MimeBodyPart mbp = new MimeBodyPart();
        mbp.setContent(body, "text/html;charset=utf-8");
        mp.addBodyPart(mbp);
        message.setContent(mp);
        message.setSentDate(new java.util.Date());

        Transport.send(message);
    }
Rauch answered 8/4, 2011 at 9:5 Comment(4)
Hi. Where do you put in the actual username and password?Gymnosophist
In getPasswordAuthentication() method of Authenticator classRauch
Hm, when i set "...socketFactory.class" it seems to use SSL over SMTP instead of StartTLS and i get a "Unrecognized SSL message, plaintext connection?" exception.Rokach
The JavaMail FAQ suggests that setting socketFactory properties hasn't been necessary for many years and should be avoided: javaee.github.io/javamail/FAQ#commonmistakesSedulous
U
5

You have to subclass Authenticator and create a PasswordAuthentication object for Session along with env properties to login

Session session = Session.getDefaultInstance(props, new javax.mail.Authenticator() {

    protected PasswordAuthentication getPasswordAuthentication() {
      return new PasswordAuthentication("user-name", "user-password");
    }
  });

user-name sometimes is full email id for some servers like gmail. Hope this helps.

Underbelly answered 8/4, 2011 at 8:12 Comment(0)
P
5

You can specify the user as

[email protected]

(or mail.smtp.user if you don't use mail.transport.protocol=smtps) in the properties that you use for the session.

AFAIK, you can't supply the password. But you can certainly put it in the props and retrieve it yourself. Or get it in some other way, e.g. by prompting the user.

When you have it, there are two ways of supplying it to the session. The simpler one is to use

Transport tr = session.getTransport();
tr.connect(null, password);
tr.sendMessage(message, message.getRecipients());

Or, as pointed out, you can use an authenticator. But then the user from the props is ignored, and you have to explicitly pass it to PasswordAuthentication. If you do, then your reward is that you can use the static Transport.send.

Parishioner answered 6/6, 2012 at 0:24 Comment(0)
T
4

You have to provide an authenticator when you create the session

Authenticator authenticator = new PasswordAuthentication("username", "password");
Session session = Session.getInstance(properties, authenticator);

then you use the session to send your message (skipping the try/catch, for brevity):

SMTPTransport tr = (SMTPTransport) session.getTransport("smtps");
tr.connect();
tr.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
Titration answered 31/5, 2013 at 6:34 Comment(1)
As stated by the JavaMail FAQ, using the Authenticator is optional and usually messy.Dabber
B
1

Using Simple Java Mail it should be straightforward:

Email email = new Email();

email.setFromAddress("lollypop", "[email protected]");
email.addRecipient("C.Cane", "[email protected]", RecipientType.TO);
email.setText("We should meet up!");
email.setTextHTML("<b>We should meet up!</b>");
email.setSubject("hey");

new Mailer("smtp.gmail.com", 25, "your user", "your password", TransportStrategy.SMTP_TLS).sendMail(email);
new Mailer("smtp.gmail.com", 587, "your user", "your password", TransportStrategy.SMTP_TLS).sendMail(email);
new Mailer("smtp.gmail.com", 465, "your user", "your password", TransportStrategy.SMTP_SSL).sendMail(email);

If you have two-factor login turned on, you need to generate an application specific password from your Google account.


If you still want to do this yourself, the code behind this library is very simple. It sets specific properties on the Session depending on which TransportStrategy was passed (plain, ssl or tls) and it uses an Authenticator to perform the authentication:

"mail.transport.protocol" : "smtp"
"mail.smtp.starttls.enable" : "true"
"mail.smtp.host" : host
"mail.smtp.port" : port
"mail.smtp.username" : username
"mail.smtp.auth" : "true"

And

return Session.getInstance(props, new Authenticator() {
   @Override
   protected PasswordAuthentication getPasswordAuthentication() {
      return new PasswordAuthentication(username, password);
   }
});
Benempt answered 19/5, 2016 at 11:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.