Не удается внедрить зависимости в задания Quartz

#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 метода. Кроме того, вы должны вводить планировщик вместо того, чтобы получать его таким образом, и при этом вы не должны его запускать.