Pages

Thursday 21 March 2013

File Change Event In Java 6 using apache.commons.jci


I had requirement in my project to reload the whole context when properties file is changes.This is similar requirement like context reloading or hot deployment apache tomcat .After doing analysis I found that it is very easy to do it in java 7.But my requirement was for java 6 which we can achieve by using apache commons jci.
I have explained with the simple example monitors file change using apache commons 
Requirement:
1)  apache commans jci Jar and dependent Jars
Download Example project using below links:
1)Example with maven project :Maven dependency is added for the  commons jci.
2)Simple java project :In this project jars are added in lib folder please put them in classpath.

Below is the exaplanation about the classes used in above example projects:

1)ConfigurationReloading : This class has main method.This class will create FilesystemAlterationListener and it will associate it with File.When  file change event occurs the listeners onStop method will be triggered.Check javadoc of FilesystemAlterationListener. 
Please take closer look to this class :

package fileReloadingExampleMain;


 
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Properties;
 
import org.apache.commons.jci.listeners.FileChangeListener;
import org.apache.commons.jci.monitor.FilesystemAlterationListener;
import org.apache.commons.jci.monitor.FilesystemAlterationMonitor;
import org.apache.commons.jci.monitor.FilesystemAlterationObserver;
 
/**
 * This example will demonstrate that how add file change listener to properties file.
 * 
 * @author Vikram P
 */
public final class ConfigurationReloading {
 
    private final FilesystemAlterationMonitor fam = new FilesystemAlterationMonitor();
 
    private void run(String[] args) {
 
    	//this is the file on which we want to add listener
        final File configFile = new File("Some.Properties");
        
        //file does not exisits then we can not add listener
        if(configFile.exists()==false){
        	System.out.println("File does not exists at path"+configFile.getAbsolutePath());
        	return;
        }
 
        System.out.println("Watching " + configFile.getAbsolutePath());
 
        
        final Collection<configurable> configurables = new ArrayList<configurable>();
 
        //this is the listener which will be associated with above configFile
        final FilesystemAlterationListener listener = new FileChangeListener() {
            public void onStop(FilesystemAlterationObserver pObserver) {
                super.onStop(pObserver);
 
                if (hasChanged()) {
                    //System.out.println("Configuration change detected " + configFile);
 
                    final Properties props = new Properties();
                    try {
 
                        props.load(new FileInputStream(configFile));
 
                        //System.out.println("Notifying about configuration change " + configFile);
 
                        for (Iterator it = configurables.iterator(); it.hasNext();) {
                            final Configurable configurable = (Configurable) it.next();
                            configurable.configure(props);
                        }
 
                    } catch (Exception e) {
                        System.err.println("Failed to load configuration " + configFile);
                    }
 
                }
            }
        };

        //add listerner to config file.you can add multiple files here.
        fam.addListener(configFile, listener);
        //start monitoring.
        fam.start();
 
        //when ever any file change event will occure it will call the configure method of ChangedFileHandler class
        //ChangedFileHandler implements Configurable 
        ChangedFileHandler changedFileHandler = new ChangedFileHandler();
        
        configurables.add(changedFileHandler );
 
        while(true) {
            try {
            	//sleep period
                Thread.sleep(1000);
            } catch (InterruptedException e) {
            }
        }
    }
 
    public static void main(String[] args) {
    	//you can send multiple files through args
        new ConfigurationReloading().run(args);
    }
}

2) Interface Configurable : This interface’s implemented by ChangedFileHandler whose configure() method will be called when file is changed.        
package fileReloadingExampleMain;

import java.util.Properties;

public interface Configurable {
	public void configure(Properties props);
}
3)ChangedFileHandler :This class implements Configurable inteface.
   package fileReloadingExampleMain;

import java.util.Properties;

public class ChangedFileHandler implements Configurable {
	
	public void configure(Properties props) {
		System.out.println("File has changed...do reloading stuff....");
	}

}
   

Download  Example Project Using Below links:

1)Example with maven project
2) Simple java project
How to test?
- Some.properties file is present in the same project.When ever this file is changed it will print message to console.


“Please comment if you find this information useful.Thank you :)”