Search code examples
springspring-bootjhipsterquartz-schedulerspring-boot-2

Bean references are not creating when using quartz with spring scheduler - Job instantiation failed


I have updated my spring-boot application from 1.x to 2.x after upgrade scheduler is not working as expected. Getting the following exception.

org.quartz.SchedulerException: Job instantiation failed
        at org.springframework.scheduling.quartz.AdaptableJobFactory.newJob(AdaptableJobFactory.java:47)
        at org.quartz.core.JobRunShell.initialize(JobRunShell.java:127)
        at org.quartz.core.QuartzSchedulerThread.run(QuartzSchedulerThread.java:392) Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.schedulers.simplejobs.SimpleJobExecutions': Unsatisfied dependency expressed through field 'sampleService'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.service.SampleService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:596)
        at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90)
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:374)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1411)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:592)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:351)
        at org.springframework.scheduling.quartz.SpringBeanJobFactory.createJobInstance(SpringBeanJobFactory.java:90)
        at com.scheduler.factory.JobFactory.createJobInstance(JobFactory.java:35)
        at org.springframework.scheduling.quartz.AdaptableJobFactory.newJob(AdaptableJobFactory.java:43)
        ... 2 common frames omitted Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.service.SampleService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1655)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1214)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1168)
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:593)
        ... 11 common frames omitted

I have tried many references from SO and suggested configurations didn't help.

Below are the stack details.

Spring boot 2.1.5

Spring 5.1.7

Quartz 2.3.1

Here is my codebase.


public final class JobFactory  extends SpringBeanJobFactory {

    private transient AutowireCapableBeanFactory beanFactory;

    private static final Logger LOGGER = LoggerFactory.getLogger(JobFactory.class);

    public void setApplicationContext(final ApplicationContext context) {
        Stream.of(context.getBeanDefinitionNames())
            .filter(s -> s.startsWith("sample"))
            .forEach(beanName -> LOGGER.debug("applicationContext beans {}",beanName));
        beanFactory = context.getAutowireCapableBeanFactory();
    }

    @Override
    protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
        final Object job = super.createJobInstance(bundle);
        LOGGER.debug("createJobInstance job {}",job);
        beanFactory.autowireBean(job);
        LOGGER.debug("createJobInstance autowireBean job {}",job);
        return job;
    }
@Component
public class SimpleJobExecutions extends QuartzJobBean {


    @Autowired
    public SampleService sampleService;

    @Override
    public void executeInternal(JobExecutionContext context)  throws JobExecutionException {
        try {
            SampleDTO sample = new SampleDTO();
            sample.setName("Name");
            sample.setAge(25);
            SampleDTO sampleObj = sampleService.save(sample);
        } catch (Exception ex) {
            throw new JobExecutionException(ex);
        }
    }
@Service("sampleService")
public class SampleServiceImpl implements SampleService {

    @Autowired
    SampleRepository sampleRepository;

    @Autowired
    SampleMapper sampleMapper;

   @Override
   public SampleDTO save(SampleDTO sampleDTO) {
      log.info("Request to save Sample : {}", sampleDTO);
      Sample sample = sampleMapper.toEntity(sampleDTO);
      sample = sampleRepository.save(sample);
      return sampleMapper.toDto(sample);
  }

}

I can able to print all the beans from application context but it's not injecting at the time of job execution.


Solution

  • Finally, I found the root cause of this problem.

    Autowiring other bean references are started working after removing the following dependencies.

      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <version>2.1.5.RELEASE</version>
      </dependency>
    

    dev tools dependencies are creating conflicts with application dependencies and it's not allowing to create the bean references only in QuartzJobBean executions.