Wednesday, October 22, 2014

Quartz Job

The Quartz Jobs can be created with a very simple program by just adding the required libraries to the class path of your project. Here I will try to explain two different ways to configure a Quartz job. This complete post is divided into 3 sections.
Section 1: Common steps for both the approaches
Section 2: Simple Job with out any XML/Properties file involved
Section 3: With XML files and properties files to manage the Jobs.
So, lets put our hands in dirt.
Tools you need before you start this example: Eclipse Juno/Kepler.
Section 1: Common steps to create a Quartz Job/Scheduler
Step 1: Download the Jars for Quartz either from Maven or manual download.
Step 2: Create a Java project  {I am going with older approach}.
Step 3: Refer your downloaded jars in your class path (by Right Click on Project -> Build path -> Add External Archives ) See screen shot below, You could even use jta-1.1.jar instead of jboss-transaction-spi. But don’t miss this jar as this is a mandatory dependency for Quartz 2.2.1.
Quartz_reference_lib
Note: Once these steps are over either you can choose Section 2 or Section 3. [I recommend Section 3]
Section 2:  Simple Job using Java Code
Step 1: Create a class which implements org.quartz.Job interface.
Step 2: Implement execute() method of this interface.
Step 3: Write your business logic inside this execute method i.e. what has to be done when your job gets executed.
See below code as example
package com.ravi.schedulers;

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

public class ExampleQuartzJob implements Job{

    @Override
    public void execute(JobExecutionContext arg0) throws JobExecutionException    {
       // TODO Auto-generated method stub
       System.out.println("Logic Goes here........");
    }
}
Create another class.
package com.ravi.schedulers.test;

import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;

public class TestBJob {

    public static void main(String[] args) {
        try {
            // Create Job details 
            JobDetail job = JobBuilder.newJob(TestJob.class)
                            .withIdentity("testJob")
                            .build();
           // Create the trigger with running interval of the job
           Trigger trigger = TriggerBuilder.newTrigger()
                          .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                          .withIntervalInSeconds(30)
                          .repeatForever()).build();
          //This is how you start the job
          SchedulerFactory schFactory = new StdSchedulerFactory();
          Scheduler scheduler = schFactory.getScheduler();
          // tricky step, if you don't start the scheduler, it won't run.
          scheduler.start();
          // This is the thing which will run your Job at the triggered time/interval.
          scheduler.scheduleJob(job, trigger);
 
          //Use it to stop the scheduler. 
          //sch.shutdown();
      } catch (SchedulerException e) {
        e.printStackTrace();
      }
   }
}
Here are the next steps ….
You might get some warning as below as I missed the dependency of slf4j -
SLF4J: Failed to load class “org.slf4j.impl.StaticLoggerBinder”.
SLF4J: Defaulting to no-operation (NOP) logger implementation
But the program will run as it is not a mandatory dependency. If you want to avoid warning please add this jar as well in your references.
Lets move on to other section.
Section 3: Scheduler Jobs with XML, Properties files.
Step1: Create a XML file with name quartz-config.xml (You can even use another name :), just for identification I am using this name.)
<?xml version="1.0" encoding="UTF-8"?>
<job-scheduling-data
xmlns="http://www.quartz-scheduler.org/xml/JobSchedulingData"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.quartz-scheduler.org/xml/JobSchedulingData

http://www.quartz-scheduler.org/xml/job_scheduling_data_1_8.xsd"

version="1.8">

<schedule>
<job>
<name>FirstJob</name>
<group>Group1</group>
<description>This is Test Job</description>
<job-class>com.ravi.schedulers.ExampleQuartzJob</job-class>
</job>
<trigger>
<cron>
<name>dummyTrigger</name>
<job-name>FirstJob</job-name>
<job-group>Group1</job-group>
<!-- It will run every 2 seconds -->
<cron-expression>0/2 * * * * ?</cron-expression>
</cron>
</trigger>
</schedule>
</job-scheduling-data>
Step2: Create a properties file with name quartz.properties, in the same folder.
org.quartz.scheduler.instanceName = ExampleQuartzJob
org.quartz.threadPool.threadCount = 3
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
org.quartz.plugin.jobInitializer.class =org.quartz.plugins.xml.XMLSchedulingDataProcessorPlugin
org.quartz.plugin.jobInitializer.fileNames = com/ravi/schedulers/quartz-config.xml
org.quartz.plugin.jobInitializer.failOnFileNotFound = true
Once you are done with these two changes, you have to create a main method class to test this job.
package com.ravi.schedulers;

import javax.naming.NamingException;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.impl.StdSchedulerFactory;

public class QuartzRunner {
     public static void main(String[] args) throws SchedulerException, NamingException {
         // Creating scheduler factory and scheduler
         SchedulerFactory factory = new StdSchedulerFactory(
                     "com/ravi/schedulers/quartz.properties");
         Scheduler scheduler = factory.getScheduler();
         // Start scheduler
         scheduler.start();
     }
}
 This is how you can create a scheduler job using Quartz API. Hope this was helpful and useful for your work.
 Happy Scheduling :)