0
votes

I just started to create Quartz Scheduled Jobs in a dynamic way. So there is a QuartzConfig class where I create a SchedulerFactoryBean, JobDetailFactoryBean and CronTriggerFactoryBean. Wherein the Job and CronTrigger beans are prototype ones.

@Configuration
public class QuartzConfig {

    @Autowired
    ApplicationContext context;;

    @Bean
    public SchedulerFactoryBean quartzScheduler(){
        SchedulerFactoryBean quartzScheduler = new SchedulerFactoryBean();
        quartzScheduler.setOverwriteExistingJobs(true);
        quartzScheduler.setSchedulerName("job-scheduler");
        AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
        jobFactory.setApplicationContext(context);
        quartzScheduler.setJobFactory(jobFactory);
        return quartzScheduler;
    }

    @Bean
    @Scope(value = "prototype")
    public JobDetailFactoryBean getJobBean(){
        JobDetailFactoryBean bean = new JobDetailFactoryBean();
        bean.setJobClass(DailyJob.class);
        bean.setGroup("daily-group");
        bean.setName("daily-name");
        bean.setBeanName("daily-name");
        bean.getJobDataMap().put("daily", "daily");
        return bean;
    }

    @Bean
    @Scope(value = "prototype")
//    @Lazy(value = true)
    public CronTriggerFactoryBean getCronTriggerBean(String cron){
        CronTriggerFactoryBean bean = new CronTriggerFactoryBean();
        bean.setCronExpression(cron);
        bean.setJobDetail(getJobBean().getObject());
        bean.setGroup("daily-group");
        return bean;
    }
}

In my Controller class I want to create the jobs by request. I autowire SchedulerFactoryBean to set the quartz trigger to the bean.

@Controller
public class JobController {

    @Autowired
    SchedulerFactoryBean quartzScheduler;

    @Autowired
    ApplicationContext context;;

    @ResponseBody
    @RequestMapping("/job/create/daily")
    public String dailyJob(){
        CronTriggerImpl cron = (CronTriggerImpl) context.getBean("getCronTriggerBean","30 * * ? * MON-FRI");
        Trigger[] triggers = { cron };
        quartzScheduler.setTriggers(triggers);
        return "dailyJob";
    }
}

Everything works without creating an error and the Job and the Trigger are set to the quartzScheduler (see it in debug mode). But the Job is never running. What do I miss?

And dont to forget, there is a class which implements Job:

@Component
public class DailyJob implements Job{

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        System.out.println("Daily Job runs!");
    }
}
2
Do you see your triggers in the TRIGGERS table? If yes, what state do they have? - ledniov
@ledniov you mean a triigers table in DB? I dont use one at the moment. All is setting up by context and will destroyed after shutdown. - Patrick
Can you try injecting Scheduler instead of SchedulerFactoryBean and use scheduler.scheduleJob(cron)? - ledniov
@ledniov tried it. Got this exception. org.quartz.JobPersistenceException: The job (daily-group.daily-name) referenced by the trigger does not exist. Any idea? - Patrick

2 Answers

1
votes

Here is what worked for me:

@Controller
public class JobController {

    @Autowired
    private Scheduler scheduler;

    @Autowired
    private ApplicationContext context;

    @ResponseBody
    @RequestMapping("/job/create/daily")
    public String dailyJob() throws SchedulerException {
        JobDetail jobDetail = context.getBean(JobDetail.class);
        Trigger cronTrigger = context.getBean(Trigger.class, "30 * * ? * MON-FRI");

        scheduler.scheduleJob(jobDetail, cronTrigger);

        return "dailyJob";
    }
}

You have to use Scheduler instead of SchedulerFactoryBean as the purpose of the latter is to create the actual scheduler that will operate on jobs.

Also if you use scheduler.scheduleJob(cron) it woun't schedule the job because it isn't in the job store yet, so you'll need to create a job using it's details and associate cron expression with it.

0
votes

Try addding "@EnableScheduling" to your configuration