diff --git a/spring-context-support/src/main/java/org/springframework/scheduling/quartz/SchedulerFactoryBean.java b/spring-context-support/src/main/java/org/springframework/scheduling/quartz/SchedulerFactoryBean.java
index 50ef456cfc..e0982a2e5f 100644
--- a/spring-context-support/src/main/java/org/springframework/scheduling/quartz/SchedulerFactoryBean.java
+++ b/spring-context-support/src/main/java/org/springframework/scheduling/quartz/SchedulerFactoryBean.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2018 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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...
diff --git a/spring-context-support/src/test/java/org/springframework/scheduling/quartz/QuartzSupportTests.java b/spring-context-support/src/test/java/org/springframework/scheduling/quartz/QuartzSupportTests.java
index 6c7d5b8691..9d461d2e40 100644
--- a/spring-context-support/src/test/java/org/springframework/scheduling/quartz/QuartzSupportTests.java
+++ b/spring-context-support/src/test/java/org/springframework/scheduling/quartz/QuartzSupportTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2020 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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;
@@ -57,10 +61,10 @@ import static org.springframework.core.testfixture.TestGroup.LONG_RUNNING;
* @author Sam Brannen
* @since 20.02.2004
*/
-public class QuartzSupportTests {
+class QuartzSupportTests {
@Test
- public void schedulerFactoryBeanWithApplicationContext() throws Exception {
+ void schedulerFactoryBeanWithApplicationContext() throws Exception {
TestBean tb = new TestBean("tb", 99);
StaticApplicationContext ac = new StaticApplicationContext();
@@ -97,7 +101,7 @@ public class QuartzSupportTests {
@Test
@EnabledForTestGroups(LONG_RUNNING)
- public void schedulerWithTaskExecutor() throws Exception {
+ void schedulerWithTaskExecutor() throws Exception {
CountingTaskExecutor taskExecutor = new CountingTaskExecutor();
DummyJob.count = 0;
@@ -130,7 +134,7 @@ public class QuartzSupportTests {
@Test
@SuppressWarnings({ "unchecked", "rawtypes" })
- public void jobDetailWithRunnableInsteadOfJob() {
+ void jobDetailWithRunnableInsteadOfJob() {
JobDetailImpl jobDetail = new JobDetailImpl();
assertThatIllegalArgumentException().isThrownBy(() ->
jobDetail.setJobClass((Class) DummyRunnable.class));
@@ -138,7 +142,7 @@ public class QuartzSupportTests {
@Test
@EnabledForTestGroups(LONG_RUNNING)
- public void schedulerWithQuartzJobBean() throws Exception {
+ void schedulerWithQuartzJobBean() throws Exception {
DummyJob.param = 0;
DummyJob.count = 0;
@@ -171,7 +175,7 @@ public class QuartzSupportTests {
@Test
@EnabledForTestGroups(LONG_RUNNING)
- public void schedulerWithSpringBeanJobFactory() throws Exception {
+ void schedulerWithSpringBeanJobFactory() throws Exception {
DummyJob.param = 0;
DummyJob.count = 0;
@@ -206,7 +210,7 @@ public class QuartzSupportTests {
@Test
@EnabledForTestGroups(LONG_RUNNING)
- public void schedulerWithSpringBeanJobFactoryAndParamMismatchNotIgnored() throws Exception {
+ void schedulerWithSpringBeanJobFactoryAndParamMismatchNotIgnored() throws Exception {
DummyJob.param = 0;
DummyJob.count = 0;
@@ -242,7 +246,7 @@ public class QuartzSupportTests {
@Test
@EnabledForTestGroups(LONG_RUNNING)
- public void schedulerWithSpringBeanJobFactoryAndQuartzJobBean() throws Exception {
+ void schedulerWithSpringBeanJobFactoryAndQuartzJobBean() throws Exception {
DummyJobBean.param = 0;
DummyJobBean.count = 0;
@@ -276,7 +280,7 @@ public class QuartzSupportTests {
@Test
@EnabledForTestGroups(LONG_RUNNING)
- public void schedulerWithSpringBeanJobFactoryAndJobSchedulingData() throws Exception {
+ void schedulerWithSpringBeanJobFactoryAndJobSchedulingData() throws Exception {
DummyJob.param = 0;
DummyJob.count = 0;
@@ -294,7 +298,7 @@ public class QuartzSupportTests {
}
@Test // SPR-772
- public void multipleSchedulers() throws Exception {
+ void multipleSchedulers() throws Exception {
try (ClassPathXmlApplicationContext ctx = context("multipleSchedulers.xml")) {
Scheduler scheduler1 = (Scheduler) ctx.getBean("scheduler1");
Scheduler scheduler2 = (Scheduler) ctx.getBean("scheduler2");
@@ -305,7 +309,7 @@ public class QuartzSupportTests {
}
@Test // SPR-16884
- public void multipleSchedulersWithQuartzProperties() throws Exception {
+ void multipleSchedulersWithQuartzProperties() throws Exception {
try (ClassPathXmlApplicationContext ctx = context("multipleSchedulersWithQuartzProperties.xml")) {
Scheduler scheduler1 = (Scheduler) ctx.getBean("scheduler1");
Scheduler scheduler2 = (Scheduler) ctx.getBean("scheduler2");
@@ -317,12 +321,13 @@ public class QuartzSupportTests {
@Test
@EnabledForTestGroups(LONG_RUNNING)
- public void twoAnonymousMethodInvokingJobDetailFactoryBeans() throws Exception {
- Thread.sleep(3000);
+ void twoAnonymousMethodInvokingJobDetailFactoryBeans() throws Exception {
try (ClassPathXmlApplicationContext ctx = context("multipleAnonymousMethodInvokingJobDetailFB.xml")) {
QuartzTestBean exportService = (QuartzTestBean) ctx.getBean("exportService");
QuartzTestBean importService = (QuartzTestBean) ctx.getBean("importService");
+ Thread.sleep(400);
+
assertThat(exportService.getImportCount()).as("doImport called exportService").isEqualTo(0);
assertThat(exportService.getExportCount()).as("doExport not called on exportService").isEqualTo(2);
assertThat(importService.getImportCount()).as("doImport not called on importService").isEqualTo(2);
@@ -332,12 +337,13 @@ public class QuartzSupportTests {
@Test
@EnabledForTestGroups(LONG_RUNNING)
- public void schedulerAccessorBean() throws Exception {
- Thread.sleep(3000);
+ void schedulerAccessorBean() throws Exception {
try (ClassPathXmlApplicationContext ctx = context("schedulerAccessorBean.xml")) {
QuartzTestBean exportService = (QuartzTestBean) ctx.getBean("exportService");
QuartzTestBean importService = (QuartzTestBean) ctx.getBean("importService");
+ Thread.sleep(400);
+
assertThat(exportService.getImportCount()).as("doImport called exportService").isEqualTo(0);
assertThat(exportService.getExportCount()).as("doExport not called on exportService").isEqualTo(2);
assertThat(importService.getImportCount()).as("doImport not called on importService").isEqualTo(2);
@@ -347,7 +353,7 @@ public class QuartzSupportTests {
@Test
@SuppressWarnings("resource")
- public void schedulerAutoStartsOnContextRefreshedEventByDefault() throws Exception {
+ void schedulerAutoStartsOnContextRefreshedEventByDefault() throws Exception {
StaticApplicationContext context = new StaticApplicationContext();
context.registerBeanDefinition("scheduler", new RootBeanDefinition(SchedulerFactoryBean.class));
Scheduler bean = context.getBean("scheduler", Scheduler.class);
@@ -358,7 +364,7 @@ public class QuartzSupportTests {
@Test
@SuppressWarnings("resource")
- public void schedulerAutoStartupFalse() throws Exception {
+ void schedulerAutoStartupFalse() throws Exception {
StaticApplicationContext context = new StaticApplicationContext();
BeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(SchedulerFactoryBean.class)
.addPropertyValue("autoStartup", false).getBeanDefinition();
@@ -370,7 +376,7 @@ public class QuartzSupportTests {
}
@Test
- public void schedulerRepositoryExposure() throws Exception {
+ void schedulerRepositoryExposure() throws Exception {
try (ClassPathXmlApplicationContext ctx = context("schedulerRepositoryExposure.xml")) {
assertThat(ctx.getBean("scheduler")).isSameAs(SchedulerRepository.getInstance().lookup("myScheduler"));
}
@@ -381,7 +387,7 @@ public class QuartzSupportTests {
* TODO: Against Quartz 2.2, this test's job doesn't actually execute anymore...
*/
@Test
- public void schedulerWithHsqlDataSource() throws Exception {
+ void schedulerWithHsqlDataSource() throws Exception {
DummyJob.param = 0;
DummyJob.count = 0;
@@ -396,12 +402,36 @@ public class QuartzSupportTests {
}
}
+ @Test
+ @SuppressWarnings("resource")
+ void schedulerFactoryBeanWithCustomJobStore() throws Exception {
+ StaticApplicationContext context = new StaticApplicationContext();
+
+ String dbName = "mydb";
+ EmbeddedDatabase database = new EmbeddedDatabaseBuilder().setName(dbName).build();
+
+ 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 scheduler = context.getBean(Scheduler.class);
+
+ assertThat(scheduler.getMetaData().getJobStoreClass()).isEqualTo(JobStoreTX.class);
+ }
+
private ClassPathXmlApplicationContext context(String path) {
return new ClassPathXmlApplicationContext(path, getClass());
}
- public static class CountingTaskExecutor implements TaskExecutor {
+ private static class CountingTaskExecutor implements TaskExecutor {
private int count;
@@ -413,12 +443,14 @@ public class QuartzSupportTests {
}
- public static class DummyJob implements Job {
+ private static class DummyJob implements Job {
private static int param;
private static int count;
+ @SuppressWarnings("unused")
+ // Must be public
public void setParam(int value) {
if (param > 0) {
throw new IllegalStateException("Param already set");
@@ -433,12 +465,13 @@ public class QuartzSupportTests {
}
- public static class DummyJobBean extends QuartzJobBean {
+ private static class DummyJobBean extends QuartzJobBean {
private static int param;
private static int count;
+ @SuppressWarnings("unused")
public void setParam(int value) {
if (param > 0) {
throw new IllegalStateException("Param already set");
@@ -453,7 +486,7 @@ public class QuartzSupportTests {
}
- public static class DummyRunnable implements Runnable {
+ private static class DummyRunnable implements Runnable {
@Override
public void run() {
diff --git a/spring-context-support/src/test/resources/org/springframework/scheduling/quartz/multipleAnonymousMethodInvokingJobDetailFB.xml b/spring-context-support/src/test/resources/org/springframework/scheduling/quartz/multipleAnonymousMethodInvokingJobDetailFB.xml
index e45ccd195f..58e771f3ad 100644
--- a/spring-context-support/src/test/resources/org/springframework/scheduling/quartz/multipleAnonymousMethodInvokingJobDetailFB.xml
+++ b/spring-context-support/src/test/resources/org/springframework/scheduling/quartz/multipleAnonymousMethodInvokingJobDetailFB.xml
@@ -19,7 +19,7 @@
-
+
@@ -30,7 +30,7 @@
-
+
diff --git a/spring-context-support/src/test/resources/org/springframework/scheduling/quartz/schedulerAccessorBean.xml b/spring-context-support/src/test/resources/org/springframework/scheduling/quartz/schedulerAccessorBean.xml
index 0ba9c4a57a..3634002664 100644
--- a/spring-context-support/src/test/resources/org/springframework/scheduling/quartz/schedulerAccessorBean.xml
+++ b/spring-context-support/src/test/resources/org/springframework/scheduling/quartz/schedulerAccessorBean.xml
@@ -21,7 +21,7 @@
-
+
@@ -32,7 +32,7 @@
-
+
diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/DefaultWebClientTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/DefaultWebClientTests.java
index 37928d2fb1..a33a24c016 100644
--- a/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/DefaultWebClientTests.java
+++ b/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/DefaultWebClientTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2020 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -133,6 +133,7 @@ public class DefaultWebClientTests {
}
@Test
+ @SuppressWarnings("deprecation")
public void contextFromThreadLocal() {
WebClient client = this.builder
.filter((request, next) ->