I use .springframework.mail.javamail.JavaMailSender to send emails via smtp.office365. It works most of the time but sometimes emails are not send because of connectivity issue. smtp.office365 has limit of 30 messages per minute. On average during the day time my service sends one email per 5 minutes, every time to exact same receivers. So I don't think that I am exceeding the limit. Nonetheless I get the following error from time to time, like once about every 10 minutes:
.springframework.mail.MailSendException: Mail server connection failed; nested exception is com.sun.mail.util.MailConnectException: Couldn't connect to host, port: smtp.office365, 587; timeout -1;
Unfortunately the debug does not provide more details. For example I would like to see to what IP address is it is trying to connect but it doesn't show me.
I am not sure the problem is but it seems like smtp.office365 doesn't like something. May be I have too much connections. May be the JavaMailSender is buggy. Or may be smtp.office365 is a very bad service. Or may be my code is buggy?
I use the following configuration in the application.yaml
.
spring:
mail:
host: smtp.office365
port: 587
username: [email protected]
password: password
protocol: smtp
properties:
mail.smtp.auth: true
mail.smtp.starttls.enable: true
And the following "service" which is actually not annotated as service, SimpleEmailService.java
, a little bit simplified;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import .springframework.beans.factory.annotation.Value;
import .springframework.mail.javamail.JavaMailSender;
import .springframework.mail.javamail.MimeMessageHelper;
import .springframework.mail.javamail.MimeMessagePreparator;
import .springframework.scheduling.annotation.Async;
import .springframework.stereotype.Component;
@Component
@RequiredArgsConstructor
public class SimpleEmailService {
private final JavaMailSender emailSender;
@Async
@SneakyThrows
public void sendTemplatedMessage(EmailHtmlNotification emailNotification) {
MimeMessagePreparator messagePreparator = mimeMessage -> {
MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage);
messageHelper.setTo(emailNotification.getToEmails().toArray(new String[]{}));
messageHelper.setFrom("[email protected]");
messageHelper.setSubject(emailNotification.getSubject());
String messageContent = getMessageFromTemplate(emailNotification.getEmailTemplates(), emailNotification.getBodyParameters());
messageHelper.setText(messageContent, true);
};
emailSender.send(messagePreparator);
}
}
To sum up, it sends emails most of the time but some of the time it has timeouts and thus some of the emails are not delivered to the SMTP.
I am not sure what is wrong but what could be wrong, any ideas?
I use .springframework.mail.javamail.JavaMailSender to send emails via smtp.office365. It works most of the time but sometimes emails are not send because of connectivity issue. smtp.office365 has limit of 30 messages per minute. On average during the day time my service sends one email per 5 minutes, every time to exact same receivers. So I don't think that I am exceeding the limit. Nonetheless I get the following error from time to time, like once about every 10 minutes:
.springframework.mail.MailSendException: Mail server connection failed; nested exception is com.sun.mail.util.MailConnectException: Couldn't connect to host, port: smtp.office365, 587; timeout -1;
Unfortunately the debug does not provide more details. For example I would like to see to what IP address is it is trying to connect but it doesn't show me.
I am not sure the problem is but it seems like smtp.office365 doesn't like something. May be I have too much connections. May be the JavaMailSender is buggy. Or may be smtp.office365 is a very bad service. Or may be my code is buggy?
I use the following configuration in the application.yaml
.
spring:
mail:
host: smtp.office365
port: 587
username: [email protected]
password: password
protocol: smtp
properties:
mail.smtp.auth: true
mail.smtp.starttls.enable: true
And the following "service" which is actually not annotated as service, SimpleEmailService.java
, a little bit simplified;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import .springframework.beans.factory.annotation.Value;
import .springframework.mail.javamail.JavaMailSender;
import .springframework.mail.javamail.MimeMessageHelper;
import .springframework.mail.javamail.MimeMessagePreparator;
import .springframework.scheduling.annotation.Async;
import .springframework.stereotype.Component;
@Component
@RequiredArgsConstructor
public class SimpleEmailService {
private final JavaMailSender emailSender;
@Async
@SneakyThrows
public void sendTemplatedMessage(EmailHtmlNotification emailNotification) {
MimeMessagePreparator messagePreparator = mimeMessage -> {
MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage);
messageHelper.setTo(emailNotification.getToEmails().toArray(new String[]{}));
messageHelper.setFrom("[email protected]");
messageHelper.setSubject(emailNotification.getSubject());
String messageContent = getMessageFromTemplate(emailNotification.getEmailTemplates(), emailNotification.getBodyParameters());
messageHelper.setText(messageContent, true);
};
emailSender.send(messagePreparator);
}
}
To sum up, it sends emails most of the time but some of the time it has timeouts and thus some of the emails are not delivered to the SMTP.
I am not sure what is wrong but what could be wrong, any ideas?
Share Improve this question edited Mar 13 at 9:56 ilhan asked Mar 13 at 8:22 ilhanilhan 9,01335 gold badges127 silver badges214 bronze badges 4- 2 sometimes, networks just fail. capturing that this happened and retrying seems the most sensible choice. – TZHX Commented Mar 13 at 8:40
- @TZHX, it fails too much. The service runs on Azure and smtp.office365 belongs to Microsoft. It fails too much, way more than cheap shared hosting. Thus I thought that may be my service creates too much connections for some reason and doesn't close them. – ilhan Commented Mar 13 at 8:45
- Show me import statements at the top. Do you use Spring mail docs.spring.io/spring-boot/reference/io/email.html . Let's tell me result of these efforts. – Vy Do Commented Mar 13 at 9:53
- @VyDo, I've updated the question with the relevant imports. – ilhan Commented Mar 13 at 9:56
1 Answer
Reset to default 1(1) Async
@Async("emailExecutor")
public void sendTemplatedMessage(EmailHtmlNotification emailNotification) {
synchronized (this) {
emailSender.send(messagePreparator);
}
}
(2) You need limit number of concurrent connection (reuse existing exiting connection)
spring:
mail:
properties:
mail.smtp.connectionpool: true
(3) You should print log in the program for troubleshooting.