Java Quartz File Watcher Example
In this example we are going to demonstrate how to make use of a Quartz File Watcher. Quartz is an open source framework that specializes in scheduling and executing jobs within a Java application.
This example monitors a file over a regularly scheduled interval and will respond to any change to the file by executing a listener.
We used Eclipse Oxygen, Java 8, Maven 3.3.9 and Quartz 2.2.1.
1. Setup
We will use Maven to setup a new project in Eclipse with the appropriate Quartz dependencies.
1.1 Add Dependencies for Quartz
Add Quartz dependencies in the pom.xml
file.
pom.xml
<properties> <quartz.version>2.2.3</quartz.version> </properties> <dependencies> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>${quartz.version}</version> </dependency> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz-jobs</artifactId> <version>${quartz.version}</version> </dependency>
2. Java Quartz Trigger, Scheduler, Job and Listener
To setup a file watcher with Quartz we must define a scheduler, trigger, job and listener. The scheduler will execute the defined job based on the provided trigger. The job will decide whether to execute the provided listener based on the criteria set forth in the job. In this case if the file was edited since the last execution.
There are a few common options for triggers that include simple triggers and cron triggers (as in this example). Simple triggers run at a given time and will repeat as many times as requested. Cron triggers use the cron syntax to schedule and repeat jobs at regularly scheduled intervals. See the following link for cron expressions in Quartz, http://www.quartz-scheduler.org/documentation/quartz-2.x/tutorials/crontrigger.html.
2.1 Define a Cron Trigger and Standard Scheduler
First we will define a cron trigger and use the StdSchedulerFactory to initiate a scheduler. The cron trigger will be set to run every 5 seconds.
JcgQuartzApp.java
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("jcgFileScanTriggerName", "group1").withSchedule(CronScheduleBuilder.cronSchedule("0/5 * * * * ?")).build(); Scheduler scheduler = new StdSchedulerFactory().getScheduler(); scheduler.start();
2.2 Define Job and Job Data
Next, we are going to setup a Quartz library job, FileScanJob
, that is designed to watch a specified file. This job provided by the Quartz library will run at the specified interval and check to see if the last modified date on the file is greater than the last time the job executed. When the last modified date is greater than the last executed time, the job will execute the listener that is defined in the global job data map. The listener is a key value pair in the global job data map with the name of the file scan listener as the key and the listener object as the value, as seen below.
JcgQuartzApp.java
JobKey jobKey = new JobKey("jcgFileScanJobName", "group1"); JobDetail job = JobBuilder.newJob(FileScanJob.class).withIdentity(jobKey).build(); job.getJobDataMap().put(FileScanJob.FILE_NAME, filename); job.getJobDataMap().put(FileScanJob.FILE_SCAN_LISTENER_NAME, JcgFileScanListener.LISTENER_NAME);
2.3 Setup FileScanListener and Schedule Job
Finally, we need to setup the file scan listener, to schedule and execute the job. The file scan listener we will implement in the next section belongs in the global job data map of the scheduler. It is important to realize that this listener is not a job listener, on the other hand it is in the global map data for the scheduled job.
JcgQuartzApp.java
scheduler.getContext().put(JcgFileScanListener.LISTENER_NAME, new JcgFileScanListener()); scheduler.scheduleJob(job, trigger);
2.4. Java File Scan Listener
The last piece of the puzzle is to implement the FileScanListener
interface provided in the Quartz library. You must implement the fileUpdated
method as shown below with the logic you want to be executed when a file is updated.
JcgFileScanListener.java
public class JcgFileScanListener implements FileScanListener { public void fileUpdated(String fileName) { logger.info("File update to {}", fileName); }
3. Running the Application
To run this example, build the project with Maven and provide the full path to the watched file as a command line parameter to the running application. Any edit to the file will trigger the listener to execute the fileUpdated
method in the JcgFileScanListener
class.
To execute the application run the jar as follows:
java -jar JcgQuartzApp-0.0.1-SNAPSHOT-jar-with-dependencies.jar /Users/mydir/testx/test.txt
Here is sample output after starting the application and editing the provided file:
2016-12-16 21:04:52 INFO com.javacodegeeks.jcgquartzapp.JcgQuartzApp.main:27 - Scheduler started monitoring filename: /Users/mydir/testx/test.txt 2016-12-16 21:05:05 INFO com.javacodegeeks.jcgquartzapp.JcgFileScanListener.fileUpdated:14 - File update to /Users/mydir/testx/test.txt
4. Download the Source Code
Here we demonstrated how to use a Java Quartz File Watcher to monitor a file for changes.