I am trying to learn quartz. I have main method
public static void main(String[] args) throws SchedulerException {
try {
JobDetail job1 = JobBuilder.newJob(Job1.class).withIdentity("job1", "group1").build();
Trigger trigger1 = TriggerBuilder.newTrigger().withIdentity("cronTrigger1", "group1")
.withSchedule(CronScheduleBuilder.weeklyOnDayAndHourAndMinute(3, 12, 38)).build();
Scheduler scheduler1 = new StdSchedulerFactory().getScheduler();
scheduler1.start();
scheduler1.scheduleJob(job1, trigger1);
scheduler1.shutdown();
}
catch (Exception e) {
e.printStackTrace();
}
Which works fine. It prints to the console on 3rd day of the week at 12:38 pm.
Now, what I want to do is to reschedule the trigger, so that it deletes the previous stored trigger and creates a new trigger with new schedule.
I read a lot of things at a lot of places but I just can't seem to understand clearly what I actually have to do, for ex:
public void execute(JobExecutionContext context) throws JobExecutionException {
Trigger newTigger = what ever you want;
Trigger oldTrigger = context.getTrigger()
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.rescheduleJob(oldTrigger.getKey(), newTrigger);
}
tell the scheduler to remove the old trigger with the given key, and
put the new one in its place*
but I can't understand the approach(I do understand what is happening in the code though). Thanks in advance.
Related
I need to schedule some periodic jobs and I have hit a roadblock with Quartz.
For example:
I do not think this is possible with Quartz (with a single expression/job):
Run a job every day between 8:30 and 12:45, with a period of five minutes. E.g. 8:30, 8:35, 8:40, .... 12:40, 12:45.
If it was between 8:00 and 12:00 it would be easy but I could not find a way to schedule it except handling 8:30-9:00 and 12:00-12:45 with separate expressions, which I do not want to.
Am I wrong in assuming that this is non-trivial with Quartz? I have also searched for some alternatives but most seem to have a similar cron syntax and I am not sure they could handle it either.
Is there a finer-grained scheduling library that I can use in this scenario?
This is perfectly possible with Quartz and a single trigger. People often focus on Cron triggers, but Quartz supports other trigger types and these are often more suitable. To implement your scheduling scenario, I recommend that you look into the Quartz DailyTimeIntervalTrigger.
In the screenshot below you can see a DailyTimeIntervalTrigger example with attribute values to cover your use-case.
I'm not certain you can do this, as you've hinted at. It seems possible to create a custom Trigger to do it, but then it becomes quite a bit of work. The other option is to split the dual Triggers by day, not time.
public class TestQuartz {
class ActualJob implements Job {
#Override
public void execute(JobExecutionContext context)
throws JobExecutionException {
}
}
class DailyJob implements Job {
#Override
public void execute(JobExecutionContext context)
throws JobExecutionException {
// Run from now (8:45) every 5 minutes until 12:45 (endDate)
Trigger trigger =
newTrigger()
.startNow()
.endAt(endDate) // 12:45 PM TODAY
.withSchedule(
cronSchedule("0 0/5 * 1/1 * ? *"))
.build();
try {
Scheduler sched = context.getScheduler();
sched.scheduleJob(newJob(ActualJob.class).build(), trigger);
} catch (SchedulerException ex) {
throw new JobExecutionException(ex);
}
}
}
#Test
public void testQuartz() throws SchedulerException {
SchedulerFactory sf = new StdSchedulerFactory();
Scheduler sched = sf.getScheduler();
// Run once a day starting at 8:45 AM
Trigger dailyTrigger =
newTrigger().withSchedule(cronSchedule("0 45 8 1/1 * ? *")).build();
JobDetail job = newJob(DailyJob.class).build();
sched.scheduleJob(job, dailyTrigger);
}
}
I work with Quartz lib and I have simple code like this:
public void run() {
try {
SchedulerFactory factory = new StdSchedulerFactory();
Scheduler scheduler = factory.getScheduler();
scheduler.start();
JobDetail job = JobBuilder
.newJob(HelloWorldJob.class)
.withIdentity("tJob")
.build();
Trigger t = TriggerBuilder
.newTrigger()
.withIdentity("tTrigger")
.startNow()
.withSchedule(CronScheduleBuilder.dailyAtHourAndMinute(19, 50).inTimeZone(TimeZone.getDefault()))
.build();
scheduler.scheduleJob(job, t);
} catch (Exception e) {
e.printStackTrace();
}
}
And Job class:
public class HelloWorldJob implements Job {
#Override
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("HELLO WORLD");
}
}
19:50 - is a time when i expected to see the result.
But it does not work.
What is wrong with this part of code?
Maybe i forgot something. Please, help me.
P.S. I tried with .inTimeZone(TimeZone.getDefault()) and without it. And i hade same result in both.
Holy moly
Today it's work fine. But i swear, yesterday it didn't work.
Maybe problem in time visualization?
Today i set 11 hour and 52 minutes. And it works fine in 11:52 and write "Hello" to console, but yesterday i have written 19:50 and it did not work.
Should i write in another time system? With A.M/P.M?
Or what the hell?
I am using quartz with cron to schedule 2 jobs . One runs at 12:00 and the other at 14:00 and it runs perfectly. Here's my code.
#Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
JobDetail job1 = JobBuilder.newJob(FirstInvoiceGeneration.class)
.withIdentity("FirstInvoiceGenerationJob", "group1").build();
Trigger trigger1 = TriggerBuilder
.newTrigger()
.withIdentity("FirstInvoiceGenerationTrigger", "group1")
.withSchedule(CronScheduleBuilder.cronSchedule("0 0 12 * * ?")).build();
//Simple invoice generation to check which invoice to be generated today
JobDetail job2 = JobBuilder.newJob(TodayInvoiceGeneration.class)
.withIdentity("TodayInvoiceGenerationJob", "group1").build();
Trigger trigger2 = TriggerBuilder
.newTrigger()
.withIdentity("TodayInvoiceGenerationTrigger", "group1")
.withSchedule(CronScheduleBuilder.cronSchedule(0 0 14 * * ?")).build();
//Schedule it
Scheduler scheduler;
try {
scheduler = new StdSchedulerFactory().getScheduler();
scheduler.start();
scheduler.scheduleJob(job1, trigger1);
scheduler.scheduleJob(job2, trigger2);
} catch (SchedulerException e) {
e.printStackTrace();
}
}}
My two classes for running two jobs are :
public class FirstInvoiceGeneration implements Job {
#Override
public void execute(JobExecutionContext arg0)
throws JobExecutionException {
System.out.println("Listener running.");
}
}
my second class for second job is
public class FirstInvoiceGeneration implements Job {
#Override
public void execute(JobExecutionContext arg0)
throws JobExecutionException {
System.out.println("Listener running.");
}
}
Now this runs perfectly , but what i want to do is to have 1 job that runs these two codes. Now i can use this cron expression --> "0 0 12,14 * * ?"
this will make the job run at 12pm , 2pm (my guess :p ). But i want to have only one class that execute one code when time is 12pm and other when time is 2pm. So can someone tell me how i can do it?
Reference. As you can see you can send data to a job by usingJobData() method to a job e.g. ("WORK","FIRST"),("WORK","SECOND").
In a single job class only check for the WORK key and accordingly do the operations you want to do. JobExecutionContext you can retrieve the job data using context.getJobDetails().getJobDataMap()
I need to execute scheduler immediately when I will call the scheduler and next time it will execute base on the cron expression. But here my code which is only executing after 10 minute but not executing when I run this class/application.
QuartzConfigure.java for registering and calling the execute method:
public class QuartzConfigure {
public static void main(String args[]) throws Exception {
// specify the job' s details..
JobDetail job = JobBuilder.newJob(QuartzSchduleJob.class)
.withIdentity("testJob")
.build();
//this is specify using chron expression using chrone expression
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("Group2")
.withSchedule(CronScheduleBuilder.cronSchedule("0 /10 * * * ?"))
.startNow().build();
//schedule the job
SchedulerFactory schFactory = new StdSchedulerFactory();
Scheduler sch = schFactory.getScheduler();
sch.start();
sch.scheduleJob(job, trigger);
}
}
QuartzSchduleJob.java for job:
public class QuartzSchduleJob implements Job {
#Override
public void execute(JobExecutionContext arg0) throws JobExecutionException {
System.out.println("calling jobSchedulling::"+System.currentTimeMillis());
}
}
With your current code, your 'scheduler' starts immediatly after sch.start(), so I am guessing you want to know how force your Job to trigger when your 'scheduler' starts.
If so, you can not achieve this with only a cron expression but I have two solutions for you.
If you want your Job to be trigger at start and then every ten minutes after, consider using a SimpleScheduleBuilder. In your code, replace the CronExpressionSchedule :
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger1", "Group2")
.withSchedule(ScheduleBuilder.simpleSchedule()
.withIntervalInMinutes(10)
.repeatForever())
.startNow()
.build();
If you want your Job to trigger at start and then fires on a scheduling based on your Cron expression. Consider using a second trigger :
[...]
Trigger trigger2 = TriggerBuilder.newTrigger()
.withIdentity("trigger2", "Group2")
.withSchedule(ScheduleBuilder.simpleSchedule())
.startNow()
.build();
[...]
sch.start();
sch.scheduleJob(job, trigger);
sch.scheduleJob(job, trigger2);
I looked all over the place. I looked through Timers and Quartz and I am still confused.
I have a huge class performing different methods. One of those methods is a synchronized method:
public void onSynch()
{
String environment = validateEnvironment(env2);
if (environment == null) return;
try
{
RAT.synchronize(environment);
onSelectEnv();
}
catch (Exception e)
{
// TODO: tell user, log
}
}
I need to be able to create a timer that triggers this method alone once a week at a particular time, every Friday and 3:00 PM for example.
I cannot create separate classes.
I need to be able to put the scheduler inside of this method, or create another method next to it that would create a scheduler and run that sync method.
I would like to suggest to use QUARTZ or Spring Batch for scheduler job.
Try below Quartz Example.
Reference : CronTrigger Tutorial, Example
YourJob.java
public class YourJob implements Job {
public void execute(JobExecutionContext context) throws JobExecutionException {
//here your operation
}
}
MySchedule.java
public class MySchedule {
public void startUp() throws Exception {
SchedulerFactory sf = new StdSchedulerFactory();
Scheduler scheduler = sf.getScheduler();
JobDetail yourJob = JobBuilder.newJob(YourJob.class).withIdentity("job1", "group1").build();
/*Run every 30 seconds on Weekdays (Monday through Friday)*/
Trigger trigger_1 = TriggerBuilder.newTrigger()
.withIdentity("trigger1", "group1")
.withSchedule(CronScheduleBuilder.cronSchedule("0,30 * * ? * MON-FRI"))
.build();
/*Run at 10am on the 1st and 15th days of the month*/
Trigger trigger_2 = TriggerBuilder.newTrigger()
.withIdentity("trigger2", "group1")
.withSchedule(CronScheduleBuilder.cronSchedule("0 0 10am 1,15 * ?"))
.build();
/*Run at 3:30PM of every friday f month*/
Trigger trigger_3 = TriggerBuilder.newTrigger()
.withIdentity("trigger3", "group1")
.withSchedule(CronScheduleBuilder.cronSchedule("0 18 30 ? * 6"))
.build();
scheduler.start();
scheduler.scheduleJob(yourJob, trigger_1);
scheduler.scheduleJob(yourJob, trigger_2);
scheduler.scheduleJob(yourJob, trigger_3);
}
}