One of the easily available sample programs in the net is java mail application that you can use to send automated emails from java application. While running these java mail application program, sometimes you might get several errors - popular one is "Can't send command to SMTP host;".
The complete stack trace is here:-
Exception in thread "main" javax.mail.MessagingException: Can't send command to SMTP host;
nested exception is:
java.net.SocketException: Software caused connection abort: socket write error
at com.sun.mail.smtp.SMTPTransport.sendCommand(SMTPTransport.java:2106)
at com.sun.mail.smtp.SMTPTransport.sendCommand(SMTPTransport.java:2093)
at com.sun.mail.smtp.SMTPTransport.close(SMTPTransport.java:1184)
at javax.mail.Transport.send0(Transport.java:197)
at javax.mail.Transport.send(Transport.java:124)
at SendMail.main(SendMail.java:27)
Caused by: java.net.SocketException: Software caused connection abort: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(Unknown Source)
at java.net.SocketOutputStream.write(Unknown Source)
at com.sun.mail.util.TraceOutputStream.write(TraceOutputStream.java:114)
at java.io.BufferedOutputStream.flushBuffer(Unknown Source)
at java.io.BufferedOutputStream.flush(Unknown Source)
at com.sun.mail.smtp.SMTPTransport.sendCommand(SMTPTransport.java:2104)
... 5 more
The sample code that generated the exception above is
import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
public class SampleSMTPClient1 {
public static void main(String args[]) throws Exception {
Properties properties = new Properties();
properties.setProperty("mail.smtp.host", "localhost" );
Session session = Session.getDefaultInstance(properties);
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress("joe.smith@js.com"));
message.addRecipient(Message.RecipientType.TO, new InternetAddress("jsmith@js.com"));
message.setSubject("Wishes..!");
message.setText("Have a great day!");
System.out.println("Sending Message .....");
Transport.send(message);
System.out.println("Message Sent.....");
}
}
By adding properties.put("mail.debug", "true"), your program can generate lots of debug information. I did so, and then I got all the below mentioned debug information.
Now it is pretty much clear that client authentication is required. Otherwise your SMTP server will not allow you to send emails. Now, the question is - how do we pass the credentials required for the client authentication. While there may be other way possible, I have followed the below one and got it working.
You have to make two changes to the above code:
a) Add properties.put("mail.smtp.auth", "true");
b) Implement an authenticator class
The modified mail client program is as below: -
import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
public class SampleSMTPClient2 {
public static void main(String args[]) throws Exception {
Properties properties = new Properties();
properties.setProperty("mail.smtp.host", "localhost" );
properties.put("mail.smtp.auth", "true");
Session session = Session.getDefaultInstance(properties, new SMTPAuthenticator() );
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress("joe.smith@js.com"));
message.addRecipient(Message.RecipientType.TO, new InternetAddress("jsmith@js.com"));
message.setSubject("Wishes..!");
message.setText("Have a great day!");
System.out.println("Sending Message .....");
Transport.send(message);
System.out.println("Message Sent.....");
}
}
Now rerun the program. Hope this works for you as well!
The complete stack trace is here:-
Exception in thread "main" javax.mail.MessagingException: Can't send command to SMTP host;
nested exception is:
java.net.SocketException: Software caused connection abort: socket write error
at com.sun.mail.smtp.SMTPTransport.sendCommand(SMTPTransport.java:2106)
at com.sun.mail.smtp.SMTPTransport.sendCommand(SMTPTransport.java:2093)
at com.sun.mail.smtp.SMTPTransport.close(SMTPTransport.java:1184)
at javax.mail.Transport.send0(Transport.java:197)
at javax.mail.Transport.send(Transport.java:124)
at SendMail.main(SendMail.java:27)
Caused by: java.net.SocketException: Software caused connection abort: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(Unknown Source)
at java.net.SocketOutputStream.write(Unknown Source)
at com.sun.mail.util.TraceOutputStream.write(TraceOutputStream.java:114)
at java.io.BufferedOutputStream.flushBuffer(Unknown Source)
at java.io.BufferedOutputStream.flush(Unknown Source)
at com.sun.mail.smtp.SMTPTransport.sendCommand(SMTPTransport.java:2104)
... 5 more
The sample code that generated the exception above is
import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
public class SampleSMTPClient1 {
public static void main(String args[]) throws Exception {
Properties properties = new Properties();
properties.setProperty("mail.smtp.host", "localhost" );
Session session = Session.getDefaultInstance(properties);
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress("joe.smith@js.com"));
message.addRecipient(Message.RecipientType.TO, new InternetAddress("jsmith@js.com"));
message.setSubject("Wishes..!");
message.setText("Have a great day!");
System.out.println("Sending Message .....");
Transport.send(message);
System.out.println("Message Sent.....");
}
}
By adding properties.put("mail.debug", "true"), your program can generate lots of debug information. I did so, and then I got all the below mentioned debug information.
DEBUG: JavaMail version 1.4.4
DEBUG: successfully loaded resource: /META-INF/javamail.default.providers
DEBUG: Tables of loaded providers
DEBUG: Providers Listed By Class Name: {com.sun.mail.smtp.SMTPSSLTransport=javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Sun Microsystems, Inc], com.sun.mail.smtp.SMTPTransport=javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc], com.sun.mail.imap.IMAPSSLStore=javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Sun Microsystems, Inc], com.sun.mail.pop3.POP3SSLStore=javax.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Sun Microsystems, Inc], com.sun.mail.imap.IMAPStore=javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Sun Microsystems, Inc], com.sun.mail.pop3.POP3Store=javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Sun Microsystems, Inc]}
DEBUG: Providers Listed By Protocol: {imaps=javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Sun Microsystems, Inc], imap=javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Sun Microsystems, Inc], smtps=javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Sun Microsystems, Inc], pop3=javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Sun Microsystems, Inc], pop3s=javax.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Sun Microsystems, Inc], smtp=javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc]}
DEBUG: successfully loaded resource: /META-INF/javamail.default.address.map
Sending Message .....
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc]
DEBUG SMTP: useEhlo true, useAuth false
DEBUG SMTP: trying to connect to host "localhost", port 25, isSSL false
220 LOCALHOST Microsoft ESMTP MAIL Service ready at Thu, 2 Aug 2012 10:23:10 +0530
DEBUG SMTP: connected to host "localhost", port: 25
EHLO LOCALHOST
DEBUG: successfully loaded resource: /META-INF/javamail.default.providers
DEBUG: Tables of loaded providers
DEBUG: Providers Listed By Class Name: {com.sun.mail.smtp.SMTPSSLTransport=javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Sun Microsystems, Inc], com.sun.mail.smtp.SMTPTransport=javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc], com.sun.mail.imap.IMAPSSLStore=javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Sun Microsystems, Inc], com.sun.mail.pop3.POP3SSLStore=javax.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Sun Microsystems, Inc], com.sun.mail.imap.IMAPStore=javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Sun Microsystems, Inc], com.sun.mail.pop3.POP3Store=javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Sun Microsystems, Inc]}
DEBUG: Providers Listed By Protocol: {imaps=javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Sun Microsystems, Inc], imap=javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Sun Microsystems, Inc], smtps=javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Sun Microsystems, Inc], pop3=javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Sun Microsystems, Inc], pop3s=javax.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Sun Microsystems, Inc], smtp=javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc]}
DEBUG: successfully loaded resource: /META-INF/javamail.default.address.map
Sending Message .....
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc]
DEBUG SMTP: useEhlo true, useAuth false
DEBUG SMTP: trying to connect to host "localhost", port 25, isSSL false
220 LOCALHOST Microsoft ESMTP MAIL Service ready at Thu, 2 Aug 2012 10:23:10 +0530
DEBUG SMTP: connected to host "localhost", port: 25
EHLO LOCALHOST
250-LOCALHOST Hello [10.xx.xx.xx]
250-SIZE
250-PIPELINING
250-DSN
250-ENHANCEDSTATUSCODES
250-STARTTLS
250-X-ANONYMOUSTLS
250-AUTH NTLM
250-X-EXPS GSSAPI NTLM
250-8BITMIME
250-BINARYMIME
250-CHUNKING
250-XEXCH50
250 XRDST
DEBUG SMTP: Found extension "SIZE", arg ""
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "DSN", arg ""
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Found extension "STARTTLS", arg ""
DEBUG SMTP: Found extension "X-ANONYMOUSTLS", arg ""
DEBUG SMTP: Found extension "AUTH", arg "NTLM"
DEBUG SMTP: Found extension "X-EXPS", arg "GSSAPI NTLM"
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "BINARYMIME", arg ""
DEBUG SMTP: Found extension "CHUNKING", arg ""
DEBUG SMTP: Found extension "XEXCH50", arg ""
DEBUG SMTP: Found extension "XRDST", arg ""
DEBUG SMTP: use8bit false
MAIL FROM:<joe.smith@js.com>
530 5.7.1 Client was not authenticated
DEBUG SMTP: got response code 530, with response: 530 5.7.1 Client was not authenticated
RSET
DEBUG SMTP: EOF: [EOF]
com.sun.mail.smtp.SMTPSendFailedException: 530 5.7.1 Client was not authenticated
at com.sun.mail.smtp.SMTPTransport.issueSendCommand(SMTPTransport.java:2057)
at com.sun.mail.smtp.SMTPTransport.mailFrom(SMTPTransport.java:1580)
at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:1097)
at javax.mail.Transport.send0(Transport.java:195)
at javax.mail.Transport.send(Transport.java:124)
at SendMail.main(SendMail.java:29)
QUIT
250-SIZE
250-PIPELINING
250-DSN
250-ENHANCEDSTATUSCODES
250-STARTTLS
250-X-ANONYMOUSTLS
250-AUTH NTLM
250-X-EXPS GSSAPI NTLM
250-8BITMIME
250-BINARYMIME
250-CHUNKING
250-XEXCH50
250 XRDST
DEBUG SMTP: Found extension "SIZE", arg ""
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "DSN", arg ""
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Found extension "STARTTLS", arg ""
DEBUG SMTP: Found extension "X-ANONYMOUSTLS", arg ""
DEBUG SMTP: Found extension "AUTH", arg "NTLM"
DEBUG SMTP: Found extension "X-EXPS", arg "GSSAPI NTLM"
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "BINARYMIME", arg ""
DEBUG SMTP: Found extension "CHUNKING", arg ""
DEBUG SMTP: Found extension "XEXCH50", arg ""
DEBUG SMTP: Found extension "XRDST", arg ""
DEBUG SMTP: use8bit false
MAIL FROM:<joe.smith@js.com>
530 5.7.1 Client was not authenticated
DEBUG SMTP: got response code 530, with response: 530 5.7.1 Client was not authenticated
RSET
DEBUG SMTP: EOF: [EOF]
com.sun.mail.smtp.SMTPSendFailedException: 530 5.7.1 Client was not authenticated
at com.sun.mail.smtp.SMTPTransport.issueSendCommand(SMTPTransport.java:2057)
at com.sun.mail.smtp.SMTPTransport.mailFrom(SMTPTransport.java:1580)
at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:1097)
at javax.mail.Transport.send0(Transport.java:195)
at javax.mail.Transport.send(Transport.java:124)
at SendMail.main(SendMail.java:29)
QUIT
Now it is pretty much clear that client authentication is required. Otherwise your SMTP server will not allow you to send emails. Now, the question is - how do we pass the credentials required for the client authentication. While there may be other way possible, I have followed the below one and got it working.
You have to make two changes to the above code:
a) Add properties.put("mail.smtp.auth", "true");
b) Implement an authenticator class
import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;
public class SMTPAuthenticator extends Authenticator {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("username", "password");
}
}
import javax.mail.PasswordAuthentication;
public class SMTPAuthenticator extends Authenticator {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("username", "password");
}
}
The modified mail client program is as below: -
import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
public class SampleSMTPClient2 {
public static void main(String args[]) throws Exception {
Properties properties = new Properties();
properties.setProperty("mail.smtp.host", "localhost" );
properties.put("mail.smtp.auth", "true");
Session session = Session.getDefaultInstance(properties, new SMTPAuthenticator() );
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress("joe.smith@js.com"));
message.addRecipient(Message.RecipientType.TO, new InternetAddress("jsmith@js.com"));
message.setSubject("Wishes..!");
message.setText("Have a great day!");
System.out.println("Sending Message .....");
Transport.send(message);
System.out.println("Message Sent.....");
}
}
Now rerun the program. Hope this works for you as well!