One of my customers is using Gmail for business (part of Google Apps) and I had to reconfigure the website I've developed so it would match the new credentials. After a bit of struggle due to TLS errors, I've managed to make the code work on localhost and on my test server (both Apache Tomcat 5.5). Everything was going smooth until I had to move it on his server (another Tomcat 5.5 as the hosting company told me). On the client's server I get the following error:
javax.mail.SendFailedException: Sending failed;
nested exception is:
class javax.mail.MessagingException: Could not connect to SMTP host: smtp.gmail.com, port: 465;
nested exception is:
java.io.IOException: Couldn't connect using "javax.net.ssl.SSLSocketFactory" socket factory to host, port: smtp.gmail.com, 465; Exception: java.lang.reflect.InvocationTargetException
The strange thing is that on localhost and the test server the port 465 works fine, and the guys from hosting said that port is opened on their server.
The code that connects to the mailserver is:
private void initConfigParams() throws CMSGeneralException {
try {
props = System.getProperties();
String smtpHost = Messages.getDBConfString("mail.smtp.host");
String mailPort = Messages.getDBConfString("mail.smtp.port");
String socketFallback = Messages.getDBConfString("mail.smtp.socketFactory.fallback");
String enableTls = Messages.getDBConfString("mail.smtp.starttls.enable");
String authSmtp = Messages.getDBConfString("mail.smtp.auth");
String tlsRequired = Messages.getDBConfString("mail.smtp.stattls.required");
String sktFactory = Messages.getDBConfString("mail.smtp.socketFactory.class");
props.put("mail.smtp.starttls.enable", enableTls);
props.put("mail.smtp.host", smtpHost);
props.put("mail.smtp.auth", authSmtp);
props.put("mail.smtp.starttls.required", tlsRequired);
props.setProperty("mail.smtp.socketFactory.class", sktFactory);
props.setProperty("mail.smtp.socketFactory.fallback", socketFallback);
props.setProperty("mail.smtp.port", mailPort);
props.setProperty("mail.smtp.socketFactory.port", mailPort);
props.put("mail.transport.protocol", Messages.getDBConfString("mail.transport.protocol"));
Authenticator auth = null;
userName = Messages.getDBConfString("mail.username");
userPassword = Messages.getDBConfString("mail.userpassword");
if (!CMSUtils.isEmptyString(userName) && !CMSUtils.isEmptyString(userPassword)){
/* props.put("mail.smtp.auth", "true"); */
auth = new SMTPAuthenticator(userName, userPassword);
}
session = Session.getDefaultInstance(props, auth);
session.setDebug(false);
address = new InternetAddress[1];
address[0] = new InternetAddress(recipients);
mbText = new MimeBodyPart();
mbText.setContent(text, "text/html");
mp = new MimeMultipart();
mp.addBodyPart(mbText);
} catch (MessagingException e) {
e.printStackTrace();
throw new CMSGeneralException();
}
}
With the following .properties file
mail.smtp.starttls.enable=true
mail.smtp.host=smtp.gmail.com
mail.smtp.auth=true
mail.smtp.starttls.required=true
mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory
mail.smtp.socketFactory.fallback=false
mail.smtp.port=465
mail.transport.protocol=smtps
[email protected]
mail.userpassword=password
[email protected]
[email protected]
I tried the other ports for GMail, 587, but it doesn't work on any of the servers. Not even port 25 won't do the trick.
So, what am I doing wrong, and what should I do to make the mailing work?
Get rid of all the socket factory properties; if you're using a reasonably recent version of JavaMail you don't need them. See the JavaMail FAQ for how to configure JavaMail to access Gmail. You'll also find debugging tips there if it still doesn't work.
Also, change Session.getDefaultInstance to Session.getInstance.
And finally, if you're setting "mail.transport.protocol" to "smtps", you need to set the other properties as "mail.smtps." properties, not "mail.smtp." properties.