Javamail无法将套接字转换为TLS GMail

我正在尝试通过gmails SMTP服务器使用JavaMail发送电子邮件。 但是这段代码。

final String username = "mygmail@gmail.com";
    final String password = "mygmailpassword";

    Properties props = new Properties();
    props.put("mail.smtp.auth", true);
    props.put("mail.smtp.starttls.enable", true);
    props.put("mail.smtp.host", "smtp.gmail.com");
    props.put("mail.smtp.port", "587");

    Session session = Session.getInstance(props,
            new javax.mail.Authenticator() {
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(username, password);
                }
            });

    try {

        Message message = new MimeMessage(session);
        message.setFrom(new InternetAddress("no-reply@gmail.com"));
        message.setRecipients(Message.RecipientType.TO,
                InternetAddress.parse("test@gmail.com"));
        message.setSubject("Testing Subject");
        message.setText("Dear Mail Crawler,"
                + "\n\n No spam to my email, please!");

        Transport.send(message);

        System.out.println("Done");

    } catch (MessagingException e) {
        throw new RuntimeException(e);
    }

返回此错误

Could not convert socket to TLS;

完整的堆栈跟踪

Exception in thread "main" java.lang.RuntimeException: javax.mail.MessagingException: Could not convert socket to TLS;
  nested exception is:
    javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at Test.main(Test.java:43)
Caused by: javax.mail.MessagingException: Could not convert socket to TLS;
  nested exception is:
    javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at com.sun.mail.smtp.SMTPTransport.startTLS(SMTPTransport.java:1907)
    at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:666)
    at javax.mail.Service.connect(Service.java:317)
    at javax.mail.Service.connect(Service.java:176)
    at javax.mail.Service.connect(Service.java:125)
    at javax.mail.Transport.send0(Transport.java:194)
    at javax.mail.Transport.send(Transport.java:124)
    at Test.main(Test.java:38)
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1649)
    at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:241)
    at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:235)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1206)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:136)
    at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:593)
    at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:529)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:893)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1138)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1165)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1149)
    at com.sun.mail.util.SocketFetcher.configureSSLSocket(SocketFetcher.java:549)
    at com.sun.mail.util.SocketFetcher.startTLS(SocketFetcher.java:486)
    at com.sun.mail.smtp.SMTPTransport.startTLS(SMTPTransport.java:1902)
    ... 7 more
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:323)
    at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:217)
    at sun.security.validator.Validator.validate(Validator.java:218)
    at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:126)
    at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:209)
    at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:249)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1185)
    ... 17 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:174)
    at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:238)
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:318)
    ... 23 more
user962206 asked 2020-07-28T06:58:29Z
11个解决方案
118 votes
props.put("mail.smtp.ssl.trust", "smtp.gmail.com");
carlos answered 2020-07-28T07:08:55Z
22 votes

确保您的防病毒程序没有干扰,并确保在防火墙中添加排除项。

shiva raj answered 2020-07-28T07:09:15Z
21 votes

我禁用了avast防病毒软件10分钟,然后使其开始工作。

Shahid Abbasi answered 2020-07-28T07:09:35Z
7 votes

@carlos的第一个答案对我有用:

session.getProperties().put("mail.smtp.ssl.trust", "smtp.gmail.com");

我已经测试了以下属性,并且对我来说也很完美:

session.getProperties().put("mail.smtp.starttls.enable", "true");

仅这两个属性就解决了这类问题,但可以肯定的是,我同时使用了这两个属性。

ℛɑƒæĿ answered 2020-07-28T07:10:04Z
2 votes

尝试将端口更改为465

mail.smtp.socketFactory.port=465
mail.smtp.port=465
trilogy answered 2020-07-28T07:10:24Z
1 votes

如果您的环境是android应用程序,然后确保将您的android设备时间设置为当前日期和时间。潜在的例外是“ SSL证书未得到认证。”

Rizwan_Khan answered 2020-07-28T07:10:44Z
1 votes

就我而言,问题是通过删除该行来解决的

prop.put("mail.smtp.starttls.enable", "true");

我不确定这可能是由于电子邮件服务器上的某些SSL配置错误所致。 电子邮件服务器管理员从不接受它,而总是将责任归咎于托管服务提供商:)

nurb answered 2020-07-28T07:11:09Z
0 votes

尝试使用JavaMail随附的smtpsend程序,如此处所述。 如果同样失败,则说明您的JDK配置或网络配置有问题。

Bill Shannon answered 2020-07-28T07:11:29Z
0 votes

这是工作解决方案兄弟。 保证

1)首先,打开您要用来发送邮件的gmail帐户,例如“ xyz@gmail.com”

2)在[https://support.google.com/accounts/answer/6010255?hl=zh_CN]下面打开此链接

3)点击“转到我的帐户中的“减少安全应用程序”部分”。 选项

4)然后打开它

5)就这样(:

这是我的代码

import javax.mail.*;
import javax.mail.internet.*;
import java.util.*;

public class SendEmail {

   final String senderEmailID = "Sender Email id";
final String senderPassword = "Sender Pass word";
final String emailSMTPserver = "smtp.gmail.com";
final String emailServerPort = "465";
String receiverEmailID = null;
static String emailSubject = "Test Mail";
static String emailBody = ":)";
public SendEmail(String receiverEmailID, String emailSubject, String emailBody)
{
this.receiverEmailID=receiverEmailID;
this.emailSubject=emailSubject;
this.emailBody=emailBody;
Properties props = new Properties();
props.put("mail.smtp.user",senderEmailID);
props.put("mail.smtp.host", emailSMTPserver);
props.put("mail.smtp.port", emailServerPort);
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.socketFactory.port", emailServerPort);
props.put("mail.smtp.socketFactory.class","javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.socketFactory.fallback", "false");
SecurityManager security = System.getSecurityManager();
try
{
Authenticator auth = new SMTPAuthenticator();
Session session = Session.getInstance(props, auth);
MimeMessage msg = new MimeMessage(session);
msg.setText(emailBody);
msg.setSubject(emailSubject);
msg.setFrom(new InternetAddress(senderEmailID));
msg.addRecipient(Message.RecipientType.TO,
new InternetAddress(receiverEmailID));
Transport.send(msg);
System.out.println("Message send Successfully:)");
}
catch (Exception mex)
{
mex.printStackTrace();
}
}
public class SMTPAuthenticator extends javax.mail.Authenticator
{
public PasswordAuthentication getPasswordAuthentication()
{
return new PasswordAuthentication(senderEmailID, senderPassword);
}
}
    public static void main(String[] args) {
       SendEmail mailSender;
        mailSender = new SendEmail("Receiver Email id","Testing Code 2 example","Testing Code Body yess");
    }

}
Zulfiqar Ali answered 2020-07-28T07:12:15Z
0 votes

帮助我解决此问题的方法(在此之前我已经尝试了所有方法)是将已安装的jre配置为JRE 1.8。

Eclipse中的步骤:Windows>首选项> java>已安装的JRE> jre1.8.0

如果将其设置为jdk,请切换到jre(这是最新Java版本默认情况下应设置为的值)。

Miadnew answered 2020-07-28T07:12:44Z
0 votes

如果应用程序不支持SMTP主机使用的TLS版本,也可能是这样。

例如,当您的应用程序(或使用较旧javax.mail JAR的Java程序)仅支持TLSv1.1时,尝试配置不使用TLSv1.2的SMTP服务器。

Catalan Cabbage answered 2020-07-28T07:13:09Z
translate from https://stackoverflow.com:/questions/16115453/javamail-could-not-convert-socket-to-tls-gmail