Search code examples
javaemailloggingmonitormailing

While loop executing infinite times in java for LogMonitor


I am working on a project where a java program records the changes made to the text file, writes it to other log file and sends it via email. The problem I am facing is the while loop used for monitoring changes has no break. If I put the code of mailing inside while loop the mail goes in infinite loop. If I put the code outside while loop, main can't reach there because while is in infinite loop. I need a break condition and I cant figure it out. Can anyone help?

import java.util.Properties;  
import java.io.*;
import javax.mail.*;  
import javax.mail.internet.*;  
import javax.activation.*;  

public class LogMonitor {
    public static void main(String[] args) throws Exception
{
        FileReader fr = new FileReader("D:/test.txt");
        BufferedReader br = new BufferedReader(fr);
        while (true) {
            String line = br.readLine();
            if (line == null)
            {
                Thread.sleep(1*1000);
            } else
            {
                byte[] y = line.getBytes();
                File g = new File("D:/abc.txt");
                try (OutputStream f = new FileOutputStream(g,true))
                {
                    f.write( y );
                }
            }    

 String to="abcde@gmail.com";//change accordingly  
  final String user="vwxyz@gmail.com";//change accordingly  
  final String password="xxxxxxx";//change accordingly  
 // final String d_port  = "465";

  //1) get the session object
  // java.security.Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
   Properties props = new Properties();
                props.put("mail.smtp.host", "smtp.gmail.com");
                props.put("mail.smtp.socketFactory.port", "465");
                props.put("mail.smtp.socketFactory.class",
                                "javax.net.ssl.SSLSocketFactory");
                props.put("mail.smtp.auth", "true");
                props.put("mail.smtp.port", "465");

  Session session = Session.getDefaultInstance(props,  
   new javax.mail.Authenticator()
   {  
   @Override
   protected PasswordAuthentication getPasswordAuthentication()
   {  
   return new PasswordAuthentication(user,password);  
   }  
   });

  //2) compose message    
  try{  
    MimeMessage message = new MimeMessage(session);  
    message.setFrom(new InternetAddress(user));  
    message.addRecipient(Message.RecipientType.TO,new InternetAddress(to));  
    message.setSubject("Message Alert! Changes made to your file");  

    //3) create MimeBodyPart object and set your message text    
    BodyPart messageBodyPart1 = new MimeBodyPart();  
    messageBodyPart1.setText("This is message body");  

    //4) create new MimeBodyPart object and set DataHandler object to this object      
   MimeBodyPart messageBodyPart2 = new MimeBodyPart();  

 String filename = "D://abc.txt";//change accordingly  
    DataSource source = new FileDataSource(filename);  
    messageBodyPart2.setDataHandler(new DataHandler(source));  
   messageBodyPart2.setFileName(filename);  


    //5) create Multipart object and add MimeBodyPart objects to this object      
    Multipart multipart = new MimeMultipart();  
    multipart.addBodyPart(messageBodyPart1);  
   multipart.addBodyPart(messageBodyPart2);  

    //6) set the multiplart object to the message object  
    message.setContent(multipart );  

    //7) send message  
    Transport.send(message);  

   System.out.println("message sent....");  
   }catch (MessagingException ex) {
       System.out.println(ex);


   }  
        }
}}

Solution

  • First Move Sending email ail block to seperate method. I just cut and pasted your code ..

    public static void sendEmail() {
        String to = "abcde@gmail.com";// change accordingly
        final String user = "vwxyz@gmail.com";// change accordingly
        final String password = "xxxxxxx";// change accordingly
        // final String d_port = "465";
    
        // 1) get the session object
        // java.security.Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
        Properties props = new Properties();
        props.put("mail.smtp.host", "smtp.gmail.com");
        props.put("mail.smtp.socketFactory.port", "465");
        props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.port", "465");
    
        Session session = Session.getDefaultInstance(props, new javax.mail.Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(user, password);
            }
        });
    
        // 2) compose message
        try {
            MimeMessage message = new MimeMessage(session);
            message.setFrom(new InternetAddress(user));
            message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
            message.setSubject("Message Alert! Changes made to your file");
    
            // 3) create MimeBodyPart object and set your message text
            BodyPart messageBodyPart1 = new MimeBodyPart();
            messageBodyPart1.setText("This is message body");
    
            // 4) create new MimeBodyPart object and set DataHandler object to this object
            MimeBodyPart messageBodyPart2 = new MimeBodyPart();
    
            String filename = "D://abc.txt";// change accordingly
            DataSource source = new FileDataSource(filename);
            messageBodyPart2.setDataHandler(new DataHandler(source));
            messageBodyPart2.setFileName(filename);
    
            // 5) create Multipart object and add MimeBodyPart objects to this object
            Multipart multipart = new MimeMultipart();
            multipart.addBodyPart(messageBodyPart1);
            multipart.addBodyPart(messageBodyPart2);
    
            // 6) set the multiplart object to the message object
            message.setContent(multipart);
    
            // 7) send message
            Transport.send(message);
    
            System.out.println("message sent....");
        }
        catch (MessagingException ex) {
            System.out.println(ex);
    
        }
    
    }
    

    Then add boolean to mark changes in main like.. Note isFileChanged used to send email the changes captured.

    public static void main(String[] args) throws Exception {
        FileReader fr = new FileReader("D:/test.txt");
        BufferedReader br = new BufferedReader(fr);
        boolean isFileChanged = false;
        while (true) {
            String line = br.readLine();
            if (line == null) {
                if (isFileChanged){
                    isFileChanged = false;
                    sendEmail();
                }
                Thread.sleep(1 * 1000);
            }
            else {
                isFileChanged = true;
                byte[] y = line.getBytes();
                File g = new File("D:/abc.txt");
                try (OutputStream f = new FileOutputStream(g, true)) {
                    f.write(y);
                }
            }
    
        }
    }