Skip to Main Content

Java EE (Java Enterprise Edition) General Discussion

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

SMTP, TLS, Gmail, and Port 465 vs. Port 587

843830Feb 8 2006 — edited Jun 14 2007
I've been testing some code for sending secure e-mail, and I've been using my Gmail account for testing. I've done a lot of googling on the subject of Java and secure SMTP access, and found a lot of specific example regarding Gmail in particular.

I've got code that works now, but I'm a bit puzzled. In order to make my code work, I MUST use port 465. I cannot get the code to work if I try to access Gmail using port 587, even though that's the recommended port and the one that I've always used to configure an e-mail client like Mac OS X Mail or Mozilla.

In the googling I've done, I've seen stories of success and failure, and I've seen examples with both ports used. The successful code seems to be using port 465, but I've never heard the particular port used mentioned as an important ingredient for success. In fact, to the minimal degree I've heard the port discussed at all, it's been to say "use either one, it doesn't matter."

This leaves me feeling that there's something missing in my code -- I'd think that if everything were in order, port 587 would also work for me. Further, while port 465 does work, in the debug trace I see "isSSL false", even though I'm specifying an SSL socket factory and am pretty sure that SSL is being used.

Here's a portion of the debug log where I fail using port 587:
...
DEBUG SMTP: useEhlo true, useAuth true
DEBUG SMTP: useEhlo true, useAuth true
DEBUG SMTP: trying to connect to host "smtp.gmail.com", port 587, isSSL false
DEBUG SMTP: exception reading response: javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?
What's all this about a "plaintext connection"? Why does it say, both here and below when my connection succeeded "isSSL false"? I experimented with the SMTPSSLTransport class, which gave me the more comforting "isSSL true", but my results didn't change one bit.

Here's a portion of the debug log where I succeed using port 465:
...
DEBUG SMTP: useEhlo true, useAuth true
DEBUG SMTP: useEhlo true, useAuth true
DEBUG SMTP: trying to connect to host "smtp.gmail.com", port 465, isSSL false
220 mx.gmail.com ESMTP i15sm7669285wxd
DEBUG SMTP: connected to host "smtp.gmail.com", port: 465

EHLO myaccount
250-mx.gmail.com at your service
250-SIZE 20971520
250-8BITMIME
250-AUTH LOGIN PLAIN
250 ENHANCEDSTATUSCODES
...
And for any light it might shed on the situation, here's an edited-down version of my code:
  public String sendMessage(Vector<String> recipients, String subject, String messageText)
  {
    String    error = null;

    if (subject == null)
      subject = "(no subject)";

    if (messageText == null)
      messageText = "";

    try {
      Properties  props  = new Properties();
      String      from   = settingsManager.getSetting(CONFIG_SMTP_FROM); // any ol' e-mail address
      String      host   = settingsManager.getSetting(CONFIG_SMTP_HOST); // smtp.gmail.com
      String      port   = settingsManager.getSetting(CONFIG_SMTP_PORT); // 465 or 587
      String      auth   = settingsManager.getSetting(CONFIG_SMTP_AUTH); // "tls"
      boolean     doAuth = !"none".equals(auth);
      boolean     useTLS = "tls".equals(auth);
      Session     session;

      props.put("mail.from",               from);
      props.put("mail.smtp.host", host);
      props.put("mail.smtp.port",          port);
      props.put("mail.transport.protocol", "smtp");
//props.put("mail.debug", "true");

      if (useTLS) {
        props.put("mail.smtp.socketFactory.port",     port);
        props.put("mail.smtp.socketFactory.class",    "javax.net.ssl.SSLSocketFactory");
        props.put("mail.smtp.socketFactory.fallback", "false");
        props.put("mail.smtp.starttls.enable",        "true");
        props.put("mail.smtp.ssl",                    "true");
      }

      if (doAuth) {
        String          username = settingsManager.getSetting(CONFIG_SMTP_USER);
        String          password = getEncryptedPassword();
        Authenticator   authenticator = new MyAuthenticator(username, password);

        props.put("mail.user",      username);
        props.put("mail.smtp.auth", "true");

        session = Session.getInstance(props, authenticator);
      }
      else
        session = Session.getInstance(props);

      MimeMessage   message = new MimeMessage(session);

      for (String addressee : recipients)
        message.addRecipient(Message.RecipientType.TO, new InternetAddress(addressee));

      message.setFrom(new InternetAddress(from));
      message.setText(messageText);
      message.setSubject(subject);
      Transport.send(message);
    }
    catch (SendFailedException e) {
      error = exceptionToErrorMessage(e);
    }
    catch (NoSuchProviderException e) {
      error = exceptionToErrorMessage(e);
    }
    catch (AddressException e) {
      error = exceptionToErrorMessage(e);
    }
    catch (MessagingException e) {
      error = exceptionToErrorMessage(e);
    }

    return error;
  }

  ...

  private class MyAuthenticator extends Authenticator
  {
    private String    username;
    private String    password;

    public MyAuthenticator(String username, String password)
    {
      this.username = username;
      this.password = password;
    }

    public PasswordAuthentication getPasswordAuthentication()
    {
      return new PasswordAuthentication(username, password);
    }
  }
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Jul 12 2007
Added on Feb 8 2006
4 comments
3,837 views