What is the required configuration steps to have a Spring Boot application send simple e-mails via AWS SES?

deinspanjer picture deinspanjer · Sep 15, 2017 · Viewed 8k times · Source

I have been fighting with this for several hours today. I started with the documentation at http://cloud.spring.io/spring-cloud-aws/spring-cloud-aws.html#_sending_mails which doesn't really say a lot about the specific steps. It just says that the developer can include a Bean XML and then autowire MailSender. I have tried that as well as many variants and have not been able to get it to work using spring-cloud-aws. I finally resorted to directly including aws-java-sdk-ses and manually configuring the class.

Here is a simple project demonstrating what I've tried: https://github.com/deinspanjer/aws-ses-test

This project compiles, but when I run it I get:

Parameter 0 of constructor in com.example.awssestest.AwsSesTestApplication required a bean of type 'org.springframework.mail.MailSender' that could not be found.
- Bean method 'mailSender' not loaded because @ConditionalOnClass did not find required class 'javax.mail.internet.MimeMessage'
- Bean method 'simpleMailSender' not loaded because @ConditionalOnClass did not find required class 'com.amazonaws.services.simpleemail.AmazonSimpleEmailService'
- Bean method 'javaMailSender' not loaded because @ConditionalOnClass did not find required class 'com.amazonaws.services.simpleemail.AmazonSimpleEmailService'

If I try adding javax-mail ( https://github.com/deinspanjer/aws-ses-test/tree/try-with-javax-mail-api ) then the error changes to:

Parameter 0 of constructor in com.example.awssestest.AwsSesTestApplication required a bean of type 'org.springframework.mail.MailSender' that could not be found.
- Bean method 'mailSender' not loaded because AnyNestedCondition 0 matched 2 did not; NestedCondition on MailSenderAutoConfiguration.MailSenderCondition.JndiNameProperty @ConditionalOnProperty (spring.mail.jndi-name) did not find property 'jndi-name'; NestedCondition on MailSenderAutoConfiguration.MailSenderCondition.HostProperty @ConditionalOnProperty (spring.mail.host) did not find property 'host'
- Bean method 'simpleMailSender' not loaded because @ConditionalOnClass did not find required class 'com.amazonaws.services.simpleemail.AmazonSimpleEmailService'
- Bean method 'javaMailSender' not loaded because @ConditionalOnClass did not find required class 'com.amazonaws.services.simpleemail.AmazonSimpleEmailService'

If instead, I try explicitly adding a dependency on aws-java-sdk-ses ( https://github.com/deinspanjer/aws-ses-test/tree/try-with-aws-java-sdk-ses ), I get this error instead:

Parameter 0 of constructor in com.example.awssestest.AwsSesTestApplication required a bean of type 'org.springframework.mail.MailSender' that could not be found.
- Bean method 'mailSender' not loaded because @ConditionalOnClass did not find required class 'javax.mail.internet.MimeMessage'
- Bean method 'javaMailSender' in 'MailSenderAutoConfiguration' not loaded because @ConditionalOnClass did not find required class 'javax.mail.Session'
- Bean method 'simpleMailSender' in 'MailSenderAutoConfiguration' not loaded because @ConditionalOnMissingClass found unwanted class 'org.springframework.cloud.aws.mail.simplemail.SimpleEmailServiceJavaMailSender'

For this error, I tried adding a @Qualifier("simpleMailSender") annotation to the @Autowired, but it did not help.

I hope someone might be able to steer me in the right direction.

Answer

skadya picture skadya · Sep 27, 2017

You may try below steps to fix your issue. I tried these changes in the forked repo from you and it works for me.

  1. Add dependency "com.amazonaws:aws-java-sdk-ses" in pom.xml file.
  2. Create an auto configuration class to configure the mail sender bean. Below is example. The AWSCredentialsProvider is configured and provided by spring-cloud-starter-aws out-of-the-box.

.

@Configuration
public class SimpleMailAutoConfig {

    @Bean
    public AmazonSimpleEmailService amazonSimpleEmailService(AWSCredentialsProvider credentialsProvider) {
        return AmazonSimpleEmailServiceClientBuilder.standard()
                .withCredentials(credentialsProvider)
                // Replace US_WEST_2 with the AWS Region you're using for
                // Amazon SES.
                .withRegion(Regions.US_WEST_2).build();
    }

    @Bean
    public MailSender mailSender(AmazonSimpleEmailService ses) {
        return new SimpleEmailServiceMailSender(ses);
    }
}

3. Use spring API to send mail using the configured mail sender.

Hope it helps.

Edit:

If you need to use JavaMailSender instead of MailSender (for instance when you want to send attachments), simply configure SimpleEmailServiceJavaMailSender instead of SimpleEmailServiceMailSender.

Like this:

    @Bean
    public JavaMailSender mailSender(AmazonSimpleEmailService ses) {
        return new SimpleEmailServiceJavaMailSender(ses);
    }