4

I am configuring Quartz job with Spring boot. The requirement is to execute the job immediately without attaching any schedule.

Here is what my code looks like

JobDetailFactoryBean factoryBean = new JobDetailFactoryBean();

String jobName = jobName(taskContext);

factoryBean.setJobClass(MyJobClass.class);
factoryBean.setDurability(true);
factoryBean.setApplicationContext(applicationContext);
factoryBean.setName("Hello job");
factoryBean.setGroup("Hello job group");

JobDataMap jobData = new JobDataMap(new HashMap<>());
factoryBean.setJobDataMap(jobData);
factoryBean.afterPropertiesSet();

JobDetail job = factoryBean.getObject();
Scheduler scheduler = schedulerFactoryBean.getScheduler();
scheduler.addJob(job, replace);
scheduler.triggerJob(job.getKey());

And here is how quartz.properties looks like

org.quartz.scheduler.instanceName=springBootQuartzApp
org.quartz.scheduler.instanceId=AUTO
org.quartz.threadPool.threadCount=10
org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
org.quartz.jobStore.useProperties=true
org.quartz.jobStore.misfireThreshold=2000
org.quartz.jobStore.tablePrefix=qrtz_
org.quartz.jobStore.isClustered=false
org.quartz.plugin.shutdownHook.class=org.quartz.plugins.management.ShutdownHookPlugin
org.quartz.plugin.shutdownHook.cleanShutdown=TRUE

The problem is that the job is not firing immediately and is getting picked up as misfire instruction. It is executed right exactly after the misfireThreshold.

Please let me know, if I have missed something in the configuration or didn't call any appropriate API.

CuriousMind
  • 3,143
  • 3
  • 29
  • 54
  • If your requirement is to execute the job immediately without attaching any schedule, then why are you using Quartz scheduler? You can use other means to get this job done! – Ketan Jan 15 '19 at 02:17
  • Retry, tracking of tasks, async execution, unified design for a scheduled and non-scheduled task. Most of these features are already built-in. In short DRY. – CuriousMind Jan 15 '19 at 04:04
  • How about an implementation of org.quartz.SchedulerListener interface and then the method that you are interested in is 'void schedulerStarted();'. So when your scheduler is starting you will get this event and do the things now. Just a caution, it may call this method everytime your start it after pausing the scheduler - so you might need a mechanism to tackle that! – Ketan Jan 16 '19 at 03:17
  • org.quartz.threadPool.threadCount=10, so any other jobs more than 10 on current running schedule? did you execute this code on application starting up? or call it from a rest API? – meadlai Nov 15 '19 at 09:26

1 Answers1

0

I got the same issue.

If your quartz is using a data source with transaction: @EnableTransactionManagement. Please add @Transactional to the method of your code, then the transaction is committed immediately. Later the scheduler thread looks up the db again and fire it finally.

meadlai
  • 895
  • 1
  • 9
  • 22