I'm try to use quartz scheduler in spring. I get below exception when configuring multiple jobs
Parameter 0 of method jobTrigger in Job2 required a bean of type 'org.quartz.JobDetail' that could not be found.
quartz - v2.3, Spring - v4.2.x
Config Class
@Configuration
public class SchedulerConfig {
private static final Logger LOG = LoggerFactory.getLogger(SchedulerConfig.class);
@Autowired
List<Trigger> triggers;
@Bean
public JobFactory jobFactory(ApplicationContext applicationContext) {
AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
jobFactory.setApplicationContext(applicationContext);
return jobFactory;
}
@Bean
public SchedulerFactoryBean schedulerFactoryBean(JobFactory jobFactory) throws IOException {
SchedulerFactoryBean factory = new SchedulerFactoryBean();
factory.setAutoStartup(true);
factory.setJobFactory(jobFactory);
factory.setQuartzProperties(quartzProperties());
if (triggers != null && !triggers.isEmpty()) {
LOG.info("starting jobs... Total Triggers - " + triggers.size());
factory.setTriggers(triggers.toArray(new Trigger[triggers.size()]));
}
return factory;
}
@Bean
public Properties quartzProperties() throws IOException {
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));
propertiesFactoryBean.afterPropertiesSet();
return propertiesFactoryBean.getObject();
}
public static CronTriggerFactoryBean createCronTrigger(JobDetail jobDetail, String cronExpression) {
CronTriggerFactoryBean factoryBean = new CronTriggerFactoryBean();
factoryBean.setJobDetail(jobDetail);
factoryBean.setCronExpression(cronExpression);
factoryBean.setMisfireInstruction(SimpleTrigger.MISFIRE_INSTRUCTION_FIRE_NOW);
return factoryBean;
}
public static JobDetailFactoryBean createJobDetail(Class jobClass) {
JobDetailFactoryBean factoryBean = new JobDetailFactoryBean();
factoryBean.setJobClass(jobClass);
factoryBean.setDurability(true);
return factoryBean;
}
SpringBeanJobFactory
public final class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {
private static final Logger LOG = LoggerFactory.getLogger(AutowiringSpringBeanJobFactory.class);
private transient AutowireCapableBeanFactory beanFactory;
@Override
public void setApplicationContext(final ApplicationContext context) {
beanFactory = context.getAutowireCapableBeanFactory();
}
@Override
protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
final Object job = super.createJobInstance(bundle);
LOG.info("create job instance");
beanFactory.autowireBean(job);
return job;
}
}
Job 1
@Component
@DisallowConcurrentExecution
public class Job1 implements Job {
private final Logger log = LoggerFactory.getLogger(this.getClass());
@Value("${schedule}")
private String frequency;
@Autowired
private Service service;
@Override
public void execute(JobExecutionContext jobExecutionContext) {
log.info("execute");
}
@Bean(name = "jobBean1")
public JobDetailFactoryBean job() {
return SchedulerConfig.createJobDetail(this.getClass());
}
@Bean(name = "jobBean1Trigger")
public CronTriggerFactoryBean jobTrigger(@Qualifier("jobBean1")JobDetail jobDetail) {
return SchedulerConfig.createCronTrigger(jobDetail, frequency);
}
Job 2
@Component
@DisallowConcurrentExecution
public class Job2 implements Job {
private final Logger log = LoggerFactory.getLogger(this.getClass());
@Value("${schedule}")
private String frequency;
@Autowired
private Service service;
@Override
public void execute(JobExecutionContext jobExecutionContext) {
log.info("execute");
}
@Bean(name = "jobBean2")
public JobDetailFactoryBean job() {
return SchedulerConfig.createJobDetail(this.getClass());
}
@Bean(name = "jobBean2Trigger")
public CronTriggerFactoryBean jobTrigger(@Qualifier("jobBean2")JobDetail jobDetail) {
return SchedulerConfig.createCronTrigger(jobDetail, frequency);
}
The Service class has Spring JPA repos. The root cause of the problem is the below autowired service. If I remove the below autowired service from both the jobs, it works fine.
@Autowired private Service service;
If there is only one job with this autowired bean, then there is no exception. How to configure multiple jobs using the same autowired dependency? What is cause this issue?