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

115,031

Solution 1

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));

Solution 2

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(
                "[email protected]", "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?

Solution 3

Your email session should be provided an authenticator instance as below

Session session = Session.getDefaultInstance(props,
    new Authenticator() {
        protected PasswordAuthentication  getPasswordAuthentication() {
        return new PasswordAuthentication(
                    "[email protected]", "password");
                }
    });

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

Solution 4

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! :)
  }
}

Solution 5

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;
}
Share:
115,031
Suhail Gupta
Author by

Suhail Gupta

"There's nothing more permanent than a temporary hack." - Kyle Simpson "The strength of JavaScript is that you can do anything. The weakness is that you will." - Reg Braithwaite I am on internet Twitter @suhail3 E-mail [email protected]

Updated on July 09, 2022

Comments

  • Suhail Gupta
    Suhail Gupta almost 2 years

    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 = "[email protected]";
            String from = "[email protected]";
            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?

  • Suhail Gupta
    Suhail Gupta almost 13 years
    I cannot understand that. Can you please include this in your answer
  • RMT
    RMT almost 13 years
    let me know if you need help i will try to help you out
  • Buhake Sindi
    Buhake Sindi almost 13 years
    @Suhail Gupta, I've already mentioned it on your previous question.
  • Suhail Gupta
    Suhail Gupta almost 13 years
    @ RMT this is my edited code after your answer Is that what you asked for ?
  • RMT
    RMT almost 13 years
    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
    RMT almost 13 years
    I edited my answer try using that instead of PasswordAuthentication
  • RMT
    RMT almost 13 years
    Errors when? compile or run time?
  • RMT
    RMT almost 13 years
    @SuhailGupta let us continue this discussion in chat
  • Suhail Gupta
    Suhail Gupta almost 13 years
    @ RMT OK...(durin compile time)
  • remi
    remi almost 11 years
    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.
  • Admin
    Admin over 8 years
    The link(productforums.google.com/forum/#!topic/gmail/x_gAqixiJi‌​o) tells you to enable accessibility. And you can do that via (google.com/settings/security/lesssecureapps). This solves the problem. Else you have to go for 2-step authentication.
  • Gagan Singh
    Gagan Singh almost 4 years
    After a lot of searching , yours is the only code that worked for me. Thanks!!!