前言
本次的问题在使用java语言进行邮件发送的时候无法发送邮件。
原本的邮箱发送代码是支持且正常的,但是当把邮箱服务器改为微软云邮箱服务器(我这是微软云,可能其他的云也有)后,便爆出无法发送的bug,
一、问题展示
报错信息:
org.springframework.mail.MailSendException: Mail server connection failed; nested exception is javax.mail.MessagingException: Can't send command to SMTP host;
nested exception is:
javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate). Failed messages: javax.mail.MessagingException: Can't send command toSMTP host;
nested exception is:
javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:448)
at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:361)
at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:356)
at com.fit2cloud.operation.service.SendMailService.sendAttachmentsMailOnly(SendMailService.java:72)
at com.fit2cloud.operation.service.SendMailService$$FastClassBySpringCGLIB$$5cefa3af.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:115)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: javax.mail.MessagingException: Can't send command to SMTP host
at com.sun.mail.smtp.SMTPTrans
二、问题分析
在网上搜了一下这个问题,确实是有这个问题的说法和解决方案,基本就是说java的一个java.security问题的配置问题:
jdk.tls.disabledAlorithms这个配置其实就是说需要禁止的协议列表。
所以根据解决方案的说法,我们也就是直接将其配置的SSLv3给去掉就好了。
三、问题解决方案(docker容器)
因为我这边的情况是使用的是docker容器化部署,所以解决方案也是根据这个来进行解决的。
(1)进入容器
docker exec -it 容器id /bin/sh
(2)找到java.security文件
find / -name 'java.security'
vim 文件目录
(3)修改
修改java.security中的disabledAlgorithms,删除SSLv3, TLSv1, TLSv1.1,然后重启应用即可。
在vim下,可以使用/disabledAlgorithms快速查找。
四、永久的解决方案
其实docker 容器使用上面这种方式去进行修改其实是可以解决问题的。
但是如果是使用dockerfile去其他容器并会经常性的重启更新这个容器的话,这个使用这种方式就不太可取了,因为一旦使用dockerfile重新生成这个容器,那么原先的配置也就都没了
所以我们需要从根本上解决这个问题。
方法一:选一个默认没有禁用这个属性的java版本
方法二:在dockerfile文件上加上:(内容根据实际情况改变而改变,我的这个java版本可能会和你的不太一样)
sed -i 's/jdk.tls.disabledAlgorithms=SSLv3, TLSv1, TLSv1.1,/jdk.tls.disabledAlgorithms=/g' /usr/lib/jvm/java-1.8-openjdk/jre/lib/security/java.security