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)?
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.