diff --git a/spring-context-support/src/main/java/org/springframework/scheduling/quartz/AdaptableJobFactory.java b/spring-context-support/src/main/java/org/springframework/scheduling/quartz/AdaptableJobFactory.java index 09cf9fbdb3..9971ebee47 100644 --- a/spring-context-support/src/main/java/org/springframework/scheduling/quartz/AdaptableJobFactory.java +++ b/spring-context-support/src/main/java/org/springframework/scheduling/quartz/AdaptableJobFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2018 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. @@ -25,7 +25,7 @@ import org.quartz.spi.TriggerFiredBundle; import org.springframework.util.ReflectionUtils; /** - * JobFactory implementation that supports {@link java.lang.Runnable} + * {@link JobFactory} implementation that supports {@link java.lang.Runnable} * objects as well as standard Quartz {@link org.quartz.Job} instances. * *
Compatible with Quartz 2.1.4 and higher, as of Spring 4.1. @@ -43,7 +43,7 @@ public class AdaptableJobFactory implements JobFactory { Object jobObject = createJobInstance(bundle); return adaptJob(jobObject); } - catch (Exception ex) { + catch (Throwable ex) { throw new SchedulerException("Job instantiation failed", ex); } } @@ -78,7 +78,8 @@ public class AdaptableJobFactory implements JobFactory { return new DelegatingJob((Runnable) jobObject); } else { - throw new IllegalArgumentException("Unable to execute job class [" + jobObject.getClass().getName() + + throw new IllegalArgumentException( + "Unable to execute job class [" + jobObject.getClass().getName() + "]: only [org.quartz.Job] and [java.lang.Runnable] supported."); } } diff --git a/spring-context-support/src/main/java/org/springframework/scheduling/quartz/LocalDataSourceJobStore.java b/spring-context-support/src/main/java/org/springframework/scheduling/quartz/LocalDataSourceJobStore.java index b8454fe8dc..fcec562759 100644 --- a/spring-context-support/src/main/java/org/springframework/scheduling/quartz/LocalDataSourceJobStore.java +++ b/spring-context-support/src/main/java/org/springframework/scheduling/quartz/LocalDataSourceJobStore.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2018 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. @@ -34,9 +34,9 @@ import org.springframework.jdbc.support.MetaDataAccessException; import org.springframework.lang.Nullable; /** - * Subclass of Quartz's JobStoreCMT class that delegates to a Spring-managed - * DataSource instead of using a Quartz-managed connection pool. This JobStore - * will be used if SchedulerFactoryBean's "dataSource" property is set. + * Subclass of Quartz's {@link JobStoreCMT} class that delegates to a Spring-managed + * {@link DataSource} instead of using a Quartz-managed JDBC connection pool. + * This JobStore will be used if SchedulerFactoryBean's "dataSource" property is set. * *
Supports both transactional and non-transactional DataSource access. * With a non-XA DataSource and local Spring transactions, a single DataSource @@ -84,15 +84,12 @@ public class LocalDataSourceJobStore extends JobStoreCMT { @Override - public void initialize(ClassLoadHelper loadHelper, SchedulerSignaler signaler) - throws SchedulerConfigException { - + public void initialize(ClassLoadHelper loadHelper, SchedulerSignaler signaler) throws SchedulerConfigException { // Absolutely needs thread-bound DataSource to initialize. this.dataSource = SchedulerFactoryBean.getConfigTimeDataSource(); if (this.dataSource == null) { - throw new SchedulerConfigException( - "No local DataSource found for configuration - " + - "'dataSource' property must be set on SchedulerFactoryBean"); + throw new SchedulerConfigException("No local DataSource found for configuration - " + + "'dataSource' property must be set on SchedulerFactoryBean"); } // Configure transactional connection settings for Quartz. diff --git a/spring-context-support/src/main/java/org/springframework/scheduling/quartz/LocalTaskExecutorThreadPool.java b/spring-context-support/src/main/java/org/springframework/scheduling/quartz/LocalTaskExecutorThreadPool.java index d00c5ce6c8..a87310b683 100644 --- a/spring-context-support/src/main/java/org/springframework/scheduling/quartz/LocalTaskExecutorThreadPool.java +++ b/spring-context-support/src/main/java/org/springframework/scheduling/quartz/LocalTaskExecutorThreadPool.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2018 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. @@ -28,8 +28,8 @@ import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** - * Quartz ThreadPool adapter that delegates to a Spring-managed - * TaskExecutor instance, specified on SchedulerFactoryBean. + * Quartz {@link ThreadPool} adapter that delegates to a Spring-managed + * {@link Executor} instance, specified on {@link SchedulerFactoryBean}. * * @author Juergen Hoeller * @since 2.0 @@ -55,12 +55,11 @@ public class LocalTaskExecutorThreadPool implements ThreadPool { @Override public void initialize() throws SchedulerConfigException { - // Absolutely needs thread-bound TaskExecutor to initialize. + // Absolutely needs thread-bound Executor to initialize. this.taskExecutor = SchedulerFactoryBean.getConfigTimeTaskExecutor(); if (this.taskExecutor == null) { - throw new SchedulerConfigException( - "No local TaskExecutor found for configuration - " + - "'taskExecutor' property must be set on SchedulerFactoryBean"); + throw new SchedulerConfigException("No local Executor found for configuration - " + + "'taskExecutor' property must be set on SchedulerFactoryBean"); } } 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 8c8f77b473..d395a52e1d 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 @@ -104,11 +104,10 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe /** - * Return the ResourceLoader for the currently configured Quartz Scheduler, - * to be used by ResourceLoaderClassLoadHelper. - *
This instance will be set before initialization of the corresponding - * Scheduler, and reset immediately afterwards. It is thus only available - * during configuration. + * Return the {@link ResourceLoader} for the currently configured Quartz Scheduler, + * to be used by {@link ResourceLoaderClassLoadHelper}. + *
This instance will be set before initialization of the corresponding Scheduler, + * and reset immediately afterwards. It is thus only available during configuration. * @see #setApplicationContext * @see ResourceLoaderClassLoadHelper */ @@ -118,11 +117,11 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe } /** - * Return the TaskExecutor for the currently configured Quartz Scheduler, - * to be used by LocalTaskExecutorThreadPool. - *
This instance will be set before initialization of the corresponding - * Scheduler, and reset immediately afterwards. It is thus only available - * during configuration. + * Return the {@link Executor} for the currently configured Quartz Scheduler, + * to be used by {@link LocalTaskExecutorThreadPool}. + *
This instance will be set before initialization of the corresponding Scheduler, + * and reset immediately afterwards. It is thus only available during configuration. + * @since 2.0 * @see #setTaskExecutor * @see LocalTaskExecutorThreadPool */ @@ -132,11 +131,11 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe } /** - * Return the DataSource for the currently configured Quartz Scheduler, - * to be used by LocalDataSourceJobStore. - *
This instance will be set before initialization of the corresponding - * Scheduler, and reset immediately afterwards. It is thus only available - * during configuration. + * Return the {@link DataSource} for the currently configured Quartz Scheduler, + * to be used by {@link LocalDataSourceJobStore}. + *
This instance will be set before initialization of the corresponding Scheduler, + * and reset immediately afterwards. It is thus only available during configuration. + * @since 1.1 * @see #setDataSource * @see LocalDataSourceJobStore */ @@ -146,11 +145,11 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe } /** - * Return the non-transactional DataSource for the currently configured - * Quartz Scheduler, to be used by LocalDataSourceJobStore. - *
This instance will be set before initialization of the corresponding - * Scheduler, and reset immediately afterwards. It is thus only available - * during configuration. + * Return the non-transactional {@link DataSource} for the currently configured + * Quartz Scheduler, to be used by {@link LocalDataSourceJobStore}. + *
This instance will be set before initialization of the corresponding Scheduler, + * and reset immediately afterwards. It is thus only available during configuration. + * @since 1.1 * @see #setNonTransactionalDataSource * @see LocalDataSourceJobStore */ @@ -160,11 +159,11 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe } - private Class extends SchedulerFactory> schedulerFactoryClass = StdSchedulerFactory.class; - @Nullable private SchedulerFactory schedulerFactory; + private Class extends SchedulerFactory> schedulerFactoryClass = StdSchedulerFactory.class; + @Nullable private String schedulerName; @@ -174,7 +173,6 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe @Nullable private Properties quartzProperties; - @Nullable private Executor taskExecutor; @@ -198,7 +196,6 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe private boolean jobFactorySet = false; - private boolean autoStartup = true; private int startupDelay = 0; @@ -209,35 +206,20 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe private boolean waitForJobsToCompleteOnShutdown = false; - @Nullable private Scheduler scheduler; - /** - * Set the Quartz {@link SchedulerFactory} implementation to use. - *
Default is the {@link StdSchedulerFactory} class, reading in the standard - * {@code quartz.properties} from {@code quartz.jar}. For applying custom Quartz - * properties, specify {@link #setConfigLocation "configLocation"} or - * {@link #setQuartzProperties "quartzProperties"} on {@code SchedulerFactoryBean}. - * @see org.quartz.impl.StdSchedulerFactory - * @see #setConfigLocation - * @see #setQuartzProperties - */ - public void setSchedulerFactoryClass(Class extends SchedulerFactory> schedulerFactoryClass) { - this.schedulerFactoryClass = schedulerFactoryClass; - } - /** * Set an external Quartz {@link SchedulerFactory} instance to use. *
Default is an internal {@link StdSchedulerFactory} instance. If this method is - * called, it overrides any class specified through {@link #setSchedulerFactoryClass}. - *
An externally provided {@code SchedulerFactory} instance may get initialized - * from local {@code SchedulerFactoryBean} settings (such as {@link #setConfigLocation} - * or {@link #setQuartzProperties}) but only if it extends from {@link StdSchedulerFactory}, - * inheriting the common {@link StdSchedulerFactory#initialize(Properties)} method. - * Otherwise, all such local settings will be ignored here in {@code SchedulerFactoryBean}, - * expecting the external {@code SchedulerFactory} instance to get initialized on its own. + * called, it overrides any class specified through {@link #setSchedulerFactoryClass} + * as well as any settings specified through {@link #setConfigLocation}, + * {@link #setQuartzProperties}, {@link #setTaskExecutor} or {@link #setDataSource}. + *
NOTE: With an externally provided {@code SchedulerFactory} instance, + * local settings such as {@link #setConfigLocation} or {@link #setQuartzProperties} + * will be ignored here in {@code SchedulerFactoryBean}, expecting the external + * {@code SchedulerFactory} instance to get initialized on its own. * @since 4.3.15 * @see #setSchedulerFactoryClass */ @@ -245,6 +227,23 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe this.schedulerFactory = schedulerFactory; } + /** + * Set the Quartz {@link SchedulerFactory} implementation to use. + *
Default is the {@link StdSchedulerFactory} class, reading in the standard + * {@code quartz.properties} from {@code quartz.jar}. For applying custom Quartz + * properties, specify {@link #setConfigLocation "configLocation"} and/or + * {@link #setQuartzProperties "quartzProperties"} etc on this local + * {@code SchedulerFactoryBean} instance. + * @see org.quartz.impl.StdSchedulerFactory + * @see #setConfigLocation + * @see #setQuartzProperties + * @see #setTaskExecutor + * @see #setDataSource + */ + public void setSchedulerFactoryClass(Class extends SchedulerFactory> schedulerFactoryClass) { + this.schedulerFactoryClass = schedulerFactoryClass; + } + /** * Set the name of the Scheduler to create via the SchedulerFactory. *
If not specified, the bean name will be used as default scheduler name. @@ -277,14 +276,14 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe this.quartzProperties = quartzProperties; } - /** - * Set the Spring TaskExecutor to use as Quartz backend. + * Set a Spring-managed {@link Executor} to use as Quartz backend. * Exposed as thread pool through the Quartz SPI. - *
Can be used to assign a JDK 1.5 ThreadPoolExecutor or a CommonJ + *
Can be used to assign a local JDK ThreadPoolExecutor or a CommonJ * WorkManager as Quartz backend, to avoid Quartz's manual thread creation. *
By default, a Quartz SimpleThreadPool will be used, configured through * the corresponding Quartz properties. + * @since 2.0 * @see #setQuartzProperties * @see LocalTaskExecutorThreadPool * @see org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor @@ -295,8 +294,8 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe } /** - * Set the default DataSource to be used by the Scheduler. If set, - * this will override corresponding settings in Quartz properties. + * Set the default {@link DataSource} to be used by the Scheduler. + * If set, this will override corresponding settings in Quartz properties. *
Note: If this is set, the Quartz settings should not define * a job store "dataSource" to avoid meaningless double configuration. *
A Spring-specific subclass of Quartz' JobStoreCMT will be used. @@ -309,6 +308,7 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe * argument is sufficient. In case of an XA DataSource and global JTA transactions, * SchedulerFactoryBean's "nonTransactionalDataSource" property should be set, * passing in a non-XA DataSource that will not participate in global transactions. + * @since 1.1 * @see #setNonTransactionalDataSource * @see #setQuartzProperties * @see #setTransactionManager @@ -319,12 +319,13 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe } /** - * Set the DataSource to be used by the Scheduler for non-transactional access. + * Set the {@link DataSource} to be used for non-transactional access. *
This is only necessary if the default DataSource is an XA DataSource that will * always participate in transactions: A non-XA version of that DataSource should * be specified as "nonTransactionalDataSource" in such a scenario. *
This is not relevant with a local DataSource instance and Spring transactions. * Specifying a single default DataSource as "dataSource" is sufficient there. + * @since 1.1 * @see #setDataSource * @see LocalDataSourceJobStore */ @@ -347,7 +348,7 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe } /** - * Set the key of an ApplicationContext reference to expose in the + * Set the key of an {@link ApplicationContext} reference to expose in the * SchedulerContext, for example "applicationContext". Default is none. * Only applicable when running in a Spring ApplicationContext. *
Note: When using persistent Jobs whose JobDetail will be kept in the @@ -367,7 +368,7 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe } /** - * Set the Quartz JobFactory to use for this Scheduler. + * Set the Quartz {@link JobFactory} to use for this Scheduler. *
Default is Spring's {@link AdaptableJobFactory}, which supports * {@link java.lang.Runnable} objects as well as standard Quartz * {@link org.quartz.Job} instances. Note that this default only applies @@ -376,6 +377,7 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe *
Specify an instance of Spring's {@link SpringBeanJobFactory} here * (typically as an inner bean definition) to automatically populate a job's * bean properties from the specified job data map and scheduler context. + * @since 2.0 * @see AdaptableJobFactory * @see SpringBeanJobFactory */ @@ -384,7 +386,6 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe this.jobFactorySet = true; } - /** * Set whether to automatically start the scheduler after initialization. *
Default is "true"; set this to "false" to allow for manual startup. @@ -404,11 +405,12 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe } /** - * Specify the phase in which this scheduler should be started and - * stopped. The startup order proceeds from lowest to highest, and - * the shutdown order is the reverse of that. By default this value - * is Integer.MAX_VALUE meaning that this scheduler starts as late - * as possible and stops as soon as possible. + * Specify the phase in which this scheduler should be started and stopped. + * The startup order proceeds from lowest to highest, and the shutdown order + * is the reverse of that. By default this value is {@code Integer.MAX_VALUE} + * meaning that this scheduler starts as late as possible and stops as soon + * as possible. + * @since 3.0 */ public void setPhase(int phase) { this.phase = phase; @@ -456,7 +458,6 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe this.waitForJobsToCompleteOnShutdown = waitForJobsToCompleteOnShutdown; } - @Override public void setBeanName(String name) { if (this.schedulerName == null) { @@ -548,13 +549,7 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe */ private SchedulerFactory prepareSchedulerFactory() throws SchedulerException, IOException { SchedulerFactory schedulerFactory = this.schedulerFactory; - if (schedulerFactory != null) { - if (schedulerFactory instanceof StdSchedulerFactory) { - initSchedulerFactory((StdSchedulerFactory) schedulerFactory); - } - // Otherwise, assume that externally provided factory has been initialized with appropriate settings... - } - else { + if (schedulerFactory == null) { // Create local SchedulerFactory instance (typically a StdSchedulerFactory) schedulerFactory = BeanUtils.instantiateClass(this.schedulerFactoryClass); if (schedulerFactory instanceof StdSchedulerFactory) { @@ -567,6 +562,7 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe } // Otherwise, no local settings to be applied via StdSchedulerFactory.initialize(Properties) } + // Otherwise, assume that externally provided factory has been initialized with appropriate settings return schedulerFactory; }