9
votes

I'm trying to do java mail and im getting an error "Cant send command to SMTP host". Any help would be appreciated. And any future problems' solutions if possible. The exact Exception is

javax.mail.MessagingException: Can't send command to SMTP host;
  nested exception is:
    java.net.SocketException: Connection closed by remote host
    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 TestEmail.main(TestEmail.java:45)
    at __SHELL17.run(__SHELL17.java:6)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at bluej.runtime.ExecServer$3.run(ExecServer.java:774)
Caused by: java.net.SocketException: Connection closed by remote host
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.checkWrite(SSLSocketImpl.java:1186)
    at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:43)
    at com.sun.mail.util.TraceOutputStream.write(TraceOutputStream.java:114)
    at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65)
    at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123)
    at com.sun.mail.smtp.SMTPTransport.sendCommand(SMTPTransport.java:2104)
    ... 11 more

My code is as follows

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

// Send a simple, single part, text/plain e-mail
public class TestEmail {

    public static void main(String[] args) {

        // SUBSTITUTE YOUR EMAIL ADDRESSES HERE!!!
        String to = "my gmail account whose name i removed for publicity";
        String from = "my hotmail account whose name i removed for publicity";
        // SUBSTITUTE YOUR ISP'S MAIL SERVER HERE!!!
        String host = "smtp.live.com";

        // Create properties, get Session
        Properties props = new Properties();

        // If using static Transport.send(),
        // need to specify which host to send it to
        props.put("mail.smtp.host", host);
        props.put("mail.smtp.starttls.enable", "true");
        // To see what is going on behind the scene
        props.put("mail.debug", "true");
        Session session = Session.getInstance(props);

        try {
            // Instantiatee a message
            Message msg = new MimeMessage(session);

            //Set message attributes
            msg.setFrom(new InternetAddress(from));
            InternetAddress[] address = {new InternetAddress(to)};
            msg.setRecipients(Message.RecipientType.TO, address);
            msg.setSubject("Test E-Mail through Java");
            msg.setSentDate(new Date());

            // Set message content
            msg.setText("This is a test of sending a " +
                        "plain text e-mail through Java.\n" +
                        "Here is line 2.");

            //Send the message
            Transport.send(msg);
        }
        catch (MessagingException mex) {
            // Prints all nested (chained) exceptions as well
            mex.printStackTrace();
        }
    }
}
6
"And any future problems' solutions if possible" -- really?Jim Garrison
Well I mean like I put in "mail.smtp.auth" earlier and got a username and password error so thats what i meanGlobmont
THe stack trace says "Connection closed by remote host". You are going to have to use Wireshark to capture the traffic and find out the exact sequence of events. What happens if you manually telnet to the mail server and try a mail session?Jim Garrison
I'm sorry I'm not too familiar with SMTP and mail so I didn't exactly understand what you just said. Can you please de-techify that? :)Globmont
I posted an answer below. However, until you understand a lot more about SMTP and TLS you're not going to be able to make progress.Jim Garrison

6 Answers

12
votes

Today I gone through this same issue. But for me the issue is, in smtp server TLS was not enabled. So I have changed the mail properties like this.
mail.smtp.starttls.enable=false

Now every thing is working good for me.

3
votes

In my case, I was able to find the root problem after I enabled mailer debugging.

Different ways to enable mailer debugging:

java -Dmail.debug=true ...

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

Jenkins config (/etc/default/jenkins):

JAVA_ARGS="-Dmail.smtp.starttls.enable=true -Dmail.debug=true"

More info: http://www.oracle.com/technetwork/java/faq-135477.html

My particular error was that I had an incorrect address in the "from:" line when the email was created. Google "G Suite" (google apps for business) requires the from-address to be in the same domain as the account owner. Eg. mycompanyname.com

The mailer debug revealed:

MAIL FROM:<[email protected]> 550-5.7.1 Invalid credentials for relay [192.168.42.42]. The IP address you've 550-5.7.1 registered in your G Suite SMTP Relay service doesn't match domain of 550-5.7.1 the account this email is being sent from. If you are trying to relay 550-5.7.1 mail from a domain that isn't registered under your G Suite account

1
votes

The server requires STARTTLS. Here's what I get if I do a manual SMTP session with telnet:

220 BLU0-SMTP122.phx.gbl Microsoft ESMTP MAIL Service, Version: 6.0.3790.4675 ready at  Mon, 18 Jul 2011 17:08:14 -0700
HELO jhmg.net
250 BLU0-SMTP122.phx.gbl Hello [70.123.155.64]
MAIL FROM:<[email protected]>
530 5.7.0 Must issue a STARTTLS command first

This server does not accept unencrypted connections

0
votes

Try adding from address

mail.setFromAddress("Name ");

0
votes

You need to set ssl trust to smtp.gmail.com

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

and Authenticator as a parameter for session


        Session session = Session.getDefaultInstance(properties,new javax.mail.Authenticator(){
            protected PasswordAuthentication getPasswordAuthentication() {

                return new PasswordAuthentication(
                        sender, senderPassword);// Specify the Username and the PassWord
            }
        });
-1
votes

Added this line for O365. Works fine now.

sslMailProps.put("mail.smtp.ssl.enable", "true");