JavaMail 不使用 SMTP 发送内容,发送 "QUIT" 并挂起
JavaMail sends no content with SMTP, sends "QUIT" and hangs
我正在尝试在 Java 8 中使用 JavaMail 1.6 to send an email to a local MailHog SMTP 服务器。代码是:
// import javax.mail.*;
// import javax.mail.internet.*;
// import javax.mail.internet.MimeMessage.RecipientType;
String from = "test_sender@gmail.com";
String to = "test_receiver@gmail.com";
String subject = "Sample subject";
String body = "Test message, please ignore";
Properties props = System.getProperties();
props.setProperty("mail.smtp.host", "localhost");
props.setProperty("mail.smtp.port", "1025");
Session session = Session.getInstance(props);
session.setDebug(true);
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
message.addRecipient(RecipientType.TO, new InternetAddress(to));
message.setSubject(subject);
message.setText(body);
Transport.send(message);
当代码为运行时,它将启动并与服务器建立会话,并逐步通过 SMTP 直到它应该发送数据。此后,它发送 QUIT\r\n
并挂起,不发送任何内容。
MailHog 日志:
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] Starting session
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] [PROTO: INVALID] Started session, switching to ESTABLISH state
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] Sent 35 bytes: '220 mailhog.example ESMTP MailHog\r\n'
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] Received 26 bytes: 'EHLO DEVICE.local\r\n'
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] [PROTO: ESTABLISH] Processing line: EHLO DEVICE.local
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] [PROTO: ESTABLISH] In state 1, got command 'EHLO', args 'DEVICE.local'
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] [PROTO: ESTABLISH] In ESTABLISH state
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] [PROTO: ESTABLISH] Got EHLO command, switching to MAIL state
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] Sent 31 bytes: '250-Hello DEVICE.local\r\n'
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] Sent 16 bytes: '250-PIPELINING\r\n'
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] Sent 16 bytes: '250 AUTH PLAIN\r\n'
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] Received 37 bytes: 'MAIL FROM:<sample_sender@gmail.com>\r\n'
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] [PROTO: MAIL] Processing line: MAIL FROM:<sample_sender@gmail.com>
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] [PROTO: MAIL] In state 6, got command 'MAIL', args 'FROM:<sample_sender@gmail.com>'
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] [PROTO: MAIL] In MAIL state
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] [PROTO: MAIL] Got MAIL command, switching to RCPT state
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] Sent 39 bytes: '250 Sender sample_sender@gmail.com ok\r\n'
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] Received 37 bytes: 'RCPT TO:<sample_receiver@gmail.com>\r\n'
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] [PROTO: RCPT] Processing line: RCPT TO:<sample_receiver@gmail.com>
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] [PROTO: RCPT] In state 7, got command 'RCPT', args 'TO:<sample_receiver@gmail.com>'
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] [PROTO: RCPT] In RCPT state
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] [PROTO: RCPT] Got RCPT command
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] Sent 44 bytes: '250 Recipient sample_receiver@gmail.com ok\r\n'
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] Received 6 bytes: 'DATA\r\n'
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] [PROTO: RCPT] Processing line: DATA
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] [PROTO: RCPT] In state 7, got command 'DATA', args ''
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] [PROTO: RCPT] In RCPT state
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] [PROTO: RCPT] Got DATA command, switching to DATA state
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] Sent 37 bytes: '354 End data with <CR><LF>.<CR><LF>\r\n'
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] Received 6 bytes: 'QUIT\r\n'
Java 输出:
DEBUG: setDebug: JavaMail version 1.6.2
DEBUG: successfully loaded resource: /META-INF/javamail.default.providers
DEBUG: Tables of loaded providers from javamail.providers
DEBUG: Providers Listed By Class Name: {com.sun.mail.smtp.SMTPTransport=javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle], com.sun.mail.imap.IMAPSSLStore=javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Oracle], com.sun.mail.pop3.POP3Store=javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Oracle], com.sun.mail.smtp.SMTPSSLTransport=javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Oracle], com.sun.mail.imap.IMAPStore=javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Oracle], com.sun.mail.pop3.POP3SSLStore=javax.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Oracle]}
DEBUG: Providers Listed By Protocol: {imap=javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Oracle], smtp=javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle], pop3=javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Oracle], imaps=javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Oracle], smtps=javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Oracle], pop3s=javax.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Oracle]}
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle]
DEBUG SMTP: useEhlo true, useAuth false
DEBUG SMTP: trying to connect to host "localhost", port 1025, isSSL false
220 mailhog.example ESMTP MailHog
DEBUG SMTP: connected to host "localhost", port: 1025
EHLO DEVICE.local
250-Hello DEVICE.local
250-PIPELINING
250 AUTH PLAIN
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "AUTH", arg "PLAIN"
DEBUG SMTP: use8bit false
MAIL FROM:<sample_sender@gmail.com>
250 Sender sample_sender@gmail.com ok
RCPT TO:<sample_receiver@gmail.com>
250 Recipient sample_receiver@gmail.com ok
DEBUG SMTP: Verified Addresses
DEBUG SMTP: sample_receiver@gmail.com
DATA
354 End data with <CR><LF>.<CR><LF>
QUIT
环顾四周,我可以找到一些 JavaMail 在发送邮件时挂起的参考,但其中 none 似乎在会话的这一部分挂起。看起来应该是与 message.setText
有关的错误配置。但是,在使用 message.setContent(body, "text/plain")
、使用 MimeMultipart
并在内容中添加 MimeBodyPart
以及使用 DataHandler
时,我得到了相同的行为。此外,如果它是内容的错误配置,我觉得很奇怪它立即发送 QUIT
而没有先终止 DATA
。据我所知,正常的交换看起来像:
DATA
354 End data with <CR><LF>.<CR><LF>
Test message, please ignore
.
QUIT
回答我自己的问题:
JavaMail(Maven 包 javax.mail/javax.mail-api
)已移至 Jakarta Mail (com.sun.mail/jakarta.mail
)。我不太确定旧包有什么问题,但是一旦我从
更新了适当的 Maven 依赖项
<dependency>
<groupId>javax.mail</groupId>
<artifactId>javax.mail-api</artifactId>
<version>1.6.2</version>
</dependency>
到
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>jakarta.mail</artifactId>
<version>1.6.4</version>
</dependency>
问题自行解决,无需进一步更改代码。
我正在尝试在 Java 8 中使用 JavaMail 1.6 to send an email to a local MailHog SMTP 服务器。代码是:
// import javax.mail.*;
// import javax.mail.internet.*;
// import javax.mail.internet.MimeMessage.RecipientType;
String from = "test_sender@gmail.com";
String to = "test_receiver@gmail.com";
String subject = "Sample subject";
String body = "Test message, please ignore";
Properties props = System.getProperties();
props.setProperty("mail.smtp.host", "localhost");
props.setProperty("mail.smtp.port", "1025");
Session session = Session.getInstance(props);
session.setDebug(true);
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
message.addRecipient(RecipientType.TO, new InternetAddress(to));
message.setSubject(subject);
message.setText(body);
Transport.send(message);
当代码为运行时,它将启动并与服务器建立会话,并逐步通过 SMTP 直到它应该发送数据。此后,它发送 QUIT\r\n
并挂起,不发送任何内容。
MailHog 日志:
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] Starting session
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] [PROTO: INVALID] Started session, switching to ESTABLISH state
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] Sent 35 bytes: '220 mailhog.example ESMTP MailHog\r\n'
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] Received 26 bytes: 'EHLO DEVICE.local\r\n'
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] [PROTO: ESTABLISH] Processing line: EHLO DEVICE.local
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] [PROTO: ESTABLISH] In state 1, got command 'EHLO', args 'DEVICE.local'
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] [PROTO: ESTABLISH] In ESTABLISH state
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] [PROTO: ESTABLISH] Got EHLO command, switching to MAIL state
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] Sent 31 bytes: '250-Hello DEVICE.local\r\n'
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] Sent 16 bytes: '250-PIPELINING\r\n'
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] Sent 16 bytes: '250 AUTH PLAIN\r\n'
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] Received 37 bytes: 'MAIL FROM:<sample_sender@gmail.com>\r\n'
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] [PROTO: MAIL] Processing line: MAIL FROM:<sample_sender@gmail.com>
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] [PROTO: MAIL] In state 6, got command 'MAIL', args 'FROM:<sample_sender@gmail.com>'
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] [PROTO: MAIL] In MAIL state
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] [PROTO: MAIL] Got MAIL command, switching to RCPT state
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] Sent 39 bytes: '250 Sender sample_sender@gmail.com ok\r\n'
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] Received 37 bytes: 'RCPT TO:<sample_receiver@gmail.com>\r\n'
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] [PROTO: RCPT] Processing line: RCPT TO:<sample_receiver@gmail.com>
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] [PROTO: RCPT] In state 7, got command 'RCPT', args 'TO:<sample_receiver@gmail.com>'
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] [PROTO: RCPT] In RCPT state
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] [PROTO: RCPT] Got RCPT command
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] Sent 44 bytes: '250 Recipient sample_receiver@gmail.com ok\r\n'
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] Received 6 bytes: 'DATA\r\n'
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] [PROTO: RCPT] Processing line: DATA
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] [PROTO: RCPT] In state 7, got command 'DATA', args ''
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] [PROTO: RCPT] In RCPT state
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] [PROTO: RCPT] Got DATA command, switching to DATA state
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] Sent 37 bytes: '354 End data with <CR><LF>.<CR><LF>\r\n'
2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] Received 6 bytes: 'QUIT\r\n'
Java 输出:
DEBUG: setDebug: JavaMail version 1.6.2
DEBUG: successfully loaded resource: /META-INF/javamail.default.providers
DEBUG: Tables of loaded providers from javamail.providers
DEBUG: Providers Listed By Class Name: {com.sun.mail.smtp.SMTPTransport=javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle], com.sun.mail.imap.IMAPSSLStore=javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Oracle], com.sun.mail.pop3.POP3Store=javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Oracle], com.sun.mail.smtp.SMTPSSLTransport=javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Oracle], com.sun.mail.imap.IMAPStore=javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Oracle], com.sun.mail.pop3.POP3SSLStore=javax.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Oracle]}
DEBUG: Providers Listed By Protocol: {imap=javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Oracle], smtp=javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle], pop3=javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Oracle], imaps=javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Oracle], smtps=javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Oracle], pop3s=javax.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Oracle]}
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle]
DEBUG SMTP: useEhlo true, useAuth false
DEBUG SMTP: trying to connect to host "localhost", port 1025, isSSL false
220 mailhog.example ESMTP MailHog
DEBUG SMTP: connected to host "localhost", port: 1025
EHLO DEVICE.local
250-Hello DEVICE.local
250-PIPELINING
250 AUTH PLAIN
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "AUTH", arg "PLAIN"
DEBUG SMTP: use8bit false
MAIL FROM:<sample_sender@gmail.com>
250 Sender sample_sender@gmail.com ok
RCPT TO:<sample_receiver@gmail.com>
250 Recipient sample_receiver@gmail.com ok
DEBUG SMTP: Verified Addresses
DEBUG SMTP: sample_receiver@gmail.com
DATA
354 End data with <CR><LF>.<CR><LF>
QUIT
环顾四周,我可以找到一些 JavaMail 在发送邮件时挂起的参考,但其中 none 似乎在会话的这一部分挂起。看起来应该是与 message.setText
有关的错误配置。但是,在使用 message.setContent(body, "text/plain")
、使用 MimeMultipart
并在内容中添加 MimeBodyPart
以及使用 DataHandler
时,我得到了相同的行为。此外,如果它是内容的错误配置,我觉得很奇怪它立即发送 QUIT
而没有先终止 DATA
。据我所知,正常的交换看起来像:
DATA
354 End data with <CR><LF>.<CR><LF>
Test message, please ignore
.
QUIT
回答我自己的问题:
JavaMail(Maven 包 javax.mail/javax.mail-api
)已移至 Jakarta Mail (com.sun.mail/jakarta.mail
)。我不太确定旧包有什么问题,但是一旦我从
<dependency>
<groupId>javax.mail</groupId>
<artifactId>javax.mail-api</artifactId>
<version>1.6.2</version>
</dependency>
到
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>jakarta.mail</artifactId>
<version>1.6.4</version>
</dependency>
问题自行解决,无需进一步更改代码。