Search code examples
javawhile-loopinfinite-loop

Java unknown cause for infinite loop


I have a code result that I cannot explain in Java 11 code that sends an email.

I am using the javax mail package:

import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

Here is the code:

Properties props = System.getProperties();
props.put("mail.smtp.host", smtpHost);
Session session = Session.getInstance(props);

int nMaxTries = 5;
int nTries = 0;
boolean success = false;

while (!success || nTries >= nMaxTries) {
    try {
        MimeMessage msg = new MimeMessage(session);
        //set message headers
        msg.addHeader("Content-type", "text/HTML; charset=UTF-8");
        msg.addHeader("format", "flowed");
        msg.addHeader("Content-Transfer-Encoding", "8bit");

        msg.setFrom(new InternetAddress(fromEmail, from));
        msg.setSubject(subject, "UTF-8");
        msg.setContent(body, "text/html");
        msg.setSentDate(new Date());
        msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toEmail, false));

        System.out.println("Message is ready");
        Transport.send(msg);

        System.out.println("EMail Sent Successfully!!");
        success = true;
    } catch (Exception e) {
        e.printStackTrace();
        nTries++;
    }
}

I noticed that sometimes the email would fail, hence the retry. This runs using a cron process that pipes output to the logs. This has been working fine for several weeks. This morning, I received nearly 400,000 emails. I see this over and over in the logs:

Message is ready
EMail Sent Successfully!!
Message is ready
EMail Sent Successfully!!
Message is ready
EMail Sent Successfully!!
Message is ready
EMail Sent Successfully!!
Message is ready

This is a single threaded process. Looking at this I realize I can increment the counter in the loop vs just the catch statement so these infinite loops will stop. Can anyone explain the logic as far as how the while loop would fail to complete?

Thanks!


Solution

  • As was stated, use

    !success && nTries < nMaxTries
    

    But forget about testing the success boolean and just break out of the loop when the email is sent.

    while (nTries < nMaxTries) {
        try {
            MimeMessage msg = new MimeMessage(session);
            //set message headers
            msg.addHeader("Content-type", "text/HTML; charset=UTF-8");
            msg.addHeader("format", "flowed");
            msg.addHeader("Content-Transfer-Encoding", "8bit");
    
            msg.setFrom(new InternetAddress(fromEmail, from));
            msg.setSubject(subject, "UTF-8");
            msg.setContent(body, "text/html");
            msg.setSentDate(new Date());
            msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toEmail, false));
    
            System.out.println("Message is ready");
            Transport.send(msg);
    
            System.out.println("EMail Sent Successfully!!");
            success = true;    // keep for final status
            break;             // terminate the loop here.
        } catch (Exception e) {
            e.printStackTrace();
            nTries++;
        }
    }