SchedulerFactoryBean triggers shutdown after registration failure

Issue: SPR-16816
This commit is contained in:
Juergen Hoeller 2018-05-16 00:45:33 +02:00
parent 3c8c99664f
commit 009824598c
1 changed files with 66 additions and 53 deletions

View File

@ -486,61 +486,21 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
this.resourceLoader = this.applicationContext; this.resourceLoader = this.applicationContext;
} }
// Initialize the SchedulerFactory instance... // Initialize the Scheduler instance...
SchedulerFactory schedulerFactory = prepareSchedulerFactory(); this.scheduler = prepareScheduler(prepareSchedulerFactory());
if (this.resourceLoader != null) {
// Make given ResourceLoader available for SchedulerFactory configuration.
configTimeResourceLoaderHolder.set(this.resourceLoader);
}
if (this.taskExecutor != null) {
// Make given TaskExecutor available for SchedulerFactory configuration.
configTimeTaskExecutorHolder.set(this.taskExecutor);
}
if (this.dataSource != null) {
// Make given DataSource available for SchedulerFactory configuration.
configTimeDataSourceHolder.set(this.dataSource);
}
if (this.nonTransactionalDataSource != null) {
// Make given non-transactional DataSource available for SchedulerFactory configuration.
configTimeNonTransactionalDataSourceHolder.set(this.nonTransactionalDataSource);
}
// Get Scheduler instance from SchedulerFactory.
try { try {
this.scheduler = createScheduler(schedulerFactory, this.schedulerName); registerListeners();
populateSchedulerContext(); registerJobsAndTriggers();
if (!this.jobFactorySet && !(this.scheduler instanceof RemoteScheduler)) {
// Use AdaptableJobFactory as default for a local Scheduler, unless when
// explicitly given a null value through the "jobFactory" bean property.
this.jobFactory = new AdaptableJobFactory();
}
if (this.jobFactory != null) {
if (this.jobFactory instanceof SchedulerContextAware) {
((SchedulerContextAware) this.jobFactory).setSchedulerContext(this.scheduler.getContext());
}
this.scheduler.setJobFactory(this.jobFactory);
}
} }
catch (Exception ex) {
finally { try {
if (this.resourceLoader != null) { this.scheduler.shutdown(true);
configTimeResourceLoaderHolder.remove();
} }
if (this.taskExecutor != null) { catch (Exception ex2) {
configTimeTaskExecutorHolder.remove(); logger.debug("Scheduler shutdown exception after registration failure", ex2);
}
if (this.dataSource != null) {
configTimeDataSourceHolder.remove();
}
if (this.nonTransactionalDataSource != null) {
configTimeNonTransactionalDataSourceHolder.remove();
} }
throw ex;
} }
registerListeners();
registerJobsAndTriggers();
} }
@ -607,6 +567,59 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
schedulerFactory.initialize(mergedProps); schedulerFactory.initialize(mergedProps);
} }
private Scheduler prepareScheduler(SchedulerFactory schedulerFactory) throws SchedulerException {
if (this.resourceLoader != null) {
// Make given ResourceLoader available for SchedulerFactory configuration.
configTimeResourceLoaderHolder.set(this.resourceLoader);
}
if (this.taskExecutor != null) {
// Make given TaskExecutor available for SchedulerFactory configuration.
configTimeTaskExecutorHolder.set(this.taskExecutor);
}
if (this.dataSource != null) {
// Make given DataSource available for SchedulerFactory configuration.
configTimeDataSourceHolder.set(this.dataSource);
}
if (this.nonTransactionalDataSource != null) {
// Make given non-transactional DataSource available for SchedulerFactory configuration.
configTimeNonTransactionalDataSourceHolder.set(this.nonTransactionalDataSource);
}
// Get Scheduler instance from SchedulerFactory.
try {
Scheduler scheduler = createScheduler(schedulerFactory, this.schedulerName);
populateSchedulerContext(scheduler);
if (!this.jobFactorySet && !(scheduler instanceof RemoteScheduler)) {
// Use AdaptableJobFactory as default for a local Scheduler, unless when
// explicitly given a null value through the "jobFactory" bean property.
this.jobFactory = new AdaptableJobFactory();
}
if (this.jobFactory != null) {
if (this.jobFactory instanceof SchedulerContextAware) {
((SchedulerContextAware) this.jobFactory).setSchedulerContext(scheduler.getContext());
}
scheduler.setJobFactory(this.jobFactory);
}
return scheduler;
}
finally {
if (this.resourceLoader != null) {
configTimeResourceLoaderHolder.remove();
}
if (this.taskExecutor != null) {
configTimeTaskExecutorHolder.remove();
}
if (this.dataSource != null) {
configTimeDataSourceHolder.remove();
}
if (this.nonTransactionalDataSource != null) {
configTimeNonTransactionalDataSourceHolder.remove();
}
}
}
/** /**
* Create the Scheduler instance for the given factory and scheduler name. * Create the Scheduler instance for the given factory and scheduler name.
* Called by {@link #afterPropertiesSet}. * Called by {@link #afterPropertiesSet}.
@ -658,10 +671,10 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
* Expose the specified context attributes and/or the current * Expose the specified context attributes and/or the current
* ApplicationContext in the Quartz SchedulerContext. * ApplicationContext in the Quartz SchedulerContext.
*/ */
private void populateSchedulerContext() throws SchedulerException { private void populateSchedulerContext(Scheduler scheduler) throws SchedulerException {
// Put specified objects into Scheduler context. // Put specified objects into Scheduler context.
if (this.schedulerContextMap != null) { if (this.schedulerContextMap != null) {
getScheduler().getContext().putAll(this.schedulerContextMap); scheduler.getContext().putAll(this.schedulerContextMap);
} }
// Register ApplicationContext in Scheduler context. // Register ApplicationContext in Scheduler context.
@ -671,7 +684,7 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
"SchedulerFactoryBean needs to be set up in an ApplicationContext " + "SchedulerFactoryBean needs to be set up in an ApplicationContext " +
"to be able to handle an 'applicationContextSchedulerContextKey'"); "to be able to handle an 'applicationContextSchedulerContextKey'");
} }
getScheduler().getContext().put(this.applicationContextSchedulerContextKey, this.applicationContext); scheduler.getContext().put(this.applicationContextSchedulerContextKey, this.applicationContext);
} }
} }