Skip to content

Commit a3bcdbe

Browse files
committed
SchedulerFactoryBean triggers shutdown after registration failure
Issue: SPR-16816 (cherry picked from commit 0098245)
1 parent 3978d55 commit a3bcdbe

File tree

1 file changed

+66
-53
lines changed

1 file changed

+66
-53
lines changed

spring-context-support/src/main/java/org/springframework/scheduling/quartz/SchedulerFactoryBean.java

Lines changed: 66 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -486,61 +486,21 @@ public void afterPropertiesSet() throws Exception {
486486
this.resourceLoader = this.applicationContext;
487487
}
488488

489-
// Initialize the SchedulerFactory instance...
490-
SchedulerFactory schedulerFactory = prepareSchedulerFactory();
491-
492-
if (this.resourceLoader != null) {
493-
// Make given ResourceLoader available for SchedulerFactory configuration.
494-
configTimeResourceLoaderHolder.set(this.resourceLoader);
495-
}
496-
if (this.taskExecutor != null) {
497-
// Make given TaskExecutor available for SchedulerFactory configuration.
498-
configTimeTaskExecutorHolder.set(this.taskExecutor);
499-
}
500-
if (this.dataSource != null) {
501-
// Make given DataSource available for SchedulerFactory configuration.
502-
configTimeDataSourceHolder.set(this.dataSource);
503-
}
504-
if (this.nonTransactionalDataSource != null) {
505-
// Make given non-transactional DataSource available for SchedulerFactory configuration.
506-
configTimeNonTransactionalDataSourceHolder.set(this.nonTransactionalDataSource);
507-
}
508-
509-
// Get Scheduler instance from SchedulerFactory.
489+
// Initialize the Scheduler instance...
490+
this.scheduler = prepareScheduler(prepareSchedulerFactory());
510491
try {
511-
this.scheduler = createScheduler(schedulerFactory, this.schedulerName);
512-
populateSchedulerContext();
513-
514-
if (!this.jobFactorySet && !(this.scheduler instanceof RemoteScheduler)) {
515-
// Use AdaptableJobFactory as default for a local Scheduler, unless when
516-
// explicitly given a null value through the "jobFactory" bean property.
517-
this.jobFactory = new AdaptableJobFactory();
518-
}
519-
if (this.jobFactory != null) {
520-
if (this.jobFactory instanceof SchedulerContextAware) {
521-
((SchedulerContextAware) this.jobFactory).setSchedulerContext(this.scheduler.getContext());
522-
}
523-
this.scheduler.setJobFactory(this.jobFactory);
524-
}
492+
registerListeners();
493+
registerJobsAndTriggers();
525494
}
526-
527-
finally {
528-
if (this.resourceLoader != null) {
529-
configTimeResourceLoaderHolder.remove();
530-
}
531-
if (this.taskExecutor != null) {
532-
configTimeTaskExecutorHolder.remove();
495+
catch (Exception ex) {
496+
try {
497+
this.scheduler.shutdown(true);
533498
}
534-
if (this.dataSource != null) {
535-
configTimeDataSourceHolder.remove();
536-
}
537-
if (this.nonTransactionalDataSource != null) {
538-
configTimeNonTransactionalDataSourceHolder.remove();
499+
catch (Exception ex2) {
500+
logger.debug("Scheduler shutdown exception after registration failure", ex2);
539501
}
502+
throw ex;
540503
}
541-
542-
registerListeners();
543-
registerJobsAndTriggers();
544504
}
545505

546506

@@ -607,6 +567,59 @@ private void initSchedulerFactory(StdSchedulerFactory schedulerFactory) throws S
607567
schedulerFactory.initialize(mergedProps);
608568
}
609569

570+
private Scheduler prepareScheduler(SchedulerFactory schedulerFactory) throws SchedulerException {
571+
if (this.resourceLoader != null) {
572+
// Make given ResourceLoader available for SchedulerFactory configuration.
573+
configTimeResourceLoaderHolder.set(this.resourceLoader);
574+
}
575+
if (this.taskExecutor != null) {
576+
// Make given TaskExecutor available for SchedulerFactory configuration.
577+
configTimeTaskExecutorHolder.set(this.taskExecutor);
578+
}
579+
if (this.dataSource != null) {
580+
// Make given DataSource available for SchedulerFactory configuration.
581+
configTimeDataSourceHolder.set(this.dataSource);
582+
}
583+
if (this.nonTransactionalDataSource != null) {
584+
// Make given non-transactional DataSource available for SchedulerFactory configuration.
585+
configTimeNonTransactionalDataSourceHolder.set(this.nonTransactionalDataSource);
586+
}
587+
588+
// Get Scheduler instance from SchedulerFactory.
589+
try {
590+
Scheduler scheduler = createScheduler(schedulerFactory, this.schedulerName);
591+
populateSchedulerContext(scheduler);
592+
593+
if (!this.jobFactorySet && !(scheduler instanceof RemoteScheduler)) {
594+
// Use AdaptableJobFactory as default for a local Scheduler, unless when
595+
// explicitly given a null value through the "jobFactory" bean property.
596+
this.jobFactory = new AdaptableJobFactory();
597+
}
598+
if (this.jobFactory != null) {
599+
if (this.jobFactory instanceof SchedulerContextAware) {
600+
((SchedulerContextAware) this.jobFactory).setSchedulerContext(scheduler.getContext());
601+
}
602+
scheduler.setJobFactory(this.jobFactory);
603+
}
604+
return scheduler;
605+
}
606+
607+
finally {
608+
if (this.resourceLoader != null) {
609+
configTimeResourceLoaderHolder.remove();
610+
}
611+
if (this.taskExecutor != null) {
612+
configTimeTaskExecutorHolder.remove();
613+
}
614+
if (this.dataSource != null) {
615+
configTimeDataSourceHolder.remove();
616+
}
617+
if (this.nonTransactionalDataSource != null) {
618+
configTimeNonTransactionalDataSourceHolder.remove();
619+
}
620+
}
621+
}
622+
610623
/**
611624
* Create the Scheduler instance for the given factory and scheduler name.
612625
* Called by {@link #afterPropertiesSet}.
@@ -658,10 +671,10 @@ protected Scheduler createScheduler(SchedulerFactory schedulerFactory, @Nullable
658671
* Expose the specified context attributes and/or the current
659672
* ApplicationContext in the Quartz SchedulerContext.
660673
*/
661-
private void populateSchedulerContext() throws SchedulerException {
674+
private void populateSchedulerContext(Scheduler scheduler) throws SchedulerException {
662675
// Put specified objects into Scheduler context.
663676
if (this.schedulerContextMap != null) {
664-
getScheduler().getContext().putAll(this.schedulerContextMap);
677+
scheduler.getContext().putAll(this.schedulerContextMap);
665678
}
666679

667680
// Register ApplicationContext in Scheduler context.
@@ -671,7 +684,7 @@ private void populateSchedulerContext() throws SchedulerException {
671684
"SchedulerFactoryBean needs to be set up in an ApplicationContext " +
672685
"to be able to handle an 'applicationContextSchedulerContextKey'");
673686
}
674-
getScheduler().getContext().put(this.applicationContextSchedulerContextKey, this.applicationContext);
687+
scheduler.getContext().put(this.applicationContextSchedulerContextKey, this.applicationContext);
675688
}
676689
}
677690

0 commit comments

Comments
 (0)