I was able to do this using the Spring Scheduling Framework successfully.
I understand that this is a very old post, but since the content on this topic is rather scarce, it is better to post it here.
The main problem in the code for the first message is that afterPropertiesSet() not called for both the JobDetail object and the CronTrigger object. The afterProperties function does some processing of the entered values ββbefore cron is ready to run.
In addition, I used MethodInvokingJobDetailFactoryBean instead of the regular JobDetail , since it gives more flexibility to the function that cron will call in this class.
Here is my code:
package test.spring; import org.quartz.JobDetail; import org.quartz.Trigger; import org.springframework.context.support.GenericApplicationContext; import org.springframework.scheduling.SchedulingException; import org.springframework.scheduling.quartz.CronTriggerBean; import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean; import org.springframework.scheduling.quartz.SchedulerFactoryBean; import java.text.ParseException; public class ProgrammaticCron { public static void callWorkFlow() { System.out.println("Abhishek Jain"); } public static void main (String[] args) { try { GenericApplicationContext applicationContext = new GenericApplicationContext(); MethodInvokingJobDetailFactoryBean jdfb = new MethodInvokingJobDetailFactoryBean(); jdfb.setTargetClass(ProgrammaticCron.class); jdfb.setTargetMethod("callWorkFlow"); jdfb.setName("Trial program"); jdfb.afterPropertiesSet(); JobDetail jd = (JobDetail)jdfb.getObject(); CronTriggerBean ctb = new CronTriggerBean(); ctb.setJobDetail(jd); ctb.setName("Daily cron"); ctb.setJobName(jd.getName()); try { ctb.setCronExpression("59 * * * * ? *"); } catch (ParseException e) { e.printStackTrace(); } ctb.afterPropertiesSet(); SchedulerFactoryBean sfb = new SchedulerFactoryBean(); sfb.setJobDetails(new JobDetail[]{(JobDetail)jdfb.getObject()}); sfb.setTriggers(new Trigger[]{ctb}); sfb.afterPropertiesSet(); try { sfb.start(); } catch (SchedulingException e) { e.printStackTrace(); } } catch (Exception e) { e.printStackTrace(); } } }
afterProperties() important, and from the afterProperties implementation of SchedulerFactoryBean you can understand that:
//--------------------------------------------------------------------- // Implementation of InitializingBean interface //--------------------------------------------------------------------- public void afterPropertiesSet() throws Exception { if (this.dataSource == null && this.nonTransactionalDataSource != null) { this.dataSource = this.nonTransactionalDataSource; } if (this.applicationContext != null && this.resourceLoader == null) { this.resourceLoader = this.applicationContext; } // Create SchedulerFactory instance. SchedulerFactory schedulerFactory = (SchedulerFactory) BeanUtils.instantiateClass(this.schedulerFactoryClass); initSchedulerFactory(schedulerFactory); if (this.resourceLoader != null) { // Make given ResourceLoader available for SchedulerFactory configuration. configTimeResourceLoaderHolder.set(this.resourceLoader); } if (this.taskExecutor != null) { // Make given TaskExecutor available for SchedulerFactory configuration. configTimeTaskExecutorHolder.set(this.taskExecutor); } if (this.dataSource != null) { // Make given DataSource available for SchedulerFactory configuration. configTimeDataSourceHolder.set(this.dataSource); } if (this.nonTransactionalDataSource != null) { // Make given non-transactional DataSource available for SchedulerFactory configuration. configTimeNonTransactionalDataSourceHolder.set(this.nonTransactionalDataSource); } // Get Scheduler instance from SchedulerFactory. try { this.scheduler = createScheduler(schedulerFactory, this.schedulerName); populateSchedulerContext(); if (!this.jobFactorySet && !(this.scheduler instanceof RemoteScheduler)) { // Use AdaptableJobFactory as default for a local Scheduler, unless when // explicitly given a null value through the "jobFactory" bean property. this.jobFactory = new AdaptableJobFactory(); } if (this.jobFactory != null) { if (this.jobFactory instanceof SchedulerContextAware) { ((SchedulerContextAware) this.jobFactory).setSchedulerContext(this.scheduler.getContext()); } this.scheduler.setJobFactory(this.jobFactory); } } finally { if (this.resourceLoader != null) { configTimeResourceLoaderHolder.remove(); } if (this.taskExecutor != null) { configTimeTaskExecutorHolder.remove(); } if (this.dataSource != null) { configTimeDataSourceHolder.remove(); } if (this.nonTransactionalDataSource != null) { configTimeNonTransactionalDataSourceHolder.remove(); } } registerListeners(); registerJobsAndTriggers(); }
As you can see, all tasks such as getting a scheduler and registering a task using triggers are performed as part of this function.
source share