I've already researched the topic for a few days but none of the answers I found online did the trick for me.
Context: I've got a Spring Boot web application which sends automatic emails notifications using Java Mail API and Spring Boot Starter Mail.
It is using GMail SMTP server with a GSuite account. I recently upgraded to use Spring 5.0.6 and Spring Boot 2.0.2 and the email sending stopped working.
A few clues:
The things that have changed:
Here are the relevant dependencies in pom.xml :
<!-- https://mvnrepository.com/artifact/javax.mail/javax.mail-api -->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>javax.mail-api</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
Here is the application.yml relevant to Spring mail:
spring:
mail:
host: ${FT_MAIL_SMTP_HOST}
port: ${FT_MAIL_SMTP_PORT}
username: ${FT_MAIL_SMTP_USERNAME}
password: ${FT_MAIL_SMTP_PASSWORD}
debug: false
properties:
mail:
smtp:
starttls:
enable: ${FT_MAIL_SMTP_STARTTLS}
required: ${FT_MAIL_SMTP_TLSREQUIRED}
auth: ${FT_MAIL_SMTP_AUTH}
connectiontimeout: ${FT_MAIL_SMTP_CONN_TIMEOUT}
timeout: ${FT_MAIL_SMTP_TIMEOUT}
writetimeout: ${FT_MAIL_SMTP_WRITE_TIMEOUT}
These variables are defined in the environment:
FT_MAIL_SMTP_HOST=smtp.gmail.com
FT_MAIL_SMTP_PORT=587
FT_MAIL_SMTP_USERNAME=myaccount@myapp.com
FT_MAIL_SMTP_PASSWORD=mypassword
FT_MAIL_SMTP_STARTTLS=true
FT_MAIL_SMTP_TLSREQUIRED=true
FT_MAIL_SMTP_AUTH=true
FT_MAIL_SMTP_CONN_TIMEOUT=5000
FT_MAIL_SMTP_TIMEOUT=5000
FT_MAIL_SMTP_WRITE_TIMEOUT=5000
Here is the Spring @Service used to send the email (unchanged):
@Service
public class EmailServiceImpl {
@Autowired
public JavaMailSender emailSender;
@Autowired
private SpringTemplateEngine templateEngine;
@Value("${myapp.mail.from}")
private String fromAddress;
@Value("${myapp.mail.replyto}")
private String replyToAddress;
public void sendTemplatedMessage(String template, String to, String subject, Map<String, Object> model) throws MailException, MessagingException {
sendTemplatedMessage(template, to, fromAddress, replyToAddress, subject, model);
}
public void sendTemplatedMessage(String template, String to, String from, String subject, Map<String, Object> model) throws MailException, MessagingException {
sendTemplatedMessage(template, to, from, replyToAddress, subject, model);
}
private void sendTemplatedMessage(String template, String to, String from, String replyTo, String subject, Map<String, Object> model) throws MailException, MessagingException {
MimeMessage message = emailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message,
MimeMessageHelper.MULTIPART_MODE_MIXED_RELATED,
StandardCharsets.UTF_8.name());
//helper.addAttachment("logo.png", new ClassPathResource("memorynotfound-logo.png"));
Context context = new Context();
context.setVariables(model);
String html = templateEngine.process(template, context);
helper.setTo(to);
helper.setFrom(from);
helper.setReplyTo(from);
helper.setSubject(subject);
helper.setText(html, true);
emailSender.send(message);
}
public void sendSimpleMessage(String to, String from, String subject, String text) {
try {
SimpleMailMessage message = new SimpleMailMessage();
message.setTo(to);
message.setFrom(from);
message.setSubject(subject);
message.setText(text);
emailSender.send(message);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Now here is the error I get when trying to send an email:
04:42:19.900 [https-jsse-nio-443-exec-3] ERROR c.f.controller.StayController - Could not send Guest confirmation email to gfgorostidi@protonmail.com
org.springframework.mail.MailSendException: Failed to close server connection after message sending; nested exception is javax.mail.MessagingException: Exception reading response;
nested exception is:
java.net.SocketTimeoutException: Read timed out
at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:482)
at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:359)
at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:354)
at com.myapp.util.EmailServiceImpl.sendTemplatedMessage(EmailServiceImpl.java:61)
at com.myapp.util.EmailServiceImpl.sendTemplatedMessage(EmailServiceImpl.java:35)
at com.myapp.controller.StayController.sendConfirmEmailToGuest(StayController.java:437)
at com.myapp.controller.StayController.saveStay(StayController.java:383)
at com.myapp.controller.StayController.createStay(StayController.java:163)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
......
......
......
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1135)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:844)
Caused by: javax.mail.MessagingException: Exception reading response;
nested exception is:
java.net.SocketTimeoutException: Read timed out
at com.sun.mail.smtp.SMTPTransport.readServerResponse(SMTPTransport.java:2202)
at com.sun.mail.smtp.SMTPTransport.close(SMTPTransport.java:1212)
at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:473)
... 104 more
Caused by: java.net.SocketTimeoutException: Read timed out
at java.base/java.net.SocketInputStream.socketRead0(Native Method)
at java.base/java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
at java.base/java.net.SocketInputStream.read(SocketInputStream.java:171)
at java.base/java.net.SocketInputStream.read(SocketInputStream.java:141)
at java.base/sun.security.ssl.SSLSocketInputRecord.read(SSLSocketInputRecord.java:425)
at java.base/sun.security.ssl.SSLSocketInputRecord.bytesInCompletePacket(SSLSocketInputRecord.java:65)
at java.base/sun.security.ssl.SSLSocketImpl.bytesInCompletePacket(SSLSocketImpl.java:918)
at java.base/sun.security.ssl.AppInputStream.read(AppInputStream.java:144)
at com.sun.mail.util.TraceInputStream.read(TraceInputStream.java:124)
at java.base/java.io.BufferedInputStream.fill(BufferedInputStream.java:252)
at java.base/java.io.BufferedInputStream.read(BufferedInputStream.java:271)
at com.sun.mail.util.LineInputStream.readLine(LineInputStream.java:89)
at com.sun.mail.smtp.SMTPTransport.readServerResponse(SMTPTransport.java:2182)
... 106 more
org.springframework.mail.MailSendException: Failed to close server connection after message sending; nested exception is javax.mail.MessagingException: Exception reading response;
nested exception is:
java.net.SocketTimeoutException: Read timed out
at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:482)
at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:359)
at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:354)
at com.myapp.util.EmailServiceImpl.sendTemplatedMessage(EmailServiceImpl.java:61)
at com.myapp.util.EmailServiceImpl.sendTemplatedMessage(EmailServiceImpl.java:35)
at com.myapp.controller.StayController.sendConfirmEmailToGuest(StayController.java:437)
at com.myapp.controller.StayController.saveStay(StayController.java:383)
at com.myapp.controller.StayController.createStay(StayController.java:163)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
......
......
......
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1468)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1135)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:844)
Caused by: javax.mail.MessagingException: Exception reading response;
nested exception is:
java.net.SocketTimeoutException: Read timed out
at com.sun.mail.smtp.SMTPTransport.readServerResponse(SMTPTransport.java:2202)
at com.sun.mail.smtp.SMTPTransport.close(SMTPTransport.java:1212)
at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:473)
... 104 more
Caused by: java.net.SocketTimeoutException: Read timed out
at java.base/java.net.SocketInputStream.socketRead0(Native Method)
at java.base/java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
at java.base/java.net.SocketInputStream.read(SocketInputStream.java:171)
at java.base/java.net.SocketInputStream.read(SocketInputStream.java:141)
at java.base/sun.security.ssl.SSLSocketInputRecord.read(SSLSocketInputRecord.java:425)
at java.base/sun.security.ssl.SSLSocketInputRecord.bytesInCompletePacket(SSLSocketInputRecord.java:65)
at java.base/sun.security.ssl.SSLSocketImpl.bytesInCompletePacket(SSLSocketImpl.java:918)
at java.base/sun.security.ssl.AppInputStream.read(AppInputStream.java:144)
at com.sun.mail.util.TraceInputStream.read(TraceInputStream.java:124)
at java.base/java.io.BufferedInputStream.fill(BufferedInputStream.java:252)
at java.base/java.io.BufferedInputStream.read(BufferedInputStream.java:271)
at com.sun.mail.util.LineInputStream.readLine(LineInputStream.java:89)
at com.sun.mail.smtp.SMTPTransport.readServerResponse(SMTPTransport.java:2182)
... 106 more
I have tried setting an incorrect SMTP server or bad credentials and this made the connection fail, so I assumed the server and credentials are correct as they are, and the error happens after a successful connection.
The account used hasn't reached its limit, as another VM uses the same credentials and sends emails without problem.
I've tried changing "Start TLS" settings to false and use port 465 instead, but this isn't working either.
Any help is appreciated !! Thanks in advance!
After much more trial and error with the configuration, I found out that it required an application property "spring.mail.protocol" in the configuration.
I've added the line protocol: smtp
in application.yml:
spring:
mail:
protocol: smtp
And that fixed the read timeout issue, email are now sent properly. Hope that may help someone in the future.
I did face the same issue, but my scenario was a bit different
I was trying to send in a schedule manner using quartz
When I did not use Quartz, it was all working fine, but with quartz it started failing
The above solution did not help me, but pointed me in direction of looking at the properties that I had set.
Increasing the connection timeout did the job for me
Thus changed the application properties
from:
spring.mail.properties.mail.smtp.timeout=3000
to:
spring.mail.properties.mail.smtp.timeout=25000
Hope it works for others as well
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.