Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7604825
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 31, 20262026-05-31T00:00:35+00:00 2026-05-31T00:00:35+00:00

I am currently trying to use JavaMail to get emails from IMAP servers (Gmail

  • 0

I am currently trying to use JavaMail to get emails from IMAP servers (Gmail and others). Basically, my code works: I indeed can get the headers, body contents and so on. My problem is the following: when working on an IMAP server (no SSL), it basically takes 1-2ms to process a message. When I go on an IMAPS server (hence with SSL, such as Gmail) I reach around 250m/message. I ONLY measure the time when processing the messages (the connection, handshake and such are NOT taken into account).

I know that since this is SSL, the data is encrypted. However, the time for decryption should not be that important, should it?

I have tried setting a higher ServerCacheSize value, a higher connectionpoolsize, but am seriously running out of ideas. Anyone confronted with this problem? Solved it one might hope?

My fear is that the JavaMail API uses a different connection each time it fetches a mail from the IMAPS server (involving the overhead for handshake…). If so, is there a way to override this behavior?

Here is my code (although quite standard) called from the Main() class:

 public static int connectTest(String SSL, String user, String pwd, String host) throws IOException,
                                                                               ProtocolException,
                                                                               GeneralSecurityException {

    Properties props = System.getProperties();
    props.setProperty("mail.store.protocol", SSL);
    props.setProperty("mail.imaps.ssl.trust", host);
    props.setProperty("mail.imaps.connectionpoolsize", "10");

    try {


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

        // session.setDebug(true);

        Store store = session.getStore(SSL);
        store.connect(host, user, pwd);      
        Folder inbox = store.getFolder("INBOX");

        inbox.open(Folder.READ_ONLY);                
        int numMess = inbox.getMessageCount();
        Message[] messages = inbox.getMessages();

        for (Message m : messages) {

            m.getAllHeaders();
            m.getContent();
        }

        inbox.close(false);
        store.close();
        return numMess;
    } catch (MessagingException e) {
        e.printStackTrace();
        System.exit(2);
    }
    return 0;
}

Thanks in advance.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-31T00:00:36+00:00Added an answer on May 31, 2026 at 12:00 am

    after a lot of work, and assistance from the people at JavaMail, the source of this “slowness” is from the FETCH behavior in the API. Indeed, as pjaol said, we return to the server each time we need info (a header, or message content) for a message.

    If FetchProfile allows us to bulk fetch header information, or flags, for many messages, getting contents of multiple messages is NOT directly possible.

    Luckily, we can write our own IMAP command to avoid this “limitation” (it was done this way to avoid out of memory errors: fetching every mail in memory in one command can be quite heavy).

    Here is my code:

    import com.sun.mail.iap.Argument;
    import com.sun.mail.iap.ProtocolException;
    import com.sun.mail.iap.Response;
    import com.sun.mail.imap.IMAPFolder;
    import com.sun.mail.imap.protocol.BODY;
    import com.sun.mail.imap.protocol.FetchResponse;
    import com.sun.mail.imap.protocol.IMAPProtocol;
    import com.sun.mail.imap.protocol.UID;
    
    public class CustomProtocolCommand implements IMAPFolder.ProtocolCommand {
        /** Index on server of first mail to fetch **/
        int start;
    
        /** Index on server of last mail to fetch **/
        int end;
    
        public CustomProtocolCommand(int start, int end) {
            this.start = start;
            this.end = end;
        }
    
        @Override
        public Object doCommand(IMAPProtocol protocol) throws ProtocolException {
            Argument args = new Argument();
            args.writeString(Integer.toString(start) + ":" + Integer.toString(end));
            args.writeString("BODY[]");
            Response[] r = protocol.command("FETCH", args);
            Response response = r[r.length - 1];
            if (response.isOK()) {
                Properties props = new Properties();
                props.setProperty("mail.store.protocol", "imap");
                props.setProperty("mail.mime.base64.ignoreerrors", "true");
                props.setProperty("mail.imap.partialfetch", "false");
                props.setProperty("mail.imaps.partialfetch", "false");
                Session session = Session.getInstance(props, null);
    
                FetchResponse fetch;
                BODY body;
                MimeMessage mm;
                ByteArrayInputStream is = null;
    
                // last response is only result summary: not contents
                for (int i = 0; i < r.length - 1; i++) {
                    if (r[i] instanceof IMAPResponse) {
                        fetch = (FetchResponse) r[i];
                        body = (BODY) fetch.getItem(0);
                        is = body.getByteArrayInputStream();
                        try {
                            mm = new MimeMessage(session, is);
                            Contents.getContents(mm, i);
                        } catch (MessagingException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
            // dispatch remaining untagged responses
            protocol.notifyResponseHandlers(r);
            protocol.handleResult(response);
    
            return "" + (r.length - 1);
        }
    }
    

    the getContents(MimeMessage mm, int i) function is a classic function that recursively prints the contents of the message to a file (many examples available on the net).

    To avoid out of memory errors, I simply set a maxDocs and maxSize limit (this has been done arbitrarily and can probably be improved!) used as follows:

    public int efficientGetContents(IMAPFolder inbox, Message[] messages)
            throws MessagingException {
        FetchProfile fp = new FetchProfile();
        fp.add(FetchProfile.Item.FLAGS);
        fp.add(FetchProfile.Item.ENVELOPE);
        inbox.fetch(messages, fp);
        int index = 0;
        int nbMessages = messages.length;
        final int maxDoc = 5000;
        final long maxSize = 100000000; // 100Mo
    
        // Message numbers limit to fetch
        int start;
        int end;
    
        while (index < nbMessages) {
            start = messages[index].getMessageNumber();
            int docs = 0;
            int totalSize = 0;
            boolean noskip = true; // There are no jumps in the message numbers
                                               // list
            boolean notend = true;
            // Until we reach one of the limits
            while (docs < maxDoc && totalSize < maxSize && noskip && notend) {
                docs++;
                totalSize += messages[index].getSize();
                index++;
                if (notend = (index < nbMessages)) {
                    noskip = (messages[index - 1].getMessageNumber() + 1 == messages[index]
                            .getMessageNumber());
                }
            }
    
            end = messages[index - 1].getMessageNumber();
            inbox.doCommand(new CustomProtocolCommand(start, end));
    
            System.out.println("Fetching contents for " + start + ":" + end);
            System.out.println("Size fetched = " + (totalSize / 1000000)
                    + " Mo");
    
        }
    
        return nbMessages;
    }
    

    Do not that here I am using message numbers, which is unstable (these change if messages are erased from the server). A better method would be to use UIDs! Then you would change the command from FETCH to UID FETCH.

    Hope this helps out!

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I am currently trying to use this gem http://github.com/pengwynn/linkedin . Everything works fine (i.e.
I'm currently trying to get a jQuery slider to use the percentage height of
I'm currently trying to use the core-plot library to graph some data I get
I'm currently trying to use the current session of a php web page from
I am currently trying to use Miles J plugin located here http://milesj.me/code/cakephp/uploader Although I
I am currently trying to use Eclipse to develop some code that I've been
I'm currently trying to use NHibernate.Search, but i need to get score for each
I'm currently trying to use a WPF component that makes use of Application.Current from
So i am currently trying to use the dir command from within my c:/
I am currently trying to use NAnt and CruiseControl.NET to manage various aspects of

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.