Secure Email with Spring’s JavaMailServer and Gmail

Alex Cruikshank ·

Both Carbon Five and my ISP have moved email management over to Gmail.  While this has been a net improvement for me as an end user, it’s made it a bit more difficult to configure my applications to send outgoing mail.  It isn’t hard to find examples online that explain how to configure Spring’s JavaMailSender to work with Gmail.  But none of the examples I’ve found provide a configuration that can be switched between Gmail and an open SMTP server with a few reasonable external properties (an important feature in an application that needs to be deployed in varied environments).  What’s worse, the configurations tend to differ with no rational provided for the necessary parameters.  So I spent some time with the source and a debugger and came up with a simplified solution:

<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
  <property name="defaultEncoding" value="UTF-8"/>
  <property name="host" value="${mail.host}"/>
  <property name="port" value="${mail.port}"/>
  <property name="protocol" value="${mail.protocol}"/>
  <property name="username" value="${mail.username}"/>
  <property name="password" value="${mail.password}"/>
  <property name="javaMailProperties">
    <props>
      <prop key="mail.debug">${mail.debug}</prop>
      <prop key="mail.${mail.protocol}.auth">${mail.smtp-auth}</prop>
    </props>
  </property>
</bean>

The properties for an open server look something like this:

mail.host       = localhost
mail.port       = 25
mail.protocol   = smtp
mail.smtp-auth  = false
mail.username   =
mail.password   =
mail.debug      = false

And the properties for gmail look something like this:

mail.host       = smtp.gmail.com
mail.port       = 465
mail.protocol   = smtps
mail.smtp-auth  = true
mail.username   = my.email@address.com
mail.password   = mypassword
mail.debug      = true

The host, port, username, password and debug properties should be obvious.  The key is to change the protocol between ‘smtp’ and ‘smpts’.  The only real difference between smtp and smtps is that the later causes JavaMail’s SMTPTransport object to open an SSL socket to the server.  Gmail only accepts SSL connections on port 465.  After figuring this out, I was glad to see that Gmail was accepting my connections, but immediately frustrated to find that JavaMail was no longer attempting to authenticate before sending mail.  The trick is that JavaMail checks its transport related parameters under ‘mail.[protocol].[parameter]’.  This appears to be an entirely undocumented feature of JavaMail.  Fortunately, we can substitute the protocol name into the parameter key as well, so our auth parameter still works with either ‘smtp’ or ‘smtps’.

Alex Cruikshank
Alex Cruikshank

Alex is Carbon Five's resident mad genius. He is recently very involved in functional languages, and has been anchoring teams at C5 for the past decade.