Scheduling Java tasks with Quartz Scheduler

Photo by Imonki72 from pixabay.com

Want to make sure your daily backups are running? Take a look at PushMon, the easiest way to monitor your cron and scheduled tasks.

Introduction

There are specific cases that require a greater level of control and detail in scheduling tasks. Of course this is possible with Java’s TimerTask, but the work would be a bit more arduous and perhaps even unnecessary since we already have APIs ready for such a task, as is the case with the Quartz Scheduler.

Quartz Scheduler

Initially Quartz will seem a bit more complex than TimerTask and this is because it has many features that are complex from a functional point of view.

It works with the Factory project pattern, represented by the SchedulerFactory interface.

Instead of implementing this interface and developing all the logic needed to create a Scheduler for Quartz, we can use one of two classes that does this: StdSchedulerFactory or DirectSchedulerFactory.

The Scheduler has two methods that delimit the beginning and end, they are: start () and shutdown ().

Right after the start() method you can start scheduling your tasks and when the shutdown() method is called they stop executing.

JOB

Quartz works with the concept of JOB to implement the functionalities that will be executed.

Remember that in previous sections we saw the use of the run() method in TimerTask?

The logic is almost the same here, we implemented the Job interface, where the execute() method would be analogous to run() shown in previous sections. See the Listing below.

Implementing the Job Interface:

import java.util.Date;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

public class ValidadorJob implements Job {

   @Override
   public void execute(JobExecutionContext arg0) throws JobExecutionException {
      System.out.println("Validating duplicated data in database. At "+new Date());
      System.out.println("Deleting data with more than 10 days without use. At "+new Date());
   }
}

Also be aware of imports, so you do not import wrong packet classes. The execute() method is who will “save” our logic that must be executed at a certain instant of time.

You will see later that to instantiate our Job, we will use the JobBuilder class, where we will pass the Job implementation through the newJob() method, the identity in the withIdentity() method and the creation through build().

It may seem complex at first more will become clearer when we show in practice the use of these methods.
This is the easiest part, as we have already seen in TimerTask the logic is almost the same just replacing run() with execute().

The greater work will be to make your internal logic to execute() and this obviously depends on each business rule.

TRIGGER

We still have another artifact to know before actually starting to use Quartz.

This uses the concept of “Triggers” to configure task scheduling and trigger tasks.

We will see that Quartz defines some types of triggers to use, but in our case we will use the CronTrigger that simulates the famous linux crontab.

To construct our trigger, the steps are almost the same as in Job, we use TriggerBuild(), also withidentity() to define the name of our trigger, scheduling data with withSchedule() and trigger creation / instantiation through build().

The use of CronTrigger is a crontab simulation, and for this we need to understand how the cron expression, or cron expression works.

To create a cron expression one must know the order of the parameters that are: Seconds, Minutes, Hours, Day of the Month, Month, Day of the Week and Year (Optional).

Imagine how positions in the vector, where each of these positions exactly matches the information already mentioned.

Running Quartz

Once we understand the concept of Job and Trigger for Quartz, we will actually begin to use it, as shown in the listing below.

Using Quartz:

import org.quartz.CronScheduleBuilder;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
  
public class QuartzApp {
  
       public static void main(String[] args) {
             SchedulerFactory shedFact = new StdSchedulerFactory();
             try {
                    Scheduler scheduler = shedFact.getScheduler();
                    scheduler.start();
                    JobDetail job = JobBuilder.newJob(ValidadorJob.class)
                                  .withIdentity("validadorJOB", "group01")
                                  .build();
                    Trigger trigger = TriggerBuilder.newTrigger()
                                  .withIdentity("validadorTRIGGER","group01")
                                  .withSchedule(CronScheduleBuilder.cronSchedule("0/1 * * * * ?"))
                                  .build();
                    scheduler.scheduleJob(job, trigger);
             } catch (SchedulerException e) {
                    e.printStackTrace();
             }
       }
}

Let’s get the explanations from the listing above.

  1. We made use of the factory default implementation of the StdSchedulerFactory class, so we can capture an instance of Scheduler;
  2. The Scheduler object shown in step 1 allows us to start monitoring tasks and schedules new tasks as needed;
  3. Soon after we started to define in Job, using JobBuilder. Our identifier (withidentity) will be “validadorJOB” and the group will be “group01”;
  4. We have created our Trigger needed to define the exact execution interval of our Job;
  5. Finnaly, we add the job object and trigger to the scheduler, so it will know which task should be executed and at what instant of time.

Conclusion

The main objective of this article was to show the use of an external library called Quartz Scheduler that has the function of adding greater complexity (from the functional point of view) to the scheduling of tasks.

With this, we do not have to depend on the installation of external tools, like crontab, to execute specific classes at a certain instant of time.