I am trying to execute specific work in my Servlet/JSP application in everyday at 8.00AM and 12.00 PM. The Quartz library seems to be ideal for this, so I tried using it.
I used both of the tutorials and examples in below links.
http://www.mkyong.com/java/quartz-2-scheduler-tutorial/
http://www.javacodegeeks.com/2012/07/quartz-2-scheduler-example.html
Below is an attempt
Job class
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class HelloJob implements Job
{
public void execute(JobExecutionContext context)
throws JobExecutionException {
System.out.println("Hello Quartz!");
}
}
Trigger class
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
public class SimpleTriggerExample {
public static void main(String[] args) throws Exception {
JobDetail job = JobBuilder.newJob(HelloJob.class)
.withIdentity("dummyJobName", "group1").build();
// Trigger the job to run on the next round minute
Trigger trigger = TriggerBuilder
.newTrigger()
.withIdentity("dummyTriggerName", "group1")
.withSchedule(
SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(5).repeatForever())
.build();
// schedule it
Scheduler scheduler = new StdSchedulerFactory().getScheduler();
scheduler.start();
scheduler.scheduleJob(job, trigger);
}
}
However, both are not satisfying my need. They do not run at specific time. How can I use the Quarts to execute the job everyday 8.00AM and 12.00 PM?
Try create a schedule with Cron:
Trigger trigger = TriggerBuilder
.newTrigger()
.withIdentity("triggerName","triggerGroup")
.withSchedule(CronScheduleBuilder.cronSchedule("0 0 12 * * ?")).build();
Trigger trigger = TriggerBuilder
.newTrigger()
.withIdentity("triggerName","triggerGroup")
.withSchedule(CronScheduleBuilder.cronSchedule("0 0 8 * * ?")).build();
Trigger trigger = TriggerBuilder
.newTrigger()
.withIdentity("triggerName","triggerGroup")
.withSchedule(CronScheduleBuilder.cronSchedule("0 30 12 * * ?")).build(); //schedules a job for 12:30am
Trigger trigger = TriggerBuilder
.newTrigger()
.withIdentity("triggerName","triggerGroup")
.withSchedule(CronScheduleBuilder.cronSchedule("0 0 14 * * ?")).build(); //schedules a job for 2pm
Use this site for great information on scheduling:
http://www.quartz-scheduler.org/documentation/quartz-2.x/tutorials/crontrigger.html
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity("reportTrigger").WithSchedule(CronScheduleBuilder.DailyAtHourAndMinute(23,0)).Build();
Related
I want to create multiple threads on Java, and allot each thread a separate Quartz scheduler. But the only way I can find is to create multiple .properties files, for each separate scheduler. As I have a huge number of threads, creating so many properties files isn't feasible. Is there a better way to do so?
Please use this concept to handle multiple scheduler threads for multiple task on the basis of dynamic parameter
/*
* Date : 2015-07-06
* Author : Bhuwan Prasad Upadhyay
*/
package com.developerbhuwan.quartzexample;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.quartz.CronScheduleBuilder;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.StdSchedulerFactory;
/**
*
* #author developerbhuwan
*/
public class MutlipleScheduleThread {
public static void main(String[] args) {
new MutlipleScheduleThread().createMultipleThread();
}
private void createMultipleThread() {
for (int i = 0; i <= 10; i++) { //create 10 scheduler thread to perform different job on the basis of param
try {
JobDataMap jobDataMap = new JobDataMap();
jobDataMap.put(MyJob.KEY_PARAM, "ParamValue");
JobKey jobKey = new JobKey("UniqueJobId" + i, "JobGroup");
JobDetail job = JobBuilder
.newJob(MyJob.class)
.withIdentity(jobKey)
.setJobData(jobDataMap)
.storeDurably(true)
.build();
TriggerKey triggerKey = new TriggerKey("UniqueTriggerID" + i, "TriggerGroup");
Trigger trigger = TriggerBuilder
.newTrigger()
.withIdentity(triggerKey)
.withSchedule(CronScheduleBuilder.cronSchedule("0 0 0/1 1/1 * ? *")) //every one hour
.forJob(job)
.build();
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.scheduleJob(job, trigger);
} catch (SchedulerException ex) {
Logger.getLogger(MutlipleScheduleThread.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
private static class MyJob implements Job {
private static String KEY_PARAM = "param";
#Override
public void execute(JobExecutionContext context) throws JobExecutionException {
JobDataMap dataMap = context.getJobDetail().getJobDataMap();
String param = dataMap.getString(KEY_PARAM);
//do job on the basis of parameter
}
}
}
Source Code Quartz Example
I'm using the Quartz Scheduler to start jobs in my Java-App. I have the job HelloJob.java
package com.stackoverflow.test.java;
import java.util.Date;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class HelloJob implements Job {
private String message;
public HelloJob() {
Date akt = new Date();
this.message = "Quartz is running (" + akt + ").";
}
#Override
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println(this.message);
}
}
I'd like to start this job using two different cron expressions (here: */5 */3 * * * ? and */9 */2 * * * ?). I tried the following:
package com.stackoverflow.test.java;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.TriggerBuilder;
import org.quartz.JobBuilder;
import org.quartz.CronScheduleBuilder;
public class TestQuartz {
public static void main(String[] args) {
try {
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.start();
/* ################################################################### */
JobDetail job = JobBuilder
.newJob(HelloJob.class)
.withIdentity("job1", "group1")
.build();
CronScheduleBuilder sb1 = CronScheduleBuilder
.cronSchedule("*/5 */3 * * * ?");
CronScheduleBuilder sb2 = CronScheduleBuilder
.cronSchedule("*/9 */2 * * * ?");
Trigger trigger = TriggerBuilder
.newTrigger()
.withIdentity("trigger1", "group1")
.startNow()
.withSchedule(sb1)
.build();
Trigger trigger2 = TriggerBuilder
.newTrigger()
.withIdentity("trigger2", "group1")
.startNow()
.withSchedule(sb2)
.build();
scheduler.scheduleJob(job, trigger);
scheduler.scheduleJob(job, trigger2);
/* ################################################################### */
Thread.sleep(10 * 60 * 1000);
System.out.println("FIN");
/* ################################################################### */
scheduler.shutdown();
} catch (SchedulerException se) {
se.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
I receive the following exception:
org.quartz.ObjectAlreadyExistsException: Unable to store Job : 'group1.job1', because one already exists with this identification.
at org.quartz.simpl.RAMJobStore.storeJob(RAMJobStore.java:279)
at org.quartz.simpl.RAMJobStore.storeJobAndTrigger(RAMJobStore.java:251)
at org.quartz.core.QuartzScheduler.scheduleJob(QuartzScheduler.java:886)
at org.quartz.impl.StdScheduler.scheduleJob(StdScheduler.java:249)
at com.stackoverflow.test.java.TestQuartz.main(TestQuartz.java:47)
Is it impossible to start one Job with several triggers? Can I somehow generate a schedule that considers more than one cron expression?
You have to use TriggerBuilder's forJob(JobKey jobKey) method to assign further triggers to a job.
Trigger trigger = TriggerBuilder.newTrigger().forJob(job.getKey()). ...
scheduler.scheduleJob(trigger)
In your case, apply the following modifications:
/* ... */
Trigger trigger2 = TriggerBuilder
.newTrigger()
.forJob(job.getKey())
.withIdentity("trigger2", "group1")
.startNow()
.withSchedule(sb2)
.build();
/* ... */
scheduler.scheduleJob(trigger2);
/* ... */
I want to develop a quartz job which will run on a particular time specified within the job. But while I am starting the job it starts at that time not on that time which is specified within the code.
Please help.
Here is my code:
import java.util.TimeZone;
import org.quartz.CronScheduleBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
public class CronScheluderForActivityMilestone {
public boolean CronScheluderForActivityMilestone() throws Exception {
SchedulerFactory sf = new StdSchedulerFactory();
Scheduler sche = sf.getScheduler();
sche.start();
JobDetail jDetail = new JobDetail("SendMailOnActivityMileStone", "SendMailOnActivityMileStone", ActivityMileStoneSendMail.class);
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("mytriggerForActivityMileStone", "SendMailOnActivityMileStone")
.withSchedule(CronScheduleBuilder.dailyAtHourAndMinute(19, 00).inTimeZone(TimeZone.getTimeZone("Asia/Calcutta")))
.forJob("SendMailOnActivityMileStone", "SendMailOnActivityMileStone")
.build();
sche.scheduleJob(jDetail, trigger);
return true;
}
}
You should change your inTimeZone configuration like this :
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger3", "group1")
.withSchedule(weeklyOnDayAndHourAndMinute(DateBuilder.WEDNESDAY, 10, 42)
.inTimeZone(TimeZone.getTimeZone("America/Los_Angeles")))
.forJob(job)
.build();
inTimeZone belongs to withSchedule()
For example, I want to write a Java program to print "Hello World" at each day 12 am, how can I use Quartz scheduler to achieve this?
Trigger trigger = TriggerUtils.makeDailyTrigger(0, 0);
trigger.setName("trigger1");
trigger.setGroup("group1");
Like this? Where should I put print "hello world" method?
You could use an expression to schedule the execution of the job. e.g.:
public static class HelloJob implements Job {
#Override
public void execute(JobExecutionContext ctx) throws JobExecutionException {
System.out.println("Hello World");
}
}
public static void main(String[] args) throws SchedulerException {
String exp = "0 0 0 1/1 * ? *";
SchedulerFactory factory = new StdSchedulerFactory();
Scheduler scheduler = factory.getScheduler();
scheduler.start();
JobDetail job = JobBuilder.newJob(HelloJob.class).build();
Trigger trigger = TriggerBuilder.newTrigger()
.startNow()
.withSchedule(
CronScheduleBuilder.cronSchedule(exp))
.build();
scheduler.scheduleJob(job, trigger);
}
See http://www.cronmaker.com/ for build another expression. e.g. 0 0/1 * 1/1 * ? * every minute for to see the output. See also Cron Expressions.
Download quartz Jar Put in lib folder build project
Create Class (Job) from which you want to schedule task
import org.apache.log4j.Logger;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class MyJob implements Job {
private Logger log = Logger.getLogger(MyJob.class);
#Override
public void execute(JobExecutionContext context) throws JobExecutionException {
log.debug("Hi....");
System.out.println("Corn Executing.....");
}
}
Create Class for schedule your task
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 JobScheduler {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
JobDetail job = JobBuilder.newJob(MyJob.class).withIdentity("myjob").build();
Trigger trigger = TriggerBuilder.newTrigger().withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(30).repeatForever()).build();
SchedulerFactory schFactory = new StdSchedulerFactory();
Scheduler scheduler = schFactory.getScheduler();
scheduler.start();
scheduler.scheduleJob(job, trigger);
}catch (SchedulerException e) {
e.printStackTrace();
}
}
}
You have to create your custom job by implementing Job interface and providing your implementation of execute method.In execute method you can print "hello world". Then you can schedule your job like this
scheduler.scheduleJob(job, trigger);
Refer this link for step by step details:
Quartz tutorial
you can create cron expression for this. to have quartz job you need to have following objects
Job
Task which will be associated to a Job
Finally create a trigger and associate a Job to the trigger
Triggers of two type
Simple triggers, where you can control job , you can run every min or 10 mins and so on. you can also have additional parameters
initial delay - to kick off
repeatcount - no of times the job should be executes, if -1 then job will be executed infinitely
In your case you can use cron triggers since you want to run every day at 12 am.
For more details and sample program look at this below link
http://www.mkyong.com/spring/spring-quartz-scheduler-example/
and about quartz cron expression , see the quartz documentation
http://quartz-scheduler.org/documentation/quartz-1.x/tutorials/crontrigger
For the first time i stored the jobs and scheduled them using crontrigger with the below code.
package com.generalsentiment.test.quartz;
import static org.quartz.CronScheduleBuilder.cronSchedule;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.TriggerBuilder.newTrigger;
import java.util.Date;
import java.util.Properties;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
import org.quartz.SchedulerMetaData;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class CronTriggerExample {
public void run() throws Exception {
Logger log = LoggerFactory.getLogger(CronTriggerExample.class);
System.out.println("------- Initializing -------------------");
Xml config = new Xml("src/hibernate.cfg.xml", "hibernate-configuration");
Properties prop = new Properties();
prop.setProperty("org.quartz.scheduler.instanceName", "ALARM_SCHEDULER");
prop.setProperty("org.quartz.threadPool.class",
"org.quartz.simpl.SimpleThreadPool");
prop.setProperty("org.quartz.threadPool.threadCount", "4");
prop.setProperty("org.quartz.threadPool
.threadsInheritContextClassLoaderOfInitializingThread", "true");
prop.setProperty("org.quartz.jobStore.class",
"org.quartz.impl.jdbcjobstore.JobStoreTX");
prop.setProperty("org.quartz.jobStore.driverDelegateClass",
"org.quartz.impl.jdbcjobstore.StdJDBCDelegate");
prop.setProperty("org.quartz.jobStore.dataSource", "tasksDataStore");
prop.setProperty("org.quartz.jobStore.tablePrefix", "QRTZ_");
prop.setProperty("org.quartz.jobStore.misfireThreshold", "60000");
prop.setProperty("org.quartz.jobStore.isClustered", "false");
prop.setProperty("org.quartz.dataSource.tasksDataStore.driver",
config.child("session-factory").children("property").get(1).content());
prop.setProperty("org.quartz.dataSource.tasksDataStore.URL", config.child("session-
factory").children("property").get(2).content());
prop.setProperty("org.quartz.dataSource.tasksDataStore.user", config.child("session-
factory").children("property").get(3).content());
prop.setProperty("org.quartz.dataSource.tasksDataStore.password",
config.child("session-factory").children("property").get(4).content());
prop.setProperty("org.quartz.dataSource.tasksDataStore.maxConnections", "20");
// First we must get a reference to a scheduler
SchedulerFactory sf = new StdSchedulerFactory(prop);
Scheduler sched = sf.getScheduler();
System.out.println("------- Initialization Complete --------");
System.out.println("------- Scheduling Jobs ----------------");
// jobs can be scheduled before sched.start() has been called
// job 1 will run exactly at 12:55 daily
JobDetail job = newJob(SimpleJob.class).withIdentity("job2", "group2").build();
CronTrigger trigger = newTrigger().withIdentity("trigger2", "group2")
.withSchedule(cronSchedule("00 15 15 * *
?")).build();
Date ft = sched.scheduleJob(job, trigger);
System.out.println(sched.getSchedulerName());
System.out.println(job.getKey() + " has been scheduled to run at: " + ft
+ " and repeat based on expression: "
+ trigger.getCronExpression());
System.out.println("------- Starting Scheduler ----------------");
/*
* All of the jobs have been added to the scheduler, but none of the
* jobs will run until the scheduler has been started. If you have
* multiple jobs performing multiple tasks, then its recommended to
* write it in separate classes, like SimpleJob.class writes
* organization members to file.
*/
sched.start();
System.out.println("------- Started Scheduler -----------------");
System.out.println("------- Waiting five minutes... ------------");
try {
// wait five minutes to show jobs
Thread.sleep(300L * 1000L);
// executing...
} catch (Exception e) {
}
System.out.println("------- Shutting Down ---------------------");
sched.shutdown(true);
System.out.println("------- Shutdown Complete -----------------");
SchedulerMetaData metaData = sched.getMetaData();
System.out.println("Executed " + metaData.getNumberOfJobsExecuted() + " jobs.");
}
public static void main(String[] args) throws Exception {
CronTriggerExample example = new CronTriggerExample();
example.run();
}
}
And the details are stored in Tables - QRTZ_CRON_TRIGGERS, QRTZ_JOB_DETAILS & QRTZ_TRIGGERS
My doubt is How to schedule the jobs that are stored in DB. How to display the list of jobs in a jsp page & how to trigger them automatically.
Ours is a struts2 application with Hibernate3 ORM. I am trying to initialize the quartz scheduler when the application loads. But am unable to.
Date ft = sched.scheduleJob(job, trigger);
When this is called, your job would be scheduled for the next fire time. The scheduled job would stored in the appropriate DB tables.
To Display the list of jobs on a jsp, you should persist you job key as well as custom description of what your job entails to another DB table so that during retrieval you can retrieve this custom description as well as data Quartz persist into its own tables.
Triggering this jobs automatically is something Quartz handles for you. Once the crone expression is set to what is desired and your Job class implements org.quartz.Job, Quartz would run the execute() method at your desired next fire time
JobDetail job = newJob(SimpleJob.class).withIdentity("job2", "group2").build();
this means you will have a class named SimpleJob that implements org.quartz.Job. In that class execute() method need to be implemented. Job is triggered automatically at the time you specified by cron expression. That execute method is called when job is triggered.