Can I use Quartz Scheduler library to create schedule with following settings?:
So, the resulting schedule will be:
From what I've learned:
CalendarIntervalTrigger will skip months that don't have 30th day (trigger created by following code)
try {
SchedulerFactory schedulerFactory = new StdSchedulerFactory();
Scheduler scheduler = schedulerFactory.getScheduler();
scheduler.start();
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)
.withIdentity("HelloJob_CalendarIntervaled", "calendarIntervaled")
.build();
Calendar decemberThirty = Calendar.getInstance();
decemberThirty.set(Calendar.YEAR, 2014);
decemberThirty.set(Calendar.MONTH, Calendar.DECEMBER);
decemberThirty.set(Calendar.DAY_OF_MONTH, 30);
CalendarIntervalTrigger calendarIntervalTrigger = newTrigger()
.withIdentity("calendarIntervalTrigger", "calendarIntervaled")
.withSchedule(CalendarIntervalScheduleBuilder.calendarIntervalSchedule()
.withIntervalInMonths(2))
.startAt(decemberThirty.getTime())
.forJob(jobDetail)
.build();
scheduler.scheduleJob(jobDetail, calendarIntervalTrigger);
System.out.println(calendarIntervalTrigger.getNextFireTime());
} catch (SchedulerException e) {
e.printStackTrace();
}
If no, are there any alternatives (it should work on JBoss eap 6.2.0)?
However the scheduler was not capable of running jobs at 9 and 10 AM and it discovered that fact at 10:15 AM, i.e. 2 firings misfired. This is a more general situation compared to simple trigger running fixed number of times. CRON triggers are the most popular ones amongst Quartz users.
The situation when Quartz was incapable of firing given trigger is called misfire. Do you know what Quartz is doing when it happens? Turns out there are various strategies (called misfire instructions) Quartz can take and also there are some defaults if you haven’t thought about it.
Quartz is distributed as a small java library (.jar file) that contains all of the core Quartz functionality. The main interface (API) to this functionality is the Scheduler interface. It provides simple operations such as scheduling/unscheduling jobs, starting/stopping/pausing the scheduler.
The most common reason for this is not having called Scheduler.Start () , which tells the scheduler to start firing triggers. The second most common reason is that the trigger or trigger group has been paused. CronTrigger and SimpleTrigger each handle daylight savings time in their own way - each in the way that is intuitive to the trigger type.
You can achieve this in Quartz but you got to twist the normal behaviour by using a CalendarIntervalTrigger
to trigger a Job that calculate when your 'real' Job should be scheduled.
You schedule a trigger that fire every 1st of your scheduling months :
[...]
JobDetail jobDetail = newJob(SchedulingCalculationJob.class)
.withIdentity("SchedulingCalculation_CalendarIntervaled", "calendarIntervaled")
.build();
CalendarIntervalTrigger calendarIntervalTrigger = newTrigger()
.withIdentity("calendarIntervalCalculationTrigger", "calendarIntervaled")
.withSchedule(calendarIntervalSchedule()
.withIntervalInMonths(2))
.startAt(decemberFirst.getTime())
.forJob(jobDetail)
.build();
scheduler.scheduleJob(jobDetail, calendarIntervalTrigger);
And in the SchedulingCalculationJob
Job, you calculate your 'real' Job scheduling day :
public class SchedulingCalculationJob implements Job {
public void execute(JobExecutionContext context)
throws JobExecutionException {
Calendar calendar = calculateJobFiringDate();
// Create and schedule a dedicated trigger
Trigger calculateFiring = calculateFiring = newTrigger()
.withSchedule(SimpleSchedulerBuilder.simpleScheduler())
.startAt(calendar.getTime())
.forJob(yourRealJobDetail)
.build();
scheduler.scheduleJob(yourRealJobDetail, calculateFiring);
}
public static Calendar calculateJobFiringDate() {
Calendar result = Calendar.getInstance();
// Set up the scheduling day
if (isThereThirtyDaysInCurrentMonth()) {
// the 30th of the current month
calendar.set(Calendar.DAY_OF_MONTH, 30);
} else {
// the last day of the current month
calendar.add(Calendar.MONTH, 1);
calendar.add(Calendar.DATE, -1);
}
// Set up time of day
calendar.set(Calendar.HOUR, ...);
calendar.set(Calendar.MINUTE, ...);
calendar.set(Calendar.SECOND, ...);
return result;
}
public static boolean isThereThirtyDaysInCurrentMonth() {
Calendar thirtydaysInCurrentMonthCalendar = Calendar.getInstance();
Integer currentMonth = thirtydaysInCurrentMonthCalendar.get(Calendar.MONTH);
thirtydaysInCurrentMonthCalendar.add(Calendar.DATE, 29);
return (currentMonth == thirtydaysInCurrentMonthCalendar.get(Calendar.MONTH);
}
}
It's a bit sioux but I already use it and i works fine.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With