I’m trying to use JavaMail 1.6 to send an email to a local MailHog SMTP server in Java 8. The code is:
// 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);
When the code is ran, it will start and establish a session with the server, and step through SMTP until it’s supposed to send data. After this, it sends QUITrn
and hangs, not sending any content.
MailHog logs:
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 MailHogrn' 2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] Received 26 bytes: 'EHLO DEVICE.localrn' 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.localrn' 2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] Sent 16 bytes: '250-PIPELININGrn' 2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] Sent 16 bytes: '250 AUTH PLAINrn' 2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] Received 37 bytes: 'MAIL FROM:<sample_sender@gmail.com>rn' 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 okrn' 2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] Received 37 bytes: 'RCPT TO:<sample_receiver@gmail.com>rn' 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 okrn' 2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] Received 6 bytes: 'DATArn' 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>rn' 2022/02/25 16:18:18 [SMTP 127.0.0.1:58831] Received 6 bytes: 'QUITrn'
Java output:
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
Looking around, I can find a few references of JavaMail hanging while sending mail, but none of them seem to hang at this part of the session. It seems like it should be a misconfiguration related to message.setText
. However, I get the same behavior when using message.setContent(body, "text/plain")
, using MimeMultipart
and adding a MimeBodyPart
with the content, and also when using a DataHandler
. Furthermore, if it is a misconfiguration of the content, I find it weird that it’s sending a QUIT
immediately without first terminating the DATA
. As far as I know, a normal exchange would look something like:
DATA 354 End data with <CR><LF>.<CR><LF> Test message, please ignore . QUIT
Advertisement
Answer
Answering my own question:
JavaMail (Maven package javax.mail/javax.mail-api
) was moved to Jakarta Mail (com.sun.mail/jakarta.mail
). I’m not really sure what’s wrong with the old package, but once I updated the appropriate maven dependency from
<dependency> <groupId>javax.mail</groupId> <artifactId>javax.mail-api</artifactId> <version>1.6.2</version> </dependency>
to
<dependency> <groupId>com.sun.mail</groupId> <artifactId>jakarta.mail</artifactId> <version>1.6.4</version> </dependency>
The issue resolved itself with no further code changes needed.