#java #spring #spring-boot #quartz-scheduler
#java #весна #весенняя загрузка #quartz-планировщик
Вопрос:
Я пытаюсь внедрить зависимости в задания Quartz, но всякий раз, когда запускается мое задание, у меня возникает исключение NullPointerException для моего внедренного сервиса.
Я следил за несколькими руководствами / блогами о том, как решить эту проблему, но она остается.
Обратите внимание, что я буду создавать несколько заданий в рамках первого задания в зависимости от некоторой бизнес-логики. /! : В то время как debugging : JobExecutionContext.getScheduler().getContext().get(«ApplicationContext») равно нулю, Все, что касается создания заданий и триггеров (даже CRON), является хорошим. единственная проблема в том, что у меня всегда есть NPE в «campagneService».
Моя работа:
@Component
@DisallowConcurrentExecution
public class CreateAndCheckFirstCommandeJob implements Job {
@Autowired
private CampagneService campagneService;
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
*** buisiness Logic ****
Scheduler scheduler = new StdSchedulerFactory().getScheduler();
scheduler.start();
JobDetail jobDetail= QuartzConfig.createQuartzJobDetail(a,b,c );
Trigger trigger= QuartzConfig.createQuartzSimpleTrigger(x, y, z ,t);
scheduler.scheduleJob(jobDetail, trigger);
}
}
Конфигурация :
@Configuration
public class QuartzConfig {
private ApplicationContext applicationContext;
public QuartzConfig(ApplicationContext applicationContext, DataSource dataSource) {
this.applicationContext = applicationContext;
this.dataSource = dataSource;
}
@Bean
public SpringBeanJobFactory springBeanJobFactory() {
AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
jobFactory.setApplicationContext(applicationContext);
return jobFactory;
}
@Bean
public SchedulerFactoryBean scheduler(Trigger... triggers) {
SchedulerFactoryBean schedulerFactory = new SchedulerFactoryBean();
Properties properties = new Properties();
properties.setProperty("org.quartz.scheduler.instanceName", "SCHEDULER");
properties.setProperty("org.quartz.scheduler.instanceId", "Scheduler-1");
schedulerFactory.setOverwriteExistingJobs(true);
schedulerFactory.setAutoStartup(true);
schedulerFactory.setQuartzProperties(properties);
schedulerFactory.setDataSource(dataSource);
schedulerFactory.setJobFactory(springBeanJobFactory());
schedulerFactory.setWaitForJobsToCompleteOnShutdown(true);
if (ArrayUtils.isNotEmpty(triggers)) {
schedulerFactory.setTriggers(triggers);
}
return schedulerFactory;
}
static JobDetail createQuartzJobDetail(Class jobClazz, String jobGroup, Map<String, Object> jobDataMap) {
String jobName = jobClazz.getSimpleName()
JobKey jobUniqueKey = new JobKey(jobName, jobGroup);
JobDetail jobDetail = JobBuilder.newJob(jobClazz)
.withIdentity(jobUniqueKey).build();
return jobDetail;
}
static Trigger createQuartzSimpleTrigger(JobDetail jobDetail,String triggerName, String triggerGroup, Date startingDate) {
return TriggerBuilder.newTrigger()
.withIdentity(triggerName , triggerGroup).forJob(jobDetail)
.startAt(startingDate)
.build();
}
static Trigger createQuartzCronTrigger(JobDetail jobDetail, String triggerName, String triggerGroup, Date endDate, String cronExpression) {
return TriggerBuilder.newTrigger()
.withIdentity( triggerName, triggerGroup)
.withSchedule(
CronScheduleBuilder.cronSchedule(cronExpression))
.endAt(endDate).forJob(jobDetail)
.build();
}
}
AutowiringSpringJobFactory:
public final class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {
private AutowireCapableBeanFactory beanFactory;
@Override
public void setApplicationContext(final ApplicationContext ctx) {
beanFactory = ctx.getAutowireCapableBeanFactory();
}
@Override
protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
final Object job = super.createJobInstance(bundle);
beanFactory.autowireBean(job);
return job;
}
}
структура стека (в случае: D )
в строке 71 я вызываю свою службу (this.campagneService.xxx)
2020-08-31 15:56:24.647 ERROR 8056 --- [eduler_Worker-1] org.quartz.core.JobRunShell : Job Cammande.CreateAndCheckPremiereCommandeJob15:56:14.434 threw an unhandled Exception:
java.lang.NullPointerException: null
at com.gtmt.scheduler.quartz.config.CreateAndCheckFirstCommandeJob.execute(CreateAndCheckFirstCommandeJob.java:71)
at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)
2020-08-31 15:56:24.650 ERROR 8056 --- [eduler_Worker-1] org.quartz.core.ErrorLogger : Job (Cammande.CreateAndCheckFirstCommandeJob15:56:14.434 threw an exception.
org.quartz.SchedulerException: Job threw an unhandled exception.
at org.quartz.core.JobRunShell.run(JobRunShell.java:213)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)
Caused by: java.lang.NullPointerException: null
at com.gtmt.scheduler.quartz.config.CreateAndCheckFirstCommandeJob.execute(CreateAndCheckFirstCommandeJob.java:71)
at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
... 1 common frames omitted
Thanks.
Комментарии:
1. Не могли бы вы опубликовать трассировку стека исключений?
2. @VijayC: я добавил трассировку стека в сообщение
3. Основываясь на трассировке, я предполагаю, что может возникнуть проблема с инициализацией компонента-службы. Создан ли экземпляр CampagneService и инициализирован ли он? Я имею в виду, все ли зависимости внутри CampagneService введены правильно? Включите ведение журнала трассировки Spring, чтобы вы могли получить больше информации об исключении.
4. Да, с CampagneService все в порядке, потому что я внедряю его и использую в другом месте, он просто не работает в контексте quartz. и служба campagne — это просто название одной из многих.
5. Повторное включение
AutowiringSpringBeanJobFactory
вместоSpringBeanJobFactory
из вашегоspringBeanJobFactory
метода. Кроме того, вы должны вводить планировщик вместо того, чтобы получать его таким образом, и при этом вы не должны его запускать.