Trying to update my project from Spring Boot 1.5.8 to 2.0.1 and having problems with Quartz. I used Spring BOM and have Quartz 2.3.0 version.
Here is my QuartzConfigurer that sets up beans for Spring:
import lombok.extern.slf4j.Slf4j;
import org.quartz.JobDetail;
import org.quartz.Trigger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
import org.springframework.scheduling.quartz.JobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.scheduling.quartz.SpringBeanJobFactory;
import javax.annotation.PostConstruct;
@Slf4j
@Configuration
public class QuartzConfigurer {
@Value("${quartz.cron.contract-status}")
private String contractCron;
@Value("${quartz.config-filename}")
private String quartzConfigFileName;
@Autowired
private ApplicationContext applicationContext;
@PostConstruct
public void init() {
log.debug("Initialization of quartz configurer");
}
@Bean
public SpringBeanJobFactory springBeanJobFactory() {
AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
jobFactory.setApplicationContext(applicationContext);
return jobFactory;
}
@Bean
public SchedulerFactoryBean scheduler(Trigger trigger, JobDetail job) {
SchedulerFactoryBean schedulerFactory = new SchedulerFactoryBean();
schedulerFactory.setConfigLocation(new ClassPathResource(quartzConfigFileName));
schedulerFactory.setJobFactory(springBeanJobFactory());
schedulerFactory.setJobDetails(job);
schedulerFactory.setTriggers(trigger);
return schedulerFactory;
}
@Bean
public JobDetailFactoryBean jobDetail() {
JobDetailFactoryBean jobDetailFactory = new JobDetailFactoryBean();
jobDetailFactory.setJobClass(ContractStatusJob.class);
jobDetailFactory.setName("Qrtz_Contract_Job_Detail");
jobDetailFactory.setDescription("Invoke contract job detail");
jobDetailFactory.setDurability(true);
return jobDetailFactory;
}
@Bean
public CronTriggerFactoryBean trigger(JobDetail job) {
CronTriggerFactoryBean trigger = new CronTriggerFactoryBean();
trigger.setJobDetail(job);
log.debug("Configuring trigger to fire based on cron {}", contractCron);
trigger.setCronExpression(contractCron);
trigger.setName("Qrtz_Contract_Trigger");
return trigger;
}
}
Here is AutowiringSpringBeanJobFactory used in above file:
import lombok.extern.slf4j.Slf4j;
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.scheduling.quartz.SpringBeanJobFactory;
@Slf4j
public final class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {
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);
beanFactory.autowireBean(job);
return job;
}
}
And here is quartz.properties used with Spring Boot 1.5.8 that was working properly. This is a property file used in QuartzConfigurer:
#============================================================================
# Configure Main Scheduler Properties
#============================================================================
org.quartz.scheduler.instanceName = MyClusteredScheduler
org.quartz.scheduler.instanceId = AUTO
#============================================================================
# Configure ThreadPool
#============================================================================
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 25
org.quartz.threadPool.threadPriority = 5
#============================================================================
# Configure JobStore
#============================================================================
org.quartz.jobStore.misfireThreshold = 60000
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
org.quartz.jobStore.useProperties = false
org.quartz.jobStore.dataSource = default
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.isClustered = true
org.quartz.jobStore.clusterCheckinInterval = 20000
#============================================================================
# Configure Datasources
#============================================================================
org.quartz.dataSource.default.driver = org.postgresql.Driver
org.quartz.dataSource.default.URL = jdbc:postgresql://localhost:5432/example
org.quartz.dataSource.default.user = postgres
org.quartz.dataSource.default.password = postgres
org.quartz.dataSource.default.maxConnections = 5
org.quartz.dataSource.default.validationQuery = select 0 from dual
Here is exception thrown when starting up Application:
2018-05-08 15:26:52.855 INFO 21200 --- [ restartedMain] o.s.s.quartz.SchedulerFactoryBean : Loading Quartz config from [class path resource [quartz.properties]]
2018-05-08 15:26:52.873 INFO 21200 --- [ restartedMain] org.quartz.impl.StdSchedulerFactory : Using ConnectionProvider class 'org.quartz.utils.C3p0PoolingConnectionProvider' for data source 'default'
2018-05-08 15:26:52.874 WARN 21200 --- [ restartedMain] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scheduler' defined in class path resource [com/onwelo/vendormanagement/core/configuration/quartz/QuartzConfigurer.class]: Invocation of init method failed; nested exception is org.quartz.SchedulerException: Could not initialize DataSource: default [See nested exception: org.quartz.SchedulerException: ConnectionProvider class 'org.quartz.utils.C3p0PoolingConnectionProvider' could not be instantiated. [See nested exception: java.lang.reflect.InvocationTargetException]]
My database configuration didn't change at all and it's working fine with Spring Boot 1.5.8.
Quartz Scheduler Spring Boot offers several conveniences for working with the Quartz scheduler, including the spring-boot-starter-quartz “Starter”. If Quartz is available, a Scheduler is auto-configured (through the SchedulerFactoryBean abstraction).
It is also possible to provide a custom script by setting the spring.quartz.jdbc.schema property. To have Quartz use a DataSource other than the application’s main DataSource, declare a DataSource bean, annotating its @Bean method with @QuartzDataSource.
It is a Maven project which can be imported and run as-is. The default setting uses Spring's convenience classes, which can be easily switched to Quartz API with a run-time parameter (refer to the README.md in the repository). with Spring?
Add a Quartz scheduler to an existing repository, showing just how quick and easily this can be accomplished — thanks to Spring Boot Starters. Join the DZone community and get the full member experience.
You have to add the C3P0 dependency:
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
Configure Quartz to use HikariCP (default is c3p0)
# quartz.properties
org.quartz.dataSource.quartzDataSource.provider=hikaricp
For more: https://github.com/quartz-scheduler/quartz/wiki/How-to-Use-DB-Connection-Pool
I had the same issue sometime back. It is clearly due to the absence of the 'c3p0' dependency.
https://mvnrepository.com/artifact/c3p0/c3p0
compile group: 'c3p0', name: 'c3p0', version: '0.9.1.2'
I have added the below dependency into my build.gradle file and then refreshed the dependencies. Then this error is gone.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With