26

I am trying to access emails from Gmail accounts through IMAP with the help of the JavaMail API. I was wondering why the code works for one email account but doesn't work for another.

I am able to access the Inbox folder of both email accounts. But for one of the email accounts, other folders like SPAM([Gmail]/Spam) are not able to be accessed and it throws a FolderNotFoundException exception. Could anybody please explain what is going wrong?

Thank you in advance.

Here is the code:

import java.io.*;
import java.util.*;
import javax.mail.*;
import javax.mail.Flags.Flag;
import javax.mail.internet.*;

import com.sun.mail.imap.IMAPFolder;
import com.sun.mail.imap.IMAPMessage;


public class FolderFetchIMAP {


    public static void main(String[] args) throws MessagingException, IOException {
        IMAPFolder folder = null;
        Store store = null;
        String subject = null;
        Flag flag = null;
        try 
        {
          Properties props = System.getProperties();
          props.setProperty("mail.store.protocol", "imaps");

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

          store = session.getStore("imaps");
          store.connect("imap.googlemail.com","myemailid@gmail.com", "password");

          folder = (IMAPFolder) store.getFolder("[Gmail]/Spam"); // This doesn't work for other email account
          //folder = (IMAPFolder) store.getFolder("inbox"); This works for both email account


          if(!folder.isOpen())
          folder.open(Folder.READ_WRITE);
          Message[] messages = folder.getMessages();
          System.out.println("No of Messages : " + folder.getMessageCount());
          System.out.println("No of Unread Messages : " + folder.getUnreadMessageCount());
          System.out.println(messages.length);
          for (int i=0; i < messages.length;i++) 
          {

            System.out.println("*****************************************************************************");
            System.out.println("MESSAGE " + (i + 1) + ":");
            Message msg =  messages[i];
            //System.out.println(msg.getMessageNumber());
            //Object String;
            //System.out.println(folder.getUID(msg)

            subject = msg.getSubject();

            System.out.println("Subject: " + subject);
            System.out.println("From: " + msg.getFrom()[0]);
           System.out.println("To: "+msg.getAllRecipients()[0]);
            System.out.println("Date: "+msg.getReceivedDate());
            System.out.println("Size: "+msg.getSize());
            System.out.println(msg.getFlags());
            System.out.println("Body: \n"+ msg.getContent());
            System.out.println(msg.getContentType());

          }
        }
        finally 
        {
          if (folder != null && folder.isOpen()) { folder.close(true); }
          if (store != null) { store.close(); }
        }

    }



}
Moshe
  • 9,283
  • 4
  • 29
  • 38
Ragini
  • 1,509
  • 7
  • 28
  • 42

5 Answers5

14

Is one of the accounts using non-english UI by any chance?

Gmail folder names are localized with respect to the user localization settings.

Currently the only way to get the name of the localized folder is by using XLIST command.

Pawel Lesnikowski
  • 6,264
  • 4
  • 38
  • 42
  • @ Pawel Lesnikowski Could u please elaborate what is XLIST command and how can I use it to get localized folder name ? Thanks.. – Ragini Feb 14 '12 at 14:19
  • XLIST is one of the extensions added to IMAP protocol by Google. It is very similar to the LIST command. It's response includes additional flags, that allow client to identify the intended purpose of the folder. You can find a sample response here: http://www.limilabs.com/blog/localized-gmail-imap-folders I'm not a Java dev, so I can't show you how to issue this command using java.mail – Pawel Lesnikowski Feb 14 '12 at 15:19
  • @ Pawel Lesnikowski Thanks again..The link u provided is relly very useful..I got correct foldernames and they work fine... – Ragini Feb 14 '12 at 18:01
  • 2
    For information, http://code.google.com/p/java-gmail-imap/ is an extended version of JavaMail targetted at Gmail and includes XLIST support. – Mark McLaren Jun 14 '12 at 09:45
  • 4
    XLIST is actually now deprecated and google suggests that you use the LIST command instead... – ekawas May 30 '13 at 16:22
  • @ekawas Unfortunately Gmail doesn't support LIST SPECIAL-USE correctly: http://www.limilabs.com/blog/gmail-special-use-capability-is-broken. XLIST is still advertised and supported by Gmail server. – Pawel Lesnikowski May 31 '13 at 15:57
  • You're right, it will work now, but accoding to Gmail Apis page, its deprecated ... https://developers.google.com/gmail/imap_extensions#xlist_is_deprecated – ekawas Jun 03 '13 at 02:56
  • How can I use this XLIST cmd to fetch folder names from my android app ? – Napolean Jun 19 '13 at 11:14
6
package com.technicalkeeda;

import java.io.File;
import java.io.FileInputStream;
import java.util.Properties;

import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Store;

public class GmailInbox {

 public static void main(String[] args) {
  GmailInbox gmail = new GmailInbox();
  gmail.read();
 }

 public void read() {
  Properties props = new Properties();
  try {
   props.load(new FileInputStream(new File("C:\\smtp.properties")));
   Session session = Session.getDefaultInstance(props, null);

   Store store = session.getStore("imaps");
   store.connect("smtp.gmail.com", "*************@gmail.com","your_password");

   Folder inbox = store.getFolder("inbox");
   inbox.open(Folder.READ_ONLY);
   int messageCount = inbox.getMessageCount();

   System.out.println("Total Messages:- " + messageCount);

   Message[] messages = inbox.getMessages();
   System.out.println("------------------------------");
   for (int i = 0; i < 10; i++) {
      System.out.println("Mail Subject:- " + messages[i].getSubject());      
   }
   inbox.close(true);
   store.close();

  } catch (Exception e) {
   e.printStackTrace();
  }
 }

}
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Vicky
  • 9,515
  • 16
  • 71
  • 88
3

You can try the following code:

private List<String> getResult1(){
  try {
    Properties props = new Properties();
    props.put("mail.store.protocol","imaps");
    Session session = Session.getDefaultInstance(props, null);
    Store store = session.getStore("imaps");
    store.connect("imap.gmail.com", "Email Id", "App Password");

    //if you want mail from specified folder, just change change folder name
    //Folder inbox = store.getFolder("[Gmail]/Drafts");
    Folder inbox = store.getFolder("inbox");

    inbox.open(Folder.READ_ONLY);
    int messageCount = inbox.getMessageCount();
    Log.e("getFolder ", "getResult1: " + store.getDefaultFolder().list("*"));
    javax.mail.Folder[] folders = store.getDefaultFolder().list("*");

    for (javax.mail.Folder folder : folders) {
      if ((folder.getType() & javax.mail.Folder.HOLDS_MESSAGES) != 0){
        Log.e("getFolder ", "getResult1: " + folder.getName() );
      }
    }

    Log.e("Mail Subject:", "Total Messages:-: " + messageCount );
    javax.mail.Message[] messages = inbox.getMessages();

    System.out.println("------------------------------");
    Log.e("Mail Subject:", "messages: " + messages.toString());
    for (int i = 0; i < messages.length; i++) {
      Log.e("Mail Subject:", "getResult1: " + messages[i].getSubject());
    }
    inbox.close(true);
    store.close();
  } catch (Exception e) {
    e.printStackTrace();
  }
  return null;
}
CR Drost
  • 9,637
  • 1
  • 25
  • 36
1

Im unsure if this helps, but I've seen instances where gmail accounts have different mailboxes ie..

Gmail Account 1 :-

[[Google Mail]]
[[Google Mail]/All Mail]
[[Google Mail]/Bin]
[[Google Mail]/Drafts]
[[Google Mail]/Important]
[[Google Mail]/Sent Mail]
[[Google Mail]/Spam]
[[Google Mail]/Starred]

Gmail Account 2 :-

[[Gmail]]
[[Gmail]/All Mail]
[[Gmail]/Bin]
[[Gmail]/Drafts]
[[Gmail]/Important]
[[Gmail]/Sent Mail]
[[Gmail]/Spam]
[[Gmail]/Starred]
rams59
  • 23
  • 6
1

It works this way (It looks like it doesn't work with POP3, but it works with IMAP):

     Properties props = new Properties();
     props.put("mail.store.protocol", "imaps");
     Session session = Session.getDefaultInstance(props, null);
     Store store = session.getStore("imaps");
     store.connect("imap.gmail.com", [theMailAccount@gmail.com], [thePasswordOrAppPassword]);

     // You possibly will have to use [Google Mail]/All Mail instead
     Folder inbox = store.getFolder("[Gmail]/All Mail");
Dan Ortega
  • 1,679
  • 17
  • 13