tags:

views:

13504

answers:

10

I want to access messages in GMail from a Java application using JavaMail and IMAP. Why am I getting a SocketTimeoutException?

Here is my code:

Properties props = System.getProperties();
props.setProperty("mail.imap.host", "imap.gmail.com");
props.setProperty("mail.imap.port", "993");
props.setProperty("mail.imap.connectiontimeout", "5000");
props.setProperty("mail.imap.timeout", "5000");

try {
  Session session = Session.getDefaultInstance(props, new MyAuthenticator());
  URLName urlName = new URLName("imap://[email protected]:[email protected]");
  Store store = session.getStore(urlName);
  if (!store.isConnected()) {
    store.connect();
  }
} catch (NoSuchProviderException e) {
  e.printStackTrace();
  System.exit(1);
} catch (MessagingException e) {
  e.printStackTrace();
  System.exit(2);
}

I set the timeout values so that it wouldn't take "forever" to timeout. Also, MyAuthenticator also has the username and password, which seems redundant with the URL. Is there another way to specify the protocol? (I didn't see it in the JavaDoc for IMAP.)

+2  A: 

You have to connect to GMail using SSL only. Setting the following properties will force that for you.

props.setProperty("mail.imap.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.setProperty("mail.imap.socketFactory.fallback", "false");
bmatthews68
I don't recommend this approach in general, because it overrides _all_ imap connections to be imaps. Sometimes choice is a good thing, especially if the program is to be used for connecting to just Gmail.However, if you think plain IMAP is outright wrong, then this approach is acceptable. :-)
Chris Jester-Young
...used for connecting to _more than_ just Gmail, I meant. :-P
Chris Jester-Young
+2  A: 

In JavaMail, you can use imaps as the URL scheme to use IMAP over SSL. (See SSLNOTES.txt in your JavaMail distribution for more details.) For example, imaps://username%[email protected]/INBOX.

Similarly, use smtps to send emails via Gmail. e.g., smtps://username%[email protected]/. Again, read SSLNOTES.txt for more details. Hope it helps!

Chris Jester-Young
+14  A: 

Using imaps was a great suggestion. Neither of the answers provided just worked for me, so I googled some more and found something that worked. Here's how my code looks now.

Properties props = System.getProperties();
props.setProperty("mail.store.protocol", "imaps");
try {
  Session session = Session.getDefaultInstance(props, null);
  Store store = session.getStore("imaps");
  store.connect("imap.gmail.com", "<username>@gmail.com", "<password>");
  ...
} catch (NoSuchProviderException e) {
  e.printStackTrace();
  System.exit(1);
} catch (MessagingException e) {
  e.printStackTrace();
  System.exit(2);
}

This is nice because it takes the redundant Authenticator out of the picture. I'm glad this worked because the SSLNOTES.txt make my head spin.

Dave
A: 

Check http://g4j.sourceforge.net/. There is a minimal gmail client built using this API.

Adi
A: 

If you'd like more sample code on using JavaMail with Gmail (e.g. converting Gmail labels to IMAP folder names, or using IMAP IDLE), do check out my program GmailAssistant on SourceForge.

Zach Scrivena
A: 

URLName server = new URLName("imaps://:@imap.gmail.com/INBOX");

A: 

Thanks

Great help Dave

A: 

I used following properties to get the store and It works well.

"mail.imaps.host" : "imap.gmail.com"
"mail.store.protocol" : "imaps"
"mail.imaps.port" : "993"

Alex Cheng
A: 

I have a problems, when we run the program comming this error "Unable to locate provider for protocol: imaps"

roshan
A: 

roshan, you need to have JSSE installed to use SSL with Java