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

11.2k views Asked by At

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.

5

There are 5 answers

6
skadya On BEST ANSWER

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);
    }
0
Jaivardhan On

Just to add something to @davioooh answer,if anybody is using smtp interface of aws instead of aws sdk api,-- If you are using Port 465,then use protocol as smtps But,If you are using Port 25,587,then you use protocol as smtp It is mandatory.

If you are not using SMTPS while using port 465,then you will get exception in your springboot application.(Because,while using Port 465 client has to initiate the TLS while transferring the mail,so you have to mention SMTPS in your application.properties file.

Similarly,you are not required to use SMTPS while using Port 25,587 because in this case server first responds to the client that it is tls enabled or not,then the client initiates a tls encryption.So,you only have to use SMTP in case of Port 25,587.

6
davioooh On

I used AWS SES in a Spring Boot web project some time ago, but I haven't used Spring Cloud AWS to integrate my application with the mail service.

Instead I simply included spring-boot-starter-mail among the project dependencies (pom.xml):

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
</dependency>

Then I set SMTP server parameters in my application.properties. In my case I used these properties:

spring.mail.host=email-smtp.eu-west-1.amazonaws.com
spring.mail.port=465
spring.mail.protocol=smtps
spring.mail.smtps.auth=true
spring.mail.smtp.ssl.enable=true
spring.mail.username=<my-user>
spring.mail.password=<my-password>

Note: server host and port may vary.

Spring Boot will create a default JavaMailSender instance, configuring it with the previos parametes. You can use this object to send emails...

Probably this in not the best approach to AWS SES integration with a Spring Boot application, but it works fine for me.

1
AlexGera On
  1. Add AWS-Java-sdk to your project
  2. Setup AWS credentials (Keys) on your machine
  3. Create SendEmailRequest
  4. SendEmailRequest#.sendEmail(request)

p.s. You don't need any JavaMail here. You can wrap it to beans in Spring in any desired way.

0
Partha Mondal On

you can do it through Application.properties also. Make Sure that You are not in the sandbox in AWS SES.

  1. Verify your E-mail Adress or Domain for sending Email through SES.Go to SES DashBoard and select "Email Addresses".(For testing, you can Send a Demo email From SES DashBoard--> Email Addresses --> Send a Test email).
  2. Create 'Access Key Id' and 'Secret access key'.(Without this keys You cannot send mail. You will get 535-Error).

3.Now put the keys in your application.properties. As Shown below

`spring.mail.host=email-smtp.us-east-1.amazonaws.com(Your Hosting region)
spring.mail.username=<Access Key Id>
spring.mail.password=<Secret access key>`

If you are using MimeMessage then set the Sending mail ID as given below:

MimeMessageHelper helper = new MimeMessageHelper(message);
helper.setFrom("[email protected]");

Hope It helps.