21

This program attempts to send e-mail but throws a run time exception:

javax.mail.AuthenticationFailedException: failed to connect, no password specified?

Why am I getting this exception when I have supplied the correct username and password for authentication?

Both the sender and receiver have g-mail accounts. The sender and the receiver both have g-mail accounts. The sender has 2-step verification process disabled.

This is the code:

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

class tester {
    public static void main(String args[]) {
        Properties props = new Properties();
        props.put("mail.smtp.host" , "smtp.gmail.com");
        props.put("mail.stmp.user" , "username");

        //To use TLS
        props.put("mail.smtp.auth", "true"); 
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.smtp.password", "password");
        //To use SSL
        props.put("mail.smtp.socketFactory.port", "465");
        props.put("mail.smtp.socketFactory.class", 
            "javax.net.ssl.SSLSocketFactory");
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.port", "465");


        Session session  = Session.getDefaultInstance( props , null);
        String to = "me@gmail.com";
        String from = "from@gmail.com";
        String subject = "Testing...";
        Message msg = new MimeMessage(session);
        try {
            msg.setFrom(new InternetAddress(from));
            msg.setRecipient(Message.RecipientType.TO, 
                new InternetAddress(to));
            msg.setSubject(subject);
            msg.setText("Working fine..!");
            Transport transport = session.getTransport("smtp");
            transport.connect("smtp.gmail.com" , 465 , "username", "password");
            transport.send(msg);
            System.out.println("fine!!");
        }
        catch(Exception exc) {
            System.out.println(exc);
        }
    }
}

Even after giving the password I get the exception. Why is it not authenticating?

Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335
Suhail Gupta
  • 22,386
  • 64
  • 200
  • 328

14 Answers14

17

Try to create an javax.mail.Authenticator Object, and send that in with the properties object to the Session object.

Authenticator edit:

You can modify this to accept a username and password and you can store them there, or where ever you want.

public class SmtpAuthenticator extends Authenticator {
public SmtpAuthenticator() {

    super();
}

@Override
public PasswordAuthentication getPasswordAuthentication() {
 String username = "user";
 String password = "password";
    if ((username != null) && (username.length() > 0) && (password != null) 
      && (password.length   () > 0)) {

        return new PasswordAuthentication(username, password);
    }

    return null;
}

In your class where you send the email:

SmtpAuthenticator authentication = new SmtpAuthenticator();
javax.mail.Message msg = new MimeMessage(Session
                    .getDefaultInstance(emailProperties, authenticator));
RMT
  • 7,040
  • 4
  • 25
  • 37
  • 1
    I cannot understand that. Can you please include this in your answer – Suhail Gupta Jul 07 '11 at 13:12
  • let me know if you need help i will try to help you out – RMT Jul 07 '11 at 13:38
  • @Suhail Gupta, I've already mentioned it on your previous [question](http://stackoverflow.com/questions/6609442/i-dont-get-the-e-mail-using-this-code-what-is-the-problem/6609615#6609615). – Buhake Sindi Jul 07 '11 at 13:39
  • @ RMT [this is my edited code after your answer](http://suhail03.my3gb.com/tester.java) Is that what you asked for ? – Suhail Gupta Jul 07 '11 at 13:41
  • you have to create an new instance of the Authenticator that you created. and send that into the defaultInstance method of the Session class. I edited answer accordingly – RMT Jul 07 '11 at 13:46
  • I edited my answer try using that instead of PasswordAuthentication – RMT Jul 07 '11 at 13:55
  • Errors when? compile or run time? – RMT Jul 07 '11 at 14:04
  • @SuhailGupta let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/1216/discussion-between-rmt-and-suhail-gupta) – RMT Jul 07 '11 at 14:04
  • @ RMT OK...(durin compile time) – Suhail Gupta Jul 07 '11 at 14:11
  • 1
    I run into the same error and this solved it, but why? Why does authentication works only when getting the Session instance with authenticator and not when trying to connect with Transport, as the user/pass is obviously the good one. – remi Jun 19 '13 at 09:37
15

You need to add the Object Authentication as the Parameter to the Session. such as

Session session = Session.getDefaultInstance(props, 
    new javax.mail.Authenticator(){
        protected PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication(
                "XXXX@gmail.com", "XXXXX");// Specify the Username and the PassWord
        }
});

now You will not get this kind of Exception....

javax.mail.AuthenticationFailedException: failed to connect, no password specified?
Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335
Sowmya Vallam
  • 151
  • 1
  • 2
4

Your email session should be provided an authenticator instance as below

Session session = Session.getDefaultInstance(props,
    new Authenticator() {
        protected PasswordAuthentication  getPasswordAuthentication() {
        return new PasswordAuthentication(
                    "myemail@gmail.com", "password");
                }
    });

a complete example is here http://bharatonjava.wordpress.com/2012/08/27/sending-email-using-java-mail-api/

Bharat Sharma
  • 141
  • 1
  • 4
3

I've solved this issue adding user and password in Transport.send call:

Transport.send(msg, "user", "password");

According to this signature of the send function in javax.mail (from version 1.5):

public static void send(Message msg, String user, String password)

Also, if you use this signature it's not necessary to set up any Authenticator, and to set user and password in the Properties (only the host is needed). So your code could be:

private void sendMail(){
  try{
      Properties prop = System.getProperties();
      prop.put("mail.smtp.host", "yourHost");
      Session session = Session.getInstance(prop);
      Message msg = #createYourMsg(session, from, to, subject, mailer, yatta yatta...)#;
      Transport.send(msg, "user", "password");
  }catch(Exception exc) {
      // Deal with it! :)
  }
}
T30
  • 11,422
  • 7
  • 53
  • 57
2

In addition to RMT's answer. I also had to modify the code a bit.

  1. Transport.send should be accessed statically
  2. therefor, transport.connect did not do anything for me, I only needed to set the connection info in the initial Properties object.

here is my sample send() methods. The config object is just a dumb data container.

public boolean send(String to, String from, String subject, String text) {
    return send(new String[] {to}, from, subject, text);
}

public boolean send(String[] to, String from, String subject, String text) {

    Properties props = new Properties();
    props.put("mail.smtp.auth", "true");
    props.put("mail.smtp.host", config.host);
    props.put("mail.smtp.user", config.username);
    props.put("mail.smtp.port", config.port);
    props.put("mail.smtp.password", config.password);

    Session session = Session.getInstance(props, new SmtpAuthenticator(config));

    try {
        Message message = new MimeMessage(session);
        message.setFrom(new InternetAddress(from));
        InternetAddress[] addressTo = new InternetAddress[to.length];
        for (int i = 0; i < to.length; i++) {
            addressTo[i] = new InternetAddress(to[i]);
        }
        message.setRecipients(Message.RecipientType.TO, addressTo);
        message.setSubject(subject);
        message.setText(text);
        Transport.send(message);
    } catch (MessagingException e) {
        e.printStackTrace();
        return false;
    }
    return true;
}
Kenny Cason
  • 12,109
  • 11
  • 47
  • 72
2

First of all, enable the less secure app in your Gmail account from which you will send emails using this link:- https://myaccount.google.com/lesssecureapps?pli=1

Then you simply add the following code in your session creation. It will work fine then.

Session mailSession = Session.getInstance(props, new javax.mail.Authenticator(){
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(
                    "your_email", "your_password");// Specify the Username and the PassWord
            }
        });

if you want the more elaborated one use the following:-

import java.util.Properties;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.NoSuchProviderException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

public class MailSender {

    public Properties mailProperties() {
        Properties props = new Properties();

        props.setProperty("mail.transport.protocol", "smtp");
        props.setProperty("mail.smtp.host", "smtp.gmail.com");
        props.setProperty("mail.smtp.port", "587");
        props.setProperty("mail.smtp.user", "your_email");
        props.setProperty("mail.smtp.password", "your_password");
        props.setProperty("mail.smtp.starttls.enable", "true");
        props.setProperty("mail.smtp.auth", "true");

        return props;
    }

    public String sendMail(String from, String to, String subject, String msgBody) {
        Properties props = mailProperties();
        Session mailSession = Session.getInstance(props, new javax.mail.Authenticator(){
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(
                    "your_email", "your_password");// Specify the Username and the PassWord
            }
        });

        mailSession.setDebug(false);

        try {
            Transport transport = mailSession.getTransport();

            MimeMessage message = new MimeMessage(mailSession);
            message.setSubject(subject);
            message.setFrom(new InternetAddress(from));
            message.addRecipients(Message.RecipientType.TO, to);

            MimeMultipart multipart = new MimeMultipart();

            MimeBodyPart messageBodyPart = new MimeBodyPart();

            messageBodyPart.setContent(msgBody, "text/html");

            multipart.addBodyPart(messageBodyPart);
            message.setContent(multipart);

            transport.connect();
            transport.sendMessage(message, message.getRecipients(Message.RecipientType.TO));
            transport.close();
            return "SUCCESS";
        } catch (NoSuchProviderException e) {
            e.printStackTrace();
            return "INVALID_EMAIL";
        } catch (MessagingException e) {
            e.printStackTrace();
        }
        return "ERROR";
    }

    public static void main(String args[]) {
        System.out.println(new MailSender().sendMail("your_email/from_email", "to_email", "Subject", "Message"));
    }
}

Hope! it helps. Thanks!

Arun Kumar N
  • 1,611
  • 1
  • 20
  • 25
1

It might be worth verifying that the gmail account hasn't been locked out due to several unsuccessful login attempts, you may need to reset your password. I had the same problem as you, and this turned out to be the solution.

Andrew Calder
  • 451
  • 4
  • 8
0
import java.util.Properties;

import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

@SuppressWarnings("serial")
public class RegisterAction {


    public String execute() {


         RegisterAction mailBean = new RegisterAction();

           String subject="Your username & password ";

           String message="Hi," + username;
          message+="\n \n Your username is " + email;
          message+="\n \n Your password is " + password;
          message+="\n \n Please login to the web site with your username and password.";
          message+="\n \n Thanks";
          message+="\n \n \n Regards";

           //Getting  FROM_MAIL

           String[] recipients = new String[1];
            recipients[0] = new String();
            recipients[0] = customer.getEmail();

           try{
          mailBean.sendMail(recipients,subject,message);

          return "success";
          }catch(Exception e){
           System.out.println("Error in sending mail:"+e);
          }

        return "failure";
    }

    public void sendMail( String recipients[ ], String subject, String message)
             throws MessagingException
              {
                boolean debug = false;

                 //Set the host smtp address

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

                // create some properties and get the default Session

                Session session = Session.getDefaultInstance(props, new Authenticator() {

                    protected PasswordAuthentication getPasswordAuthentication() {
                        return new PasswordAuthentication(
                                "username@gmail.com", "5373273437543");// Specify the Username and the PassWord
                    }

                });
                session.setDebug(debug);


                // create a message
                Message msg = new MimeMessage(session);


                InternetAddress[] addressTo = new InternetAddress[recipients.length];
                for (int i = 0; i < recipients.length; i++)
                {
                  addressTo[i] = new InternetAddress(recipients[i]);
                }

                msg.setRecipients(Message.RecipientType.TO, addressTo);

                // Optional : You can also set your custom headers  in the Email if you Want
                //msg.addHeader("MyHeaderName", "myHeaderValue");

                // Setting the Subject and Content Type
                msg.setSubject(subject);
                msg.setContent(message, "text/plain");

                //send message
                Transport.send(msg);

                System.out.println("Message Sent Successfully");
              }

}
0

Even when using an Authenticator I had to set mail.smtp.auth property to true. Here is a working example:

final Properties props = new Properties();
props.put("mail.smtp.host", config.getSmtpHost());
props.setProperty("mail.smtp.auth", "true");

Session session = Session.getDefaultInstance(props, new javax.mail.Authenticator()
{
  protected PasswordAuthentication getPasswordAuthentication()
  {
    return new PasswordAuthentication(config.getSmtpUser(), config.getSmtpPassword());
  }
});
alecswan
  • 3,670
  • 5
  • 25
  • 35
0

I also have this problem so don't worry. It comes from mail server side due to an outside authentication issue. Open your mail and you will get a mail from the mail server telling you to enable accessibility. When you have done that, retry your program.

i alarmed alien
  • 9,412
  • 3
  • 27
  • 40
  • The link(https://productforums.google.com/forum/#!topic/gmail/x_gAqixiJio) tells you to enable accessibility. And you can do that via (https://www.google.com/settings/security/lesssecureapps). This solves the problem. Else you have to go for 2-step authentication. –  Feb 13 '16 at 19:03
0

Turn On "Access for less secure apps" in Security setting for the gmail account.(from mail), see the below link for references

http://www.ghacks.net/2014/07/21/gmail-starts-block-less-secure-apps-enable-access/

Prabha
  • 266
  • 4
  • 25
0

This error may be about password characters. If your password contains special characters and also you add your password into Transport class methods;

For Example

Transport transport = session.getTransport("smtp");
transport.connect("user","passw@rd");

or

Transport.send(msg, "user", "passw%rd");

you may get that error. Because Transport class' methods may not handle special characters. If you add your username and password into your message using javax.mail.PasswordAuthentication class, i hope you will escape that error;

For Example

...
Session session = Session.getInstance(props, new javax.mail.Authenticator()
{
  protected PasswordAuthentication getPasswordAuthentication()
  {
    return new PasswordAuthentication("user", "pas$w@r|d");
  }
});

Message message = new MimeMessage(session);
...
Transport.send(message);
oguzhan
  • 2,073
  • 1
  • 26
  • 23
0

See the 9 line of your code,it may be an error; it should be:

mail.smtp.user 

not

mail.stmp.user;
Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135
bymysidel
  • 11
  • 1
-1

I have just faced this problem, and the solution is that the property "mail.smtp.user" should be your email (not username).

The example for gmail user:

properties.put("mail.smtp.starttls.enable", "true");
properties.put("mail.smtp.host", host);
properties.put("mail.smtp.user", from);
properties.put("mail.smtp.password", pass);
properties.put("mail.smtp.port", "587");
properties.put("mail.smtp.auth", "true");
Magnilex
  • 11,584
  • 9
  • 62
  • 84