Search code examples
spring-bootamazon-sesaws-java-sdkspring-cloud-aws

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


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.


Solution

  • 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);
        }