16

What is the problem with this code? Somehow it is getting in to an infinity loop at the line Transport.send(message); line, no error message, no exception, just maybe infinite loop (i don't know because i don't wait more than 5-10minute)

final String username = "<mail_name>";
final String password = "<password>";

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

Session session = Session.getInstance(props,
        new javax.mail.Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(username, password);
            }
        });

try {

    Message message = new MimeMessage(session);
    message.setFrom(new InternetAddress("<mail_from>@gmail.com"));
    message.setRecipients(Message.RecipientType.TO,
            InternetAddress.parse("<mail_to>@gmail.com"));
    message.setSubject("Test Subject");
    message.setText("Test");

    Transport.send(message);

    System.out.println("Done");

} catch (MessagingException e) {
    throw new RuntimeException(e);
}
czupe
  • 4,740
  • 7
  • 34
  • 52
  • I'd suggest adding a `catch (Exception e){}` after the `MessagingException`, to see if some other kind of exception is thrown. Also add a `finally` block. You could also add `log4j.xml` and set the `javax.mail` class to `DEBUG` to see what else could be going on. – Bizmarck Mar 24 '13 at 11:04
  • good hints, thanks! will test it – czupe Mar 24 '13 at 11:06
  • Unfortunately still waiting at the Transport.send(message) line... Somebody can validate this code correctness? – czupe Mar 24 '13 at 11:28

4 Answers4

20

Here I am giving some changes, that work fine for me:

Session session = Session.getInstance(props,null);

You instantiate message object as you did. And finally:

Transport transport = session.getTransport("smtp");
String mfrom = "yourGmailUsernameWithout@"// example laabidiraissi 
transport.connect("smtp.gmail.com", mfrom, "thepassword");
transport.sendMessage(message, message.getAllRecipients());

Edit, would you please give me a favor and copy/paste and try this example and show what it displays:

package com.test;

import java.util.Properties;

import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

import org.junit.Test;

public class EmailService {

@Test
public void test(){
    Properties props = System.getProperties();
    props.put("mail.smtp.starttls.enable", true); // added this line
    props.put("mail.smtp.host", "smtp.gmail.com");
    props.put("mail.smtp.user", "username");
    props.put("mail.smtp.password", "password");
    props.put("mail.smtp.port", "587");
    props.put("mail.smtp.auth", true);



    Session session = Session.getInstance(props,null);
    MimeMessage message = new MimeMessage(session);

    System.out.println("Port: "+session.getProperty("mail.smtp.port"));

    // Create the email addresses involved
    try {
        InternetAddress from = new InternetAddress("username");
        message.setSubject("Yes we can");
        message.setFrom(from);
        message.addRecipients(Message.RecipientType.TO, InternetAddress.parse("receivermail"));

        // Create a multi-part to combine the parts
        Multipart multipart = new MimeMultipart("alternative");

        // Create your text message part
        BodyPart messageBodyPart = new MimeBodyPart();
        messageBodyPart.setText("some text to send");

        // Add the text part to the multipart
        multipart.addBodyPart(messageBodyPart);

        // Create the html part
        messageBodyPart = new MimeBodyPart();
        String htmlMessage = "Our html text";
        messageBodyPart.setContent(htmlMessage, "text/html");


        // Add html part to multi part
        multipart.addBodyPart(messageBodyPart);

        // Associate multi-part with message
        message.setContent(multipart);

        // Send message
        Transport transport = session.getTransport("smtp");
        transport.connect("smtp.gmail.com", "username", "password");
        System.out.println("Transport: "+transport.toString());
        transport.sendMessage(message, message.getAllRecipients());


    } catch (AddressException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (MessagingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
}
Laabidi Raissi
  • 3,263
  • 1
  • 22
  • 28
  • thanks, but mail.smtp.auth property is already there... And i've tried with the other port also. – czupe Mar 24 '13 at 12:07
  • ah sorry for the auth property, it's my fault, i didn't see it. – Laabidi Raissi Mar 24 '13 at 12:09
  • if if try with 25 or 587 ports, anyway check for your solution... Exception in thread "main" java.lang.RuntimeException: javax.mail.MessagingException: Could not connect to SMTP host: smtp.gmail.com, port: 25; nested exception is: java.net.ConnectException: Connection refused: connect – czupe Mar 24 '13 at 12:23
  • still the same exception, can it be that my network configuration is not proper? – czupe Mar 24 '13 at 12:27
  • good news at last, we've got some exception. your exception is classic: http://stackoverflow.com/questions/7158951/javax-mail-messagingexception-could-not-connect-to-smtp-host-smtp-gmail-com-p – Laabidi Raissi Mar 24 '13 at 12:27
  • Did you check your firewall ? does the 587 port give you this same exception ? – Laabidi Raissi Mar 24 '13 at 12:33
  • yes, i seriously think it will be a firewall issue, minute i will check... I think that because Putty still not connect to the IP and port Windows firewall is OFF : / and same... – czupe Mar 24 '13 at 12:34
  • what about ping smtp.gmail.com – Laabidi Raissi Mar 24 '13 at 12:48
  • It's OK. I have a fkn bad feeling, that my network provider just prohobited the 25 port... Any solution/idea about this?;( – czupe Mar 24 '13 at 12:52
  • anyway thank you for your help and work, i think it cannot be fixed, or i dont know how... I've upvoted. – czupe Mar 24 '13 at 13:06
  • what drives me crazy, is that the exception is talking about port 25, while we are using port 587. – Laabidi Raissi Mar 24 '13 at 13:11
  • would you please give me a favor and copy/paste and try this example and show what it displays (see edited answer) – Laabidi Raissi Mar 24 '13 at 13:55
  • ok, sorry, i am here, i will check now your solution, maybe... Because in the meantime i configured outluck and it can connect to gmail, so i dont really understand what's going on : / – czupe Mar 24 '13 at 16:19
  • It seems it is working, but had no time to saw it more deeply, what is the difference of the two code, weird, anyway thank you for your stubborness:) It would be good if i can understand it in fully... I will take time with it:) – czupe Mar 24 '13 at 17:37
  • That is really weird, one of my computer can connect to smtp, the other cannot... :/:/:/ – czupe Mar 24 '13 at 21:45
  • that must be some firewall settings, try to search for windows firewalls – Laabidi Raissi Mar 24 '13 at 21:46
3

Ok. It is a little more complex than i tought for the first time... To summorize what i got:

  • There is a very useful command: session.setDebug(true);. If you set this true, every important process will be debuged to the console. I recommend to use it.
  • The second computer could only work with the secure option, you can switch this one with: Transport transport = session.getTransport("smtps"); rather of the non secure smtp... The JavaMail API Transport object will also take care of the ports (respectively smtp: 587, smtps: 465)
  • You can use also the static method of the Transport class for sending the message and (saving it before, non static sendMessage method will not save the message), but this time you need to use the javax.mail.Authenticator at the session creation, like this:

    Session session = Session.getInstance(props,         new javax.mail.Authenticator() {
        protected PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication("login", "password");
        }
    

    });

1.4.2 JavaMailApi has another Exception than 1.4.7 version for this issue...

If you don't use it, you can not authenticated with the static method. If you use the instance method, you can.

  • One computer has maven and got the 1.4.2 version of the JavaMail API. Second computer has a downloaded library, with version 1.4.7, which i guess also mess with the things
  • First comp Netbeans, second comp Intellij... +1) There are a lot of old, and bad example code at the internet, which makes harder to use this API properly.

So pretty messed up, but there were some basic concept which should be focused...

czupe
  • 4,740
  • 7
  • 34
  • 52
1

I could reproduce the behaviour described in your question and fix it.

The send method gets stuck at

SMTPTransport(Service).connect(String, int, String, String) line: 308   

The connection does not succeed because you have the wrong port for the gmail smtp host: 465

change it to 587

props.put("mail.smtp.port", "587");

and it will work.

A4L
  • 17,353
  • 6
  • 49
  • 70
  • yeah, dont know why i rode the 465 port, but anyway, it is still not working : ( – czupe Mar 24 '13 at 12:33
  • what exception/error are you getting now ? is your java.exe allowed through the firewall ? – A4L Mar 24 '13 at 12:40
  • This:java.lang.RuntimeException: javax.mail.MessagingException: Could not connect to SMTP host: smtp.gmail.com, port: 25; nested exception is: java.net.ConnectException: Connection refused: connect I shuted down the whole windows firewall.. – czupe Mar 24 '13 at 12:45
  • It seems that your application does not support SSL. `smtp.gmail.com` requires a secure connection, otherwise you'll have to choose another host, [see google support page](http://support.google.com/a/bin/answer.py?hl=en&answer=176600). You probably need to specify it explicitly by acquiring a `Transport` instance that supports the the secure protocol `smtps` and use it to send your message. Please refer to [accepted answer for this question](http://stackoverflow.com/questions/1990454/using-javamail-to-connect-to-gmail-smtp-server-ignores-specified-port-and-tries) – A4L Mar 24 '13 at 13:27
1

Using Simple Java Mail it should be straightforward:

Email email = new Email();

email.setFromAddress("lollypop", "lol.pop@somemail.com");
email.addRecipient("C.Cane", "candycane@candyshop.org", RecipientType.TO);
email.setText("We should meet up!");
email.setTextHTML("<b>We should meet up!</b>");
email.setSubject("hey");

new Mailer("smtp.gmail.com", 25, "your user", "your password", TransportStrategy.SMTP_TLS).sendMail(email);
new Mailer("smtp.gmail.com", 587, "your user", "your password", TransportStrategy.SMTP_TLS).sendMail(email);
new Mailer("smtp.gmail.com", 465, "your user", "your password", TransportStrategy.SMTP_SSL).sendMail(email);

If you have two-factor login turned on, you need to generate an application specific password from your Google account.

Benny Bottema
  • 11,111
  • 10
  • 71
  • 96