Use LocalDataSourceJobStore only if one is not set via Quartz properties

Prior to this commit, Spring's SchedulerFactoryBean always set the
"org.quartz.jobStore.class" property to LocalDataSourceJobStore even if
the user had already specified a custom JobStore implementation via the
Quartz properties file or Properties object, thereby effectively
ignoring the user configuration.

This commit addresses this by configuring Quartz to use Spring's
LocalDataSourceJobStore only if a JobStore has not already been
specified via user configuration.

Closes gh-27560
This commit is contained in:
Daniil Pozdeev 2021-10-14 17:20:41 +03:00 committed by Sam Brannen
parent 66826ac960
commit c58853f5e5
2 changed files with 28 additions and 1 deletions

View File

@ -570,7 +570,7 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
CollectionUtils.mergePropertiesIntoMap(this.quartzProperties, mergedProps);
if (this.dataSource != null) {
mergedProps.setProperty(StdSchedulerFactory.PROP_JOB_STORE_CLASS, LocalDataSourceJobStore.class.getName());
mergedProps.putIfAbsent(StdSchedulerFactory.PROP_JOB_STORE_CLASS, LocalDataSourceJobStore.class.getName());
}
// Determine scheduler name across local settings and Quartz properties...

View File

@ -18,6 +18,7 @@ package org.springframework.scheduling.quartz;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import javax.sql.DataSource;
@ -30,6 +31,7 @@ import org.quartz.SchedulerContext;
import org.quartz.SchedulerFactory;
import org.quartz.impl.JobDetailImpl;
import org.quartz.impl.SchedulerRepository;
import org.quartz.impl.jdbcjobstore.JobStoreTX;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
@ -40,6 +42,8 @@ import org.springframework.context.support.StaticApplicationContext;
import org.springframework.core.task.TaskExecutor;
import org.springframework.core.testfixture.EnabledForTestGroups;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
@ -396,6 +400,29 @@ public class QuartzSupportTests {
}
}
@Test
public void schedulerFactoryBeanWithCustomJobStore() throws Exception {
StaticApplicationContext context = new StaticApplicationContext();
final String dbName = "mydb";
final EmbeddedDatabase database = new EmbeddedDatabaseBuilder().setName(dbName).build();
final Properties properties = new Properties();
properties.setProperty("org.quartz.jobStore.class", JobStoreTX.class.getName());
properties.setProperty("org.quartz.jobStore.dataSource", dbName);
BeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(SchedulerFactoryBean.class)
.addPropertyValue("autoStartup", false)
.addPropertyValue("dataSource", database)
.addPropertyValue("quartzProperties", properties)
.getBeanDefinition();
context.registerBeanDefinition("scheduler", beanDefinition);
Scheduler bean = context.getBean("scheduler", Scheduler.class);
assertThat(bean.getMetaData().getJobStoreClass()).isEqualTo(JobStoreTX.class);
}
private ClassPathXmlApplicationContext context(String path) {
return new ClassPathXmlApplicationContext(path, getClass());
}