Search code examples
javaspring-bootkotlinspring-data-jpaquartz-scheduler

How to access Spring Boot Quartz Bean from another module?


I have a Spring Boot project that is going to be using Quartz to manage the running of some scripts. The project layout is as follows:

scheduler
|
|__scheduler-api
|  |
|  |__quartz-bean
|
|__scheduler-composition
   |
   |__service-to-schedule-quartz-jobs-using-quartz-bean

The api module is a Spring Boot application where the quartz bean lives. The composition module is where my services live that will be used to add jobs and triggers to Quartz. The problem I am running into is that my Quartz bean is not accessible from the composition module, therefore I am not able to schedule jobs in my service like I'd want to. My Quartz bean is defined as follows:

@Configuration
class QuartzScheduler {
    @Autowired
    private val applicationContext: ApplicationContext? = null

    @Autowired
    private val databaseConfiguration: DatabaseConfiguration? = null

    @Bean
    fun springBeanJobFactory(): SpringBeanJobFactory {
        val jobFactory = AutoWiringSpringBeanJobFactory()
        jobFactory.setApplicationContext(applicationContext!!)
        return jobFactory
    }

    @Bean
    @Throws(SchedulerException::class)
    fun scheduler(@Qualifier("schedulerFactoryBean") factory: SchedulerFactoryBean): Scheduler {
        val scheduler = factory.scheduler   
        scheduler.start()
        return scheduler
    }

    @Bean
    @Throws(IOException::class)
    fun schedulerFactoryBean(): SchedulerFactoryBean {
        val factory = SchedulerFactoryBean()
        factory.setDataSource(databaseConfiguration!!.dataSource())
        factory.setJobFactory(springBeanJobFactory())
        factory.setQuartzProperties(quartzProperties())
        return factory
    }

    @Throws(IOException::class)
    fun quartzProperties(): Properties {
        val propertiesFactoryBean = PropertiesFactoryBean()
        propertiesFactoryBean.setLocation(ClassPathResource("/quartz.properties"))
        propertiesFactoryBean.afterPropertiesSet()
        return propertiesFactoryBean.getObject()!!
    }
}

A couple things I've tried include moving the Quarts bean to the composition module, but then it doesn't have access to the database configuration it needs. I also tried importing the api module into the composition module but it created a circular dependency. Can someone help me access the Quartz bean from my composition module? I'm new to Spring Boot so I am not really sure where I am going wrong or what my options are even. Thanks!

Edit

My service looks like this:

class QuartzService {

    @Autowired
    private var quartzScheduler: QuartzScheduler? = null

    fun upsertJob(job: JobEntity) {
        var jobExists = quartzScheduler!!.scheduler().checkExists(JobKey.jobKey(job.id.toString()))
        if (!jobExists) {
            quartzScheduler!!.scheduler().addJob(
                    newJob().ofType(EnqueueJob::class.java).storeDurably().withIdentity(JobKey.jobKey(job.id.toString())).build(),
                    true
            )
        }
    }
}

The error that appears is that the type QuartzScheduler cannot be found (my QuartzScheduler class from scheduler-api)


Solution

  • I had a couple of problems going on. First, my Quartz service was auto wiring the scheduler improperly. I changed it to this:

    class QuartzService {
    
        @Autowired
        private lateint var scheduler: Scheduler
    
        fun upsertJob(job: JobEntity) {
            var jobExists = scheduler.checkExists(JobKey.jobKey(job.id.toString()))
            if (!jobExists) {
                scheduler.addJob(
                        newJob().ofType(EnqueueJob::class.java).storeDurably().withIdentity(JobKey.jobKey(job.id.toString())).build(),
                        true
                )
            }
        }
    }
    

    Next, I had to change the class that was using the Quartz service to auto wire the service, I accidentally just instantiated it as a normal object:

    @Autowired
    private lateinit var quartzService: QuartzService
    

    Thanks everyone for the help!