How to Send bulk mails using javax.mail API efficiently? & Can we use reuse authenticated sessions to...











up vote
15
down vote

favorite
6












I am able to send a mail using javax.mail API. But the problem here is on an average for each mail it taking around 4.3 seconds to send to destination.



If I am sending a 20 mails sequentially, it takes around 86.599 seconds. For my requirement this approach will not work. I am looking for an approach which can send large number of mails in less time.



When I looked at the debug log, the API is trying to authenticate to SMTP server for each and every message it sending. But I am creating a session only one time and using the same session for all the mails I am sending. Now my question is Isn't it a overhead process every time authenticating itself to the smtp server. Isn't there a better approach ?



Below is the log trace you may find helpful.



250-AUTH LOGIN PLAIN XOAUTH XOAUTH2
250 ENHANCEDSTATUSCODES
DEBUG SMTP: Found extension "SIZE", arg "35882577"
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "AUTH", arg "LOGIN PLAIN XOAUTH XOAUTH2"
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Attempt to authenticate
DEBUG SMTP: check mechanisms: LOGIN PLAIN DIGEST-MD5 NTLM
DEBUG SMTP: AUTH LOGIN command trace suppressed
DEBUG SMTP: AUTH LOGIN succeeded


Please let me know your thoughts on this and any help on this is really appreciated.



-Narendra










share|improve this question
























  • what is your java code?
    – Nikolay Kuznetsov
    Nov 8 '12 at 10:53










  • send bulk email by exploitating sendmail.
    – Roman C
    Nov 8 '12 at 11:00










  • sorry I can't share my code here and I can't use sendmail .
    – Narendra
    Nov 8 '12 at 11:07















up vote
15
down vote

favorite
6












I am able to send a mail using javax.mail API. But the problem here is on an average for each mail it taking around 4.3 seconds to send to destination.



If I am sending a 20 mails sequentially, it takes around 86.599 seconds. For my requirement this approach will not work. I am looking for an approach which can send large number of mails in less time.



When I looked at the debug log, the API is trying to authenticate to SMTP server for each and every message it sending. But I am creating a session only one time and using the same session for all the mails I am sending. Now my question is Isn't it a overhead process every time authenticating itself to the smtp server. Isn't there a better approach ?



Below is the log trace you may find helpful.



250-AUTH LOGIN PLAIN XOAUTH XOAUTH2
250 ENHANCEDSTATUSCODES
DEBUG SMTP: Found extension "SIZE", arg "35882577"
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "AUTH", arg "LOGIN PLAIN XOAUTH XOAUTH2"
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Attempt to authenticate
DEBUG SMTP: check mechanisms: LOGIN PLAIN DIGEST-MD5 NTLM
DEBUG SMTP: AUTH LOGIN command trace suppressed
DEBUG SMTP: AUTH LOGIN succeeded


Please let me know your thoughts on this and any help on this is really appreciated.



-Narendra










share|improve this question
























  • what is your java code?
    – Nikolay Kuznetsov
    Nov 8 '12 at 10:53










  • send bulk email by exploitating sendmail.
    – Roman C
    Nov 8 '12 at 11:00










  • sorry I can't share my code here and I can't use sendmail .
    – Narendra
    Nov 8 '12 at 11:07













up vote
15
down vote

favorite
6









up vote
15
down vote

favorite
6






6





I am able to send a mail using javax.mail API. But the problem here is on an average for each mail it taking around 4.3 seconds to send to destination.



If I am sending a 20 mails sequentially, it takes around 86.599 seconds. For my requirement this approach will not work. I am looking for an approach which can send large number of mails in less time.



When I looked at the debug log, the API is trying to authenticate to SMTP server for each and every message it sending. But I am creating a session only one time and using the same session for all the mails I am sending. Now my question is Isn't it a overhead process every time authenticating itself to the smtp server. Isn't there a better approach ?



Below is the log trace you may find helpful.



250-AUTH LOGIN PLAIN XOAUTH XOAUTH2
250 ENHANCEDSTATUSCODES
DEBUG SMTP: Found extension "SIZE", arg "35882577"
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "AUTH", arg "LOGIN PLAIN XOAUTH XOAUTH2"
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Attempt to authenticate
DEBUG SMTP: check mechanisms: LOGIN PLAIN DIGEST-MD5 NTLM
DEBUG SMTP: AUTH LOGIN command trace suppressed
DEBUG SMTP: AUTH LOGIN succeeded


Please let me know your thoughts on this and any help on this is really appreciated.



-Narendra










share|improve this question















I am able to send a mail using javax.mail API. But the problem here is on an average for each mail it taking around 4.3 seconds to send to destination.



If I am sending a 20 mails sequentially, it takes around 86.599 seconds. For my requirement this approach will not work. I am looking for an approach which can send large number of mails in less time.



When I looked at the debug log, the API is trying to authenticate to SMTP server for each and every message it sending. But I am creating a session only one time and using the same session for all the mails I am sending. Now my question is Isn't it a overhead process every time authenticating itself to the smtp server. Isn't there a better approach ?



Below is the log trace you may find helpful.



250-AUTH LOGIN PLAIN XOAUTH XOAUTH2
250 ENHANCEDSTATUSCODES
DEBUG SMTP: Found extension "SIZE", arg "35882577"
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "AUTH", arg "LOGIN PLAIN XOAUTH XOAUTH2"
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Attempt to authenticate
DEBUG SMTP: check mechanisms: LOGIN PLAIN DIGEST-MD5 NTLM
DEBUG SMTP: AUTH LOGIN command trace suppressed
DEBUG SMTP: AUTH LOGIN succeeded


Please let me know your thoughts on this and any help on this is really appreciated.



-Narendra







java email smtp javamail






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 13 '17 at 10:10









svarog

5,45533856




5,45533856










asked Nov 8 '12 at 10:48









Narendra

2,34093049




2,34093049












  • what is your java code?
    – Nikolay Kuznetsov
    Nov 8 '12 at 10:53










  • send bulk email by exploitating sendmail.
    – Roman C
    Nov 8 '12 at 11:00










  • sorry I can't share my code here and I can't use sendmail .
    – Narendra
    Nov 8 '12 at 11:07


















  • what is your java code?
    – Nikolay Kuznetsov
    Nov 8 '12 at 10:53










  • send bulk email by exploitating sendmail.
    – Roman C
    Nov 8 '12 at 11:00










  • sorry I can't share my code here and I can't use sendmail .
    – Narendra
    Nov 8 '12 at 11:07
















what is your java code?
– Nikolay Kuznetsov
Nov 8 '12 at 10:53




what is your java code?
– Nikolay Kuznetsov
Nov 8 '12 at 10:53












send bulk email by exploitating sendmail.
– Roman C
Nov 8 '12 at 11:00




send bulk email by exploitating sendmail.
– Roman C
Nov 8 '12 at 11:00












sorry I can't share my code here and I can't use sendmail .
– Narendra
Nov 8 '12 at 11:07




sorry I can't share my code here and I can't use sendmail .
– Narendra
Nov 8 '12 at 11:07












4 Answers
4






active

oldest

votes

















up vote
24
down vote



accepted










How are you sending the messages? The JavaMail FAQ suggests that the static Transport.send method will open a fresh connection for each message, as it is a convenience method that creates a suitable Transport instance, connects it, calls sendMessage and then closes the connection again. If you get your own Transport instance from the Session you can connect once, then call sendMessage repeatedly to send several messages on the one connection, and finally close it. Something along the lines of (untested):



Transport t = session.getTransport();
t.connect();
try {
for(Message m : messages) {
m.saveChanges();
t.sendMessage(m, m.getAllRecipients());
}
} finally {
t.close();
}





share|improve this answer























  • Thanks for your answer. Curently I am using Transport.send(). I will test my code with session.getTransport().sendMessage(message, addressarray);
    – Narendra
    Nov 8 '12 at 12:07










  • @Narendra it's not quite as simple as that, but I've edited my answer with a more detailed example.
    – Ian Roberts
    Nov 8 '12 at 12:13










  • Thanks for your code snippet. I tried my code with sendMessage method and now the time for sending mails is reduced to half the time when compared to using send(). However I have one question here that is: what is the use of savechanges()? Calling savechanges is expensive right? and in what cased we should call this? Please let me know.
    – Narendra
    Nov 8 '12 at 14:34












  • @Narendra I just put it in to show the minimal change from the static send method if you want to batch several messages over one connection. The static send calls saveChanges on the message before sending it, you may be able to avoid that in your case if you know your message headers are already up to date.
    – Ian Roberts
    Nov 8 '12 at 15:36






  • 1




    @Ian Roberts , i am just clarifying, in your answer does it mean that multiple email addresses are associated with multiple Message objects? And inside for loop, each Message obj's recipient address is taken individually each time? Please suggest
    – Nishi Bangar
    Dec 16 '15 at 7:32




















up vote
11
down vote













I got the same requirement at work. I must send bulk emails and standalone email. I do not find simple and satisfactory answer: bulk emails can be sent using a single connection but standalone email cannot until I create an asynchronous buffering to send emails in batch.



Last but not least, using a lot of Transport connection in a short time can lead to a no more socket handles are available because all ports are stuck in the TIME_WAIT state.



I finally conclude the best will be an SMTP connection pool and because no library exists (at least free) I create mine using Apache Common Pool and Java Mail:



//Declare the factory and the connection pool, usually at the application startup
SmtpConnectionPool smtpConnectionPool = new SmtpConnectionPool(SmtpConnectionFactoryBuilder.newSmtpBuilder().build());

//borrow an object in a try-with-resource statement or call `close` by yourself
try (ClosableSmtpConnection transport = smtpConnectionPool.borrowObject()) {
MimeMessage mimeMessage = new MimeMessage(session);
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, false);
mimeMessageHelper.addTo("to@example.com");
mimeMessageHelper.setFrom("from@example.com");
mimeMessageHelper.setSubject("Hi!");
mimeMessageHelper.setText("Hello World!", false);
transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
}

//Close the pool, usually when the application shutdown
smtpConnectionPool.close();





share|improve this answer





















  • How long do the connections last? Suppose I have different sessions assigned for different 'from' organizational addresses (some are auth , some not, some different host)? Is it safe to assume that all are smtp? What about password, can it be made to use the session authenticator instead of requiring the username and password in the build stage?
    – The Coordinator
    Jun 3 '15 at 4:29










  • The connection last the duration you have configured. About authentication, the SmtpConnectionFactoryBuilder#session can take an Authenticator. Different hosts will require different connection pool. When you write different session, you mean Transport?
    – Nicolas Labrot
    Jun 3 '15 at 10:33










  • We have different SMTP hosts depending on the from address of the email. And different authentic too even for the same host depending on what msexchange account is being used.
    – The Coordinator
    Jun 3 '15 at 16:59


















up vote
1
down vote













No idea if the standard Java mail API allows what you are trying to accomplish (session reuse), but you may consider using multi-threading:



I would use a ThreadPool and submit mail send jobs to it. Then you do any error handling / resending within the job class code, which is executed by the ThreadPool asynchronously, and your main thread can resume to do other things. Submitting a job will only take milliseconds. It been a while since I implemented something with thread pools in Java, but I remember it was fairly easy and straightforward. If you Google "Java ThreadPool" you find plenty of material.






share|improve this answer





















  • Hi FelixD, Thanks for your answer. I am mainly looking for session reuse bcz authenticating every time is a overhead process. My main goal here is to reduce the time taken for sending mail from 4seconds to around 1 second. You suggested using theads, but it will not improve the time taken for sending mail from src system to destination.
    – Narendra
    Nov 8 '12 at 11:11










  • Hi Narenda, no worries and thanks for your comment. I see your point - unfortunately I can't really help with more advanced use of the Java mail API, I have only done the simple sending with it. I hope my suggestion with multi-threading might be helpful for others though, as there are situations where this solves the issue (e.g. when mail sending is keeping your main app busy too long etc). Of course the load on the mail server on the other end also does not get less by my approach...
    – FelixD
    Nov 8 '12 at 12:49










  • Thanks FelixD for your reply. As Ian Robert suggested in above answer, using sendMessage is useful for my scenario and it reducing time for mail delivery as it reusing the existing session object. But implementing it is a not an easy task as Ian Robert told.
    – Narendra
    Nov 8 '12 at 14:39










  • You're right. I hadn't noticed Ian Robert's reply when I wrote the last comment. What he writes looks interesting, maybe I'll need that some time as well. :)
    – FelixD
    Nov 8 '12 at 16:11


















up vote
0
down vote













You can use Thread pooling as it gives very good performance.I have implemented and sharing you the below code snippet.



try  {
ExecutorService executor = Executors.newFixedThreadPool("no. of threads"); // no. of threads is depend on your cpu/memory usage it's better to test with diff. no. of threads.
Runnable worker = new MyRunnable(message); // message is the javax.mail.Message
executor.execute(worker);
executor.shutdown();
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
}





share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














     

    draft saved


    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f13287515%2fhow-to-send-bulk-mails-using-javax-mail-api-efficiently-can-we-use-reuse-auth%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    4 Answers
    4






    active

    oldest

    votes








    4 Answers
    4






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    24
    down vote



    accepted










    How are you sending the messages? The JavaMail FAQ suggests that the static Transport.send method will open a fresh connection for each message, as it is a convenience method that creates a suitable Transport instance, connects it, calls sendMessage and then closes the connection again. If you get your own Transport instance from the Session you can connect once, then call sendMessage repeatedly to send several messages on the one connection, and finally close it. Something along the lines of (untested):



    Transport t = session.getTransport();
    t.connect();
    try {
    for(Message m : messages) {
    m.saveChanges();
    t.sendMessage(m, m.getAllRecipients());
    }
    } finally {
    t.close();
    }





    share|improve this answer























    • Thanks for your answer. Curently I am using Transport.send(). I will test my code with session.getTransport().sendMessage(message, addressarray);
      – Narendra
      Nov 8 '12 at 12:07










    • @Narendra it's not quite as simple as that, but I've edited my answer with a more detailed example.
      – Ian Roberts
      Nov 8 '12 at 12:13










    • Thanks for your code snippet. I tried my code with sendMessage method and now the time for sending mails is reduced to half the time when compared to using send(). However I have one question here that is: what is the use of savechanges()? Calling savechanges is expensive right? and in what cased we should call this? Please let me know.
      – Narendra
      Nov 8 '12 at 14:34












    • @Narendra I just put it in to show the minimal change from the static send method if you want to batch several messages over one connection. The static send calls saveChanges on the message before sending it, you may be able to avoid that in your case if you know your message headers are already up to date.
      – Ian Roberts
      Nov 8 '12 at 15:36






    • 1




      @Ian Roberts , i am just clarifying, in your answer does it mean that multiple email addresses are associated with multiple Message objects? And inside for loop, each Message obj's recipient address is taken individually each time? Please suggest
      – Nishi Bangar
      Dec 16 '15 at 7:32

















    up vote
    24
    down vote



    accepted










    How are you sending the messages? The JavaMail FAQ suggests that the static Transport.send method will open a fresh connection for each message, as it is a convenience method that creates a suitable Transport instance, connects it, calls sendMessage and then closes the connection again. If you get your own Transport instance from the Session you can connect once, then call sendMessage repeatedly to send several messages on the one connection, and finally close it. Something along the lines of (untested):



    Transport t = session.getTransport();
    t.connect();
    try {
    for(Message m : messages) {
    m.saveChanges();
    t.sendMessage(m, m.getAllRecipients());
    }
    } finally {
    t.close();
    }





    share|improve this answer























    • Thanks for your answer. Curently I am using Transport.send(). I will test my code with session.getTransport().sendMessage(message, addressarray);
      – Narendra
      Nov 8 '12 at 12:07










    • @Narendra it's not quite as simple as that, but I've edited my answer with a more detailed example.
      – Ian Roberts
      Nov 8 '12 at 12:13










    • Thanks for your code snippet. I tried my code with sendMessage method and now the time for sending mails is reduced to half the time when compared to using send(). However I have one question here that is: what is the use of savechanges()? Calling savechanges is expensive right? and in what cased we should call this? Please let me know.
      – Narendra
      Nov 8 '12 at 14:34












    • @Narendra I just put it in to show the minimal change from the static send method if you want to batch several messages over one connection. The static send calls saveChanges on the message before sending it, you may be able to avoid that in your case if you know your message headers are already up to date.
      – Ian Roberts
      Nov 8 '12 at 15:36






    • 1




      @Ian Roberts , i am just clarifying, in your answer does it mean that multiple email addresses are associated with multiple Message objects? And inside for loop, each Message obj's recipient address is taken individually each time? Please suggest
      – Nishi Bangar
      Dec 16 '15 at 7:32















    up vote
    24
    down vote



    accepted







    up vote
    24
    down vote



    accepted






    How are you sending the messages? The JavaMail FAQ suggests that the static Transport.send method will open a fresh connection for each message, as it is a convenience method that creates a suitable Transport instance, connects it, calls sendMessage and then closes the connection again. If you get your own Transport instance from the Session you can connect once, then call sendMessage repeatedly to send several messages on the one connection, and finally close it. Something along the lines of (untested):



    Transport t = session.getTransport();
    t.connect();
    try {
    for(Message m : messages) {
    m.saveChanges();
    t.sendMessage(m, m.getAllRecipients());
    }
    } finally {
    t.close();
    }





    share|improve this answer














    How are you sending the messages? The JavaMail FAQ suggests that the static Transport.send method will open a fresh connection for each message, as it is a convenience method that creates a suitable Transport instance, connects it, calls sendMessage and then closes the connection again. If you get your own Transport instance from the Session you can connect once, then call sendMessage repeatedly to send several messages on the one connection, and finally close it. Something along the lines of (untested):



    Transport t = session.getTransport();
    t.connect();
    try {
    for(Message m : messages) {
    m.saveChanges();
    t.sendMessage(m, m.getAllRecipients());
    }
    } finally {
    t.close();
    }






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 8 '12 at 12:11

























    answered Nov 8 '12 at 11:34









    Ian Roberts

    103k11130148




    103k11130148












    • Thanks for your answer. Curently I am using Transport.send(). I will test my code with session.getTransport().sendMessage(message, addressarray);
      – Narendra
      Nov 8 '12 at 12:07










    • @Narendra it's not quite as simple as that, but I've edited my answer with a more detailed example.
      – Ian Roberts
      Nov 8 '12 at 12:13










    • Thanks for your code snippet. I tried my code with sendMessage method and now the time for sending mails is reduced to half the time when compared to using send(). However I have one question here that is: what is the use of savechanges()? Calling savechanges is expensive right? and in what cased we should call this? Please let me know.
      – Narendra
      Nov 8 '12 at 14:34












    • @Narendra I just put it in to show the minimal change from the static send method if you want to batch several messages over one connection. The static send calls saveChanges on the message before sending it, you may be able to avoid that in your case if you know your message headers are already up to date.
      – Ian Roberts
      Nov 8 '12 at 15:36






    • 1




      @Ian Roberts , i am just clarifying, in your answer does it mean that multiple email addresses are associated with multiple Message objects? And inside for loop, each Message obj's recipient address is taken individually each time? Please suggest
      – Nishi Bangar
      Dec 16 '15 at 7:32




















    • Thanks for your answer. Curently I am using Transport.send(). I will test my code with session.getTransport().sendMessage(message, addressarray);
      – Narendra
      Nov 8 '12 at 12:07










    • @Narendra it's not quite as simple as that, but I've edited my answer with a more detailed example.
      – Ian Roberts
      Nov 8 '12 at 12:13










    • Thanks for your code snippet. I tried my code with sendMessage method and now the time for sending mails is reduced to half the time when compared to using send(). However I have one question here that is: what is the use of savechanges()? Calling savechanges is expensive right? and in what cased we should call this? Please let me know.
      – Narendra
      Nov 8 '12 at 14:34












    • @Narendra I just put it in to show the minimal change from the static send method if you want to batch several messages over one connection. The static send calls saveChanges on the message before sending it, you may be able to avoid that in your case if you know your message headers are already up to date.
      – Ian Roberts
      Nov 8 '12 at 15:36






    • 1




      @Ian Roberts , i am just clarifying, in your answer does it mean that multiple email addresses are associated with multiple Message objects? And inside for loop, each Message obj's recipient address is taken individually each time? Please suggest
      – Nishi Bangar
      Dec 16 '15 at 7:32


















    Thanks for your answer. Curently I am using Transport.send(). I will test my code with session.getTransport().sendMessage(message, addressarray);
    – Narendra
    Nov 8 '12 at 12:07




    Thanks for your answer. Curently I am using Transport.send(). I will test my code with session.getTransport().sendMessage(message, addressarray);
    – Narendra
    Nov 8 '12 at 12:07












    @Narendra it's not quite as simple as that, but I've edited my answer with a more detailed example.
    – Ian Roberts
    Nov 8 '12 at 12:13




    @Narendra it's not quite as simple as that, but I've edited my answer with a more detailed example.
    – Ian Roberts
    Nov 8 '12 at 12:13












    Thanks for your code snippet. I tried my code with sendMessage method and now the time for sending mails is reduced to half the time when compared to using send(). However I have one question here that is: what is the use of savechanges()? Calling savechanges is expensive right? and in what cased we should call this? Please let me know.
    – Narendra
    Nov 8 '12 at 14:34






    Thanks for your code snippet. I tried my code with sendMessage method and now the time for sending mails is reduced to half the time when compared to using send(). However I have one question here that is: what is the use of savechanges()? Calling savechanges is expensive right? and in what cased we should call this? Please let me know.
    – Narendra
    Nov 8 '12 at 14:34














    @Narendra I just put it in to show the minimal change from the static send method if you want to batch several messages over one connection. The static send calls saveChanges on the message before sending it, you may be able to avoid that in your case if you know your message headers are already up to date.
    – Ian Roberts
    Nov 8 '12 at 15:36




    @Narendra I just put it in to show the minimal change from the static send method if you want to batch several messages over one connection. The static send calls saveChanges on the message before sending it, you may be able to avoid that in your case if you know your message headers are already up to date.
    – Ian Roberts
    Nov 8 '12 at 15:36




    1




    1




    @Ian Roberts , i am just clarifying, in your answer does it mean that multiple email addresses are associated with multiple Message objects? And inside for loop, each Message obj's recipient address is taken individually each time? Please suggest
    – Nishi Bangar
    Dec 16 '15 at 7:32






    @Ian Roberts , i am just clarifying, in your answer does it mean that multiple email addresses are associated with multiple Message objects? And inside for loop, each Message obj's recipient address is taken individually each time? Please suggest
    – Nishi Bangar
    Dec 16 '15 at 7:32














    up vote
    11
    down vote













    I got the same requirement at work. I must send bulk emails and standalone email. I do not find simple and satisfactory answer: bulk emails can be sent using a single connection but standalone email cannot until I create an asynchronous buffering to send emails in batch.



    Last but not least, using a lot of Transport connection in a short time can lead to a no more socket handles are available because all ports are stuck in the TIME_WAIT state.



    I finally conclude the best will be an SMTP connection pool and because no library exists (at least free) I create mine using Apache Common Pool and Java Mail:



    //Declare the factory and the connection pool, usually at the application startup
    SmtpConnectionPool smtpConnectionPool = new SmtpConnectionPool(SmtpConnectionFactoryBuilder.newSmtpBuilder().build());

    //borrow an object in a try-with-resource statement or call `close` by yourself
    try (ClosableSmtpConnection transport = smtpConnectionPool.borrowObject()) {
    MimeMessage mimeMessage = new MimeMessage(session);
    MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, false);
    mimeMessageHelper.addTo("to@example.com");
    mimeMessageHelper.setFrom("from@example.com");
    mimeMessageHelper.setSubject("Hi!");
    mimeMessageHelper.setText("Hello World!", false);
    transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
    }

    //Close the pool, usually when the application shutdown
    smtpConnectionPool.close();





    share|improve this answer





















    • How long do the connections last? Suppose I have different sessions assigned for different 'from' organizational addresses (some are auth , some not, some different host)? Is it safe to assume that all are smtp? What about password, can it be made to use the session authenticator instead of requiring the username and password in the build stage?
      – The Coordinator
      Jun 3 '15 at 4:29










    • The connection last the duration you have configured. About authentication, the SmtpConnectionFactoryBuilder#session can take an Authenticator. Different hosts will require different connection pool. When you write different session, you mean Transport?
      – Nicolas Labrot
      Jun 3 '15 at 10:33










    • We have different SMTP hosts depending on the from address of the email. And different authentic too even for the same host depending on what msexchange account is being used.
      – The Coordinator
      Jun 3 '15 at 16:59















    up vote
    11
    down vote













    I got the same requirement at work. I must send bulk emails and standalone email. I do not find simple and satisfactory answer: bulk emails can be sent using a single connection but standalone email cannot until I create an asynchronous buffering to send emails in batch.



    Last but not least, using a lot of Transport connection in a short time can lead to a no more socket handles are available because all ports are stuck in the TIME_WAIT state.



    I finally conclude the best will be an SMTP connection pool and because no library exists (at least free) I create mine using Apache Common Pool and Java Mail:



    //Declare the factory and the connection pool, usually at the application startup
    SmtpConnectionPool smtpConnectionPool = new SmtpConnectionPool(SmtpConnectionFactoryBuilder.newSmtpBuilder().build());

    //borrow an object in a try-with-resource statement or call `close` by yourself
    try (ClosableSmtpConnection transport = smtpConnectionPool.borrowObject()) {
    MimeMessage mimeMessage = new MimeMessage(session);
    MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, false);
    mimeMessageHelper.addTo("to@example.com");
    mimeMessageHelper.setFrom("from@example.com");
    mimeMessageHelper.setSubject("Hi!");
    mimeMessageHelper.setText("Hello World!", false);
    transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
    }

    //Close the pool, usually when the application shutdown
    smtpConnectionPool.close();





    share|improve this answer





















    • How long do the connections last? Suppose I have different sessions assigned for different 'from' organizational addresses (some are auth , some not, some different host)? Is it safe to assume that all are smtp? What about password, can it be made to use the session authenticator instead of requiring the username and password in the build stage?
      – The Coordinator
      Jun 3 '15 at 4:29










    • The connection last the duration you have configured. About authentication, the SmtpConnectionFactoryBuilder#session can take an Authenticator. Different hosts will require different connection pool. When you write different session, you mean Transport?
      – Nicolas Labrot
      Jun 3 '15 at 10:33










    • We have different SMTP hosts depending on the from address of the email. And different authentic too even for the same host depending on what msexchange account is being used.
      – The Coordinator
      Jun 3 '15 at 16:59













    up vote
    11
    down vote










    up vote
    11
    down vote









    I got the same requirement at work. I must send bulk emails and standalone email. I do not find simple and satisfactory answer: bulk emails can be sent using a single connection but standalone email cannot until I create an asynchronous buffering to send emails in batch.



    Last but not least, using a lot of Transport connection in a short time can lead to a no more socket handles are available because all ports are stuck in the TIME_WAIT state.



    I finally conclude the best will be an SMTP connection pool and because no library exists (at least free) I create mine using Apache Common Pool and Java Mail:



    //Declare the factory and the connection pool, usually at the application startup
    SmtpConnectionPool smtpConnectionPool = new SmtpConnectionPool(SmtpConnectionFactoryBuilder.newSmtpBuilder().build());

    //borrow an object in a try-with-resource statement or call `close` by yourself
    try (ClosableSmtpConnection transport = smtpConnectionPool.borrowObject()) {
    MimeMessage mimeMessage = new MimeMessage(session);
    MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, false);
    mimeMessageHelper.addTo("to@example.com");
    mimeMessageHelper.setFrom("from@example.com");
    mimeMessageHelper.setSubject("Hi!");
    mimeMessageHelper.setText("Hello World!", false);
    transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
    }

    //Close the pool, usually when the application shutdown
    smtpConnectionPool.close();





    share|improve this answer












    I got the same requirement at work. I must send bulk emails and standalone email. I do not find simple and satisfactory answer: bulk emails can be sent using a single connection but standalone email cannot until I create an asynchronous buffering to send emails in batch.



    Last but not least, using a lot of Transport connection in a short time can lead to a no more socket handles are available because all ports are stuck in the TIME_WAIT state.



    I finally conclude the best will be an SMTP connection pool and because no library exists (at least free) I create mine using Apache Common Pool and Java Mail:



    //Declare the factory and the connection pool, usually at the application startup
    SmtpConnectionPool smtpConnectionPool = new SmtpConnectionPool(SmtpConnectionFactoryBuilder.newSmtpBuilder().build());

    //borrow an object in a try-with-resource statement or call `close` by yourself
    try (ClosableSmtpConnection transport = smtpConnectionPool.borrowObject()) {
    MimeMessage mimeMessage = new MimeMessage(session);
    MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, false);
    mimeMessageHelper.addTo("to@example.com");
    mimeMessageHelper.setFrom("from@example.com");
    mimeMessageHelper.setSubject("Hi!");
    mimeMessageHelper.setText("Hello World!", false);
    transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
    }

    //Close the pool, usually when the application shutdown
    smtpConnectionPool.close();






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered May 15 '15 at 14:33









    Nicolas Labrot

    2,8221728




    2,8221728












    • How long do the connections last? Suppose I have different sessions assigned for different 'from' organizational addresses (some are auth , some not, some different host)? Is it safe to assume that all are smtp? What about password, can it be made to use the session authenticator instead of requiring the username and password in the build stage?
      – The Coordinator
      Jun 3 '15 at 4:29










    • The connection last the duration you have configured. About authentication, the SmtpConnectionFactoryBuilder#session can take an Authenticator. Different hosts will require different connection pool. When you write different session, you mean Transport?
      – Nicolas Labrot
      Jun 3 '15 at 10:33










    • We have different SMTP hosts depending on the from address of the email. And different authentic too even for the same host depending on what msexchange account is being used.
      – The Coordinator
      Jun 3 '15 at 16:59


















    • How long do the connections last? Suppose I have different sessions assigned for different 'from' organizational addresses (some are auth , some not, some different host)? Is it safe to assume that all are smtp? What about password, can it be made to use the session authenticator instead of requiring the username and password in the build stage?
      – The Coordinator
      Jun 3 '15 at 4:29










    • The connection last the duration you have configured. About authentication, the SmtpConnectionFactoryBuilder#session can take an Authenticator. Different hosts will require different connection pool. When you write different session, you mean Transport?
      – Nicolas Labrot
      Jun 3 '15 at 10:33










    • We have different SMTP hosts depending on the from address of the email. And different authentic too even for the same host depending on what msexchange account is being used.
      – The Coordinator
      Jun 3 '15 at 16:59
















    How long do the connections last? Suppose I have different sessions assigned for different 'from' organizational addresses (some are auth , some not, some different host)? Is it safe to assume that all are smtp? What about password, can it be made to use the session authenticator instead of requiring the username and password in the build stage?
    – The Coordinator
    Jun 3 '15 at 4:29




    How long do the connections last? Suppose I have different sessions assigned for different 'from' organizational addresses (some are auth , some not, some different host)? Is it safe to assume that all are smtp? What about password, can it be made to use the session authenticator instead of requiring the username and password in the build stage?
    – The Coordinator
    Jun 3 '15 at 4:29












    The connection last the duration you have configured. About authentication, the SmtpConnectionFactoryBuilder#session can take an Authenticator. Different hosts will require different connection pool. When you write different session, you mean Transport?
    – Nicolas Labrot
    Jun 3 '15 at 10:33




    The connection last the duration you have configured. About authentication, the SmtpConnectionFactoryBuilder#session can take an Authenticator. Different hosts will require different connection pool. When you write different session, you mean Transport?
    – Nicolas Labrot
    Jun 3 '15 at 10:33












    We have different SMTP hosts depending on the from address of the email. And different authentic too even for the same host depending on what msexchange account is being used.
    – The Coordinator
    Jun 3 '15 at 16:59




    We have different SMTP hosts depending on the from address of the email. And different authentic too even for the same host depending on what msexchange account is being used.
    – The Coordinator
    Jun 3 '15 at 16:59










    up vote
    1
    down vote













    No idea if the standard Java mail API allows what you are trying to accomplish (session reuse), but you may consider using multi-threading:



    I would use a ThreadPool and submit mail send jobs to it. Then you do any error handling / resending within the job class code, which is executed by the ThreadPool asynchronously, and your main thread can resume to do other things. Submitting a job will only take milliseconds. It been a while since I implemented something with thread pools in Java, but I remember it was fairly easy and straightforward. If you Google "Java ThreadPool" you find plenty of material.






    share|improve this answer





















    • Hi FelixD, Thanks for your answer. I am mainly looking for session reuse bcz authenticating every time is a overhead process. My main goal here is to reduce the time taken for sending mail from 4seconds to around 1 second. You suggested using theads, but it will not improve the time taken for sending mail from src system to destination.
      – Narendra
      Nov 8 '12 at 11:11










    • Hi Narenda, no worries and thanks for your comment. I see your point - unfortunately I can't really help with more advanced use of the Java mail API, I have only done the simple sending with it. I hope my suggestion with multi-threading might be helpful for others though, as there are situations where this solves the issue (e.g. when mail sending is keeping your main app busy too long etc). Of course the load on the mail server on the other end also does not get less by my approach...
      – FelixD
      Nov 8 '12 at 12:49










    • Thanks FelixD for your reply. As Ian Robert suggested in above answer, using sendMessage is useful for my scenario and it reducing time for mail delivery as it reusing the existing session object. But implementing it is a not an easy task as Ian Robert told.
      – Narendra
      Nov 8 '12 at 14:39










    • You're right. I hadn't noticed Ian Robert's reply when I wrote the last comment. What he writes looks interesting, maybe I'll need that some time as well. :)
      – FelixD
      Nov 8 '12 at 16:11















    up vote
    1
    down vote













    No idea if the standard Java mail API allows what you are trying to accomplish (session reuse), but you may consider using multi-threading:



    I would use a ThreadPool and submit mail send jobs to it. Then you do any error handling / resending within the job class code, which is executed by the ThreadPool asynchronously, and your main thread can resume to do other things. Submitting a job will only take milliseconds. It been a while since I implemented something with thread pools in Java, but I remember it was fairly easy and straightforward. If you Google "Java ThreadPool" you find plenty of material.






    share|improve this answer





















    • Hi FelixD, Thanks for your answer. I am mainly looking for session reuse bcz authenticating every time is a overhead process. My main goal here is to reduce the time taken for sending mail from 4seconds to around 1 second. You suggested using theads, but it will not improve the time taken for sending mail from src system to destination.
      – Narendra
      Nov 8 '12 at 11:11










    • Hi Narenda, no worries and thanks for your comment. I see your point - unfortunately I can't really help with more advanced use of the Java mail API, I have only done the simple sending with it. I hope my suggestion with multi-threading might be helpful for others though, as there are situations where this solves the issue (e.g. when mail sending is keeping your main app busy too long etc). Of course the load on the mail server on the other end also does not get less by my approach...
      – FelixD
      Nov 8 '12 at 12:49










    • Thanks FelixD for your reply. As Ian Robert suggested in above answer, using sendMessage is useful for my scenario and it reducing time for mail delivery as it reusing the existing session object. But implementing it is a not an easy task as Ian Robert told.
      – Narendra
      Nov 8 '12 at 14:39










    • You're right. I hadn't noticed Ian Robert's reply when I wrote the last comment. What he writes looks interesting, maybe I'll need that some time as well. :)
      – FelixD
      Nov 8 '12 at 16:11













    up vote
    1
    down vote










    up vote
    1
    down vote









    No idea if the standard Java mail API allows what you are trying to accomplish (session reuse), but you may consider using multi-threading:



    I would use a ThreadPool and submit mail send jobs to it. Then you do any error handling / resending within the job class code, which is executed by the ThreadPool asynchronously, and your main thread can resume to do other things. Submitting a job will only take milliseconds. It been a while since I implemented something with thread pools in Java, but I remember it was fairly easy and straightforward. If you Google "Java ThreadPool" you find plenty of material.






    share|improve this answer












    No idea if the standard Java mail API allows what you are trying to accomplish (session reuse), but you may consider using multi-threading:



    I would use a ThreadPool and submit mail send jobs to it. Then you do any error handling / resending within the job class code, which is executed by the ThreadPool asynchronously, and your main thread can resume to do other things. Submitting a job will only take milliseconds. It been a while since I implemented something with thread pools in Java, but I remember it was fairly easy and straightforward. If you Google "Java ThreadPool" you find plenty of material.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 8 '12 at 11:07









    FelixD

    427415




    427415












    • Hi FelixD, Thanks for your answer. I am mainly looking for session reuse bcz authenticating every time is a overhead process. My main goal here is to reduce the time taken for sending mail from 4seconds to around 1 second. You suggested using theads, but it will not improve the time taken for sending mail from src system to destination.
      – Narendra
      Nov 8 '12 at 11:11










    • Hi Narenda, no worries and thanks for your comment. I see your point - unfortunately I can't really help with more advanced use of the Java mail API, I have only done the simple sending with it. I hope my suggestion with multi-threading might be helpful for others though, as there are situations where this solves the issue (e.g. when mail sending is keeping your main app busy too long etc). Of course the load on the mail server on the other end also does not get less by my approach...
      – FelixD
      Nov 8 '12 at 12:49










    • Thanks FelixD for your reply. As Ian Robert suggested in above answer, using sendMessage is useful for my scenario and it reducing time for mail delivery as it reusing the existing session object. But implementing it is a not an easy task as Ian Robert told.
      – Narendra
      Nov 8 '12 at 14:39










    • You're right. I hadn't noticed Ian Robert's reply when I wrote the last comment. What he writes looks interesting, maybe I'll need that some time as well. :)
      – FelixD
      Nov 8 '12 at 16:11


















    • Hi FelixD, Thanks for your answer. I am mainly looking for session reuse bcz authenticating every time is a overhead process. My main goal here is to reduce the time taken for sending mail from 4seconds to around 1 second. You suggested using theads, but it will not improve the time taken for sending mail from src system to destination.
      – Narendra
      Nov 8 '12 at 11:11










    • Hi Narenda, no worries and thanks for your comment. I see your point - unfortunately I can't really help with more advanced use of the Java mail API, I have only done the simple sending with it. I hope my suggestion with multi-threading might be helpful for others though, as there are situations where this solves the issue (e.g. when mail sending is keeping your main app busy too long etc). Of course the load on the mail server on the other end also does not get less by my approach...
      – FelixD
      Nov 8 '12 at 12:49










    • Thanks FelixD for your reply. As Ian Robert suggested in above answer, using sendMessage is useful for my scenario and it reducing time for mail delivery as it reusing the existing session object. But implementing it is a not an easy task as Ian Robert told.
      – Narendra
      Nov 8 '12 at 14:39










    • You're right. I hadn't noticed Ian Robert's reply when I wrote the last comment. What he writes looks interesting, maybe I'll need that some time as well. :)
      – FelixD
      Nov 8 '12 at 16:11
















    Hi FelixD, Thanks for your answer. I am mainly looking for session reuse bcz authenticating every time is a overhead process. My main goal here is to reduce the time taken for sending mail from 4seconds to around 1 second. You suggested using theads, but it will not improve the time taken for sending mail from src system to destination.
    – Narendra
    Nov 8 '12 at 11:11




    Hi FelixD, Thanks for your answer. I am mainly looking for session reuse bcz authenticating every time is a overhead process. My main goal here is to reduce the time taken for sending mail from 4seconds to around 1 second. You suggested using theads, but it will not improve the time taken for sending mail from src system to destination.
    – Narendra
    Nov 8 '12 at 11:11












    Hi Narenda, no worries and thanks for your comment. I see your point - unfortunately I can't really help with more advanced use of the Java mail API, I have only done the simple sending with it. I hope my suggestion with multi-threading might be helpful for others though, as there are situations where this solves the issue (e.g. when mail sending is keeping your main app busy too long etc). Of course the load on the mail server on the other end also does not get less by my approach...
    – FelixD
    Nov 8 '12 at 12:49




    Hi Narenda, no worries and thanks for your comment. I see your point - unfortunately I can't really help with more advanced use of the Java mail API, I have only done the simple sending with it. I hope my suggestion with multi-threading might be helpful for others though, as there are situations where this solves the issue (e.g. when mail sending is keeping your main app busy too long etc). Of course the load on the mail server on the other end also does not get less by my approach...
    – FelixD
    Nov 8 '12 at 12:49












    Thanks FelixD for your reply. As Ian Robert suggested in above answer, using sendMessage is useful for my scenario and it reducing time for mail delivery as it reusing the existing session object. But implementing it is a not an easy task as Ian Robert told.
    – Narendra
    Nov 8 '12 at 14:39




    Thanks FelixD for your reply. As Ian Robert suggested in above answer, using sendMessage is useful for my scenario and it reducing time for mail delivery as it reusing the existing session object. But implementing it is a not an easy task as Ian Robert told.
    – Narendra
    Nov 8 '12 at 14:39












    You're right. I hadn't noticed Ian Robert's reply when I wrote the last comment. What he writes looks interesting, maybe I'll need that some time as well. :)
    – FelixD
    Nov 8 '12 at 16:11




    You're right. I hadn't noticed Ian Robert's reply when I wrote the last comment. What he writes looks interesting, maybe I'll need that some time as well. :)
    – FelixD
    Nov 8 '12 at 16:11










    up vote
    0
    down vote













    You can use Thread pooling as it gives very good performance.I have implemented and sharing you the below code snippet.



    try  {
    ExecutorService executor = Executors.newFixedThreadPool("no. of threads"); // no. of threads is depend on your cpu/memory usage it's better to test with diff. no. of threads.
    Runnable worker = new MyRunnable(message); // message is the javax.mail.Message
    executor.execute(worker);
    executor.shutdown();
    executor.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
    }





    share|improve this answer



























      up vote
      0
      down vote













      You can use Thread pooling as it gives very good performance.I have implemented and sharing you the below code snippet.



      try  {
      ExecutorService executor = Executors.newFixedThreadPool("no. of threads"); // no. of threads is depend on your cpu/memory usage it's better to test with diff. no. of threads.
      Runnable worker = new MyRunnable(message); // message is the javax.mail.Message
      executor.execute(worker);
      executor.shutdown();
      executor.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
      }





      share|improve this answer

























        up vote
        0
        down vote










        up vote
        0
        down vote









        You can use Thread pooling as it gives very good performance.I have implemented and sharing you the below code snippet.



        try  {
        ExecutorService executor = Executors.newFixedThreadPool("no. of threads"); // no. of threads is depend on your cpu/memory usage it's better to test with diff. no. of threads.
        Runnable worker = new MyRunnable(message); // message is the javax.mail.Message
        executor.execute(worker);
        executor.shutdown();
        executor.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
        }





        share|improve this answer














        You can use Thread pooling as it gives very good performance.I have implemented and sharing you the below code snippet.



        try  {
        ExecutorService executor = Executors.newFixedThreadPool("no. of threads"); // no. of threads is depend on your cpu/memory usage it's better to test with diff. no. of threads.
        Runnable worker = new MyRunnable(message); // message is the javax.mail.Message
        executor.execute(worker);
        executor.shutdown();
        executor.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
        }






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Oct 14 '15 at 16:11









        Walery Strauch

        3,67963448




        3,67963448










        answered Oct 14 '15 at 15:50









        S Boot

        12619




        12619






























             

            draft saved


            draft discarded



















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f13287515%2fhow-to-send-bulk-mails-using-javax-mail-api-efficiently-can-we-use-reuse-auth%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            這個網誌中的熱門文章

            Xamarin.form Move up view when keyboard appear

            Post-Redirect-Get with Spring WebFlux and Thymeleaf

            Anylogic : not able to use stopDelay()