33

I'm trying to use javamail in a groovy script to send out an email via gmail. I've looked many places online and have been unable to get it working thus far. The error I'm getting when running my script is:

DEBUG SMTP: useEhlo true, useAuth false
DEBUG SMTP: trying to connect to host "smtp.gmail.com", port 25, isSSL false
Caught: javax.mail.SendFailedException: Send failure (javax.mail.MessagingException: Could not connect to SMTP host: smtp.gmail.com, port: 25 (javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?))

It appears to be trying to use port 25 even though I've specified that it should use port 587. Does anyone know what could be causing this problem, I've used telnet to connect to the smtp server on port 587, and thunderbird uses port 587 with STARTTLS security and is able to successfully send mail using the smtp server. This tells me that it is not a blocked port or connectivity issue. Here is the code I'm using to try and send the email:

import javax.mail.*
import javax.mail.internet.*

private class SMTPAuthenticator extends Authenticator
{
    public PasswordAuthentication getPasswordAuthentication()
    {
        return new PasswordAuthentication('email@gmail.com', 'password');
    }
}

def  d_email = "email@gmail.com",
        d_password = "password",
        d_host = "smtp.gmail.com",
        d_port  = "587", //465,587
        m_to = "email@gmail.com",
        m_subject = "Testing",
        m_text = "This is a test."

def props = new Properties()
props.put("mail.smtp.user", d_email)
props.put("mail.smtp.host", d_host)
props.put("mail.smtp.port", d_port)
props.put("mail.smtp.starttls.enable","true")
props.put("mail.smtp.debug", "true");
props.put("mail.smtp.auth", "true")
props.put("mail.smtp.socketFactory.port", d_port)
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory")
props.put("mail.smtp.socketFactory.fallback", "false")

def auth = new SMTPAuthenticator()
def session = Session.getInstance(props, auth)
session.setDebug(true);

def msg = new MimeMessage(session)
msg.setText(m_text)
msg.setSubject(m_subject)
msg.setFrom(new InternetAddress(d_email))
msg.addRecipient(Message.RecipientType.TO, new InternetAddress(m_to))
Transport.send(msg)

Any help would be greatly appreciated. Thanks in advance!

-Bryan

Bryan
  • 1,431
  • 1
  • 14
  • 19

3 Answers3

34

In Java you would do something similar to:

Transport transport = session.getTransport("smtps");
transport.connect (smtp_host, smtp_port, smtp_username, smtp_password);
transport.sendMessage(msg, msg.getAllRecipients());
transport.close();    

Note 'smtpS' protocol. Also socketFactory properties is no longer necessary in modern JVMs but you might need to set 'mail.smtps.auth' and 'mail.smtps.starttls.enable' to 'true' for Gmail. 'mail.smtps.debug' could be helpful too.

maximdim
  • 8,041
  • 3
  • 33
  • 48
  • 4
    Thank you that worked! Note that the second parameter to connect() in an int, also I had to switch the port number to be 465 because it is the SSL port, while 587 is for TLS. Thanks again! – Bryan Jan 02 '10 at 05:09
  • Glad it worked. I think you can drop mail.smtp.socketFactory.* properties as well. – maximdim Jan 02 '10 at 17:33
  • Nice to find this! Sendgrid has a java example [here](http://sendgrid.com/docs/Code_Examples/java.html) that uses Properties, and works fine if you can use port 25, but if you have to switch, it fails. My ISP blocks port 25, so that code was working from my office, but not home, and I could not figure out why my selected port was being ignored. – Alper Akture Jun 01 '13 at 23:04
  • 1
    Thanks, that worked on port 587 on android but with "smtp" instead of "smtps". The static Transport.send() works too, but only if an authenticator callback is used in Session.getInstance(). – Tilman Hausherr Jul 02 '13 at 10:11
  • Thank´s a lot your post help me so much. – Julio enrique godoy muñoz Dec 27 '19 at 21:36
18

For anyone looking for a full solution, I got this working with the following code based on maximdim's answer:

import javax.mail.*
import javax.mail.internet.*

private class SMTPAuthenticator extends Authenticator
{
    public PasswordAuthentication getPasswordAuthentication()
    {
        return new PasswordAuthentication('email@gmail.com', 'test1234');
    }
}

def  d_email = "email@gmail.com",
        d_uname = "email",
        d_password = "password",
        d_host = "smtp.gmail.com",
        d_port  = "465", //465,587
        m_to = "testepscript@gmail.com",
        m_subject = "Testing",
        m_text = "Hey, this is the testing email."

def props = new Properties()
props.put("mail.smtp.user", d_email)
props.put("mail.smtp.host", d_host)
props.put("mail.smtp.port", d_port)
props.put("mail.smtp.starttls.enable","true")
props.put("mail.smtp.debug", "true");
props.put("mail.smtp.auth", "true")
props.put("mail.smtp.socketFactory.port", d_port)
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory")
props.put("mail.smtp.socketFactory.fallback", "false")

def auth = new SMTPAuthenticator()
def session = Session.getInstance(props, auth)
session.setDebug(true);

def msg = new MimeMessage(session)
msg.setText(m_text)
msg.setSubject(m_subject)
msg.setFrom(new InternetAddress(d_email))
msg.addRecipient(Message.RecipientType.TO, new InternetAddress(m_to))

Transport transport = session.getTransport("smtps");
transport.connect(d_host, 465, d_uname, d_password);
transport.sendMessage(msg, msg.getAllRecipients());
transport.close();
Bryan
  • 1,431
  • 1
  • 14
  • 19
  • One of the few example codes out there that worked for me, thanks! – Cookie Dec 09 '11 at 19:54
  • can ayone please look up to my question similar to this?http://stackoverflow.com/questions/14209284/could-not-connect-to-smtp-host-localhost-port-25 – BhavikKama Jan 09 '13 at 12:27
6

Maybe useful for anyone else running into this issue: When setting the port on the properties:

props.put("mail.smtp.port", smtpPort);

..make sure to use a string object. Using a numeric (ie Long) object will cause this statement to seemingly have no effect.

uncrase
  • 644
  • 1
  • 8
  • 16