Skip to content

Commit 849b6cc

Browse files
committed
SchedulerFactoryBean triggers shutdown after registration failure
Issue: SPR-16816
1 parent 997ca5c commit 849b6cc

File tree

1 file changed

+67
-54
lines changed

1 file changed

+67
-54
lines changed

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

Lines changed: 67 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -470,61 +470,21 @@ public void afterPropertiesSet() throws Exception {
470470
this.resourceLoader = this.applicationContext;
471471
}
472472

473-
// Initialize the SchedulerFactory instance...
474-
SchedulerFactory schedulerFactory = prepareSchedulerFactory();
475-
476-
if (this.resourceLoader != null) {
477-
// Make given ResourceLoader available for SchedulerFactory configuration.
478-
configTimeResourceLoaderHolder.set(this.resourceLoader);
479-
}
480-
if (this.taskExecutor != null) {
481-
// Make given TaskExecutor available for SchedulerFactory configuration.
482-
configTimeTaskExecutorHolder.set(this.taskExecutor);
483-
}
484-
if (this.dataSource != null) {
485-
// Make given DataSource available for SchedulerFactory configuration.
486-
configTimeDataSourceHolder.set(this.dataSource);
487-
}
488-
if (this.nonTransactionalDataSource != null) {
489-
// Make given non-transactional DataSource available for SchedulerFactory configuration.
490-
configTimeNonTransactionalDataSourceHolder.set(this.nonTransactionalDataSource);
491-
}
492-
493-
// Get Scheduler instance from SchedulerFactory.
473+
// Initialize the Scheduler instance...
474+
this.scheduler = prepareScheduler(prepareSchedulerFactory());
494475
try {
495-
this.scheduler = createScheduler(schedulerFactory, this.schedulerName);
496-
populateSchedulerContext();
497-
498-
if (!this.jobFactorySet && !(this.scheduler instanceof RemoteScheduler)) {
499-
// Use AdaptableJobFactory as default for a local Scheduler, unless when
500-
// explicitly given a null value through the "jobFactory" bean property.
501-
this.jobFactory = new AdaptableJobFactory();
502-
}
503-
if (this.jobFactory != null) {
504-
if (this.jobFactory instanceof SchedulerContextAware) {
505-
((SchedulerContextAware) this.jobFactory).setSchedulerContext(this.scheduler.getContext());
506-
}
507-
this.scheduler.setJobFactory(this.jobFactory);
508-
}
476+
registerListeners();
477+
registerJobsAndTriggers();
509478
}
510-
511-
finally {
512-
if (this.resourceLoader != null) {
513-
configTimeResourceLoaderHolder.remove();
514-
}
515-
if (this.taskExecutor != null) {
516-
configTimeTaskExecutorHolder.remove();
479+
catch (Exception ex) {
480+
try {
481+
this.scheduler.shutdown(true);
517482
}
518-
if (this.dataSource != null) {
519-
configTimeDataSourceHolder.remove();
520-
}
521-
if (this.nonTransactionalDataSource != null) {
522-
configTimeNonTransactionalDataSourceHolder.remove();
483+
catch (Exception ex2) {
484+
logger.debug("Scheduler shutdown exception after registration failure", ex2);
523485
}
486+
throw ex;
524487
}
525-
526-
registerListeners();
527-
registerJobsAndTriggers();
528488
}
529489

530490

@@ -591,6 +551,59 @@ private void initSchedulerFactory(StdSchedulerFactory schedulerFactory) throws S
591551
schedulerFactory.initialize(mergedProps);
592552
}
593553

554+
private Scheduler prepareScheduler(SchedulerFactory schedulerFactory) throws SchedulerException {
555+
if (this.resourceLoader != null) {
556+
// Make given ResourceLoader available for SchedulerFactory configuration.
557+
configTimeResourceLoaderHolder.set(this.resourceLoader);
558+
}
559+
if (this.taskExecutor != null) {
560+
// Make given TaskExecutor available for SchedulerFactory configuration.
561+
configTimeTaskExecutorHolder.set(this.taskExecutor);
562+
}
563+
if (this.dataSource != null) {
564+
// Make given DataSource available for SchedulerFactory configuration.
565+
configTimeDataSourceHolder.set(this.dataSource);
566+
}
567+
if (this.nonTransactionalDataSource != null) {
568+
// Make given non-transactional DataSource available for SchedulerFactory configuration.
569+
configTimeNonTransactionalDataSourceHolder.set(this.nonTransactionalDataSource);
570+
}
571+
572+
// Get Scheduler instance from SchedulerFactory.
573+
try {
574+
Scheduler scheduler = createScheduler(schedulerFactory, this.schedulerName);
575+
populateSchedulerContext(scheduler);
576+
577+
if (!this.jobFactorySet && !(scheduler instanceof RemoteScheduler)) {
578+
// Use AdaptableJobFactory as default for a local Scheduler, unless when
579+
// explicitly given a null value through the "jobFactory" bean property.
580+
this.jobFactory = new AdaptableJobFactory();
581+
}
582+
if (this.jobFactory != null) {
583+
if (this.jobFactory instanceof SchedulerContextAware) {
584+
((SchedulerContextAware) this.jobFactory).setSchedulerContext(scheduler.getContext());
585+
}
586+
scheduler.setJobFactory(this.jobFactory);
587+
}
588+
return scheduler;
589+
}
590+
591+
finally {
592+
if (this.resourceLoader != null) {
593+
configTimeResourceLoaderHolder.remove();
594+
}
595+
if (this.taskExecutor != null) {
596+
configTimeTaskExecutorHolder.remove();
597+
}
598+
if (this.dataSource != null) {
599+
configTimeDataSourceHolder.remove();
600+
}
601+
if (this.nonTransactionalDataSource != null) {
602+
configTimeNonTransactionalDataSourceHolder.remove();
603+
}
604+
}
605+
}
606+
594607
/**
595608
* Create the Scheduler instance for the given factory and scheduler name.
596609
* Called by {@link #afterPropertiesSet}.
@@ -610,7 +623,7 @@ protected Scheduler createScheduler(SchedulerFactory schedulerFactory, String sc
610623
Thread currentThread = Thread.currentThread();
611624
ClassLoader threadContextClassLoader = currentThread.getContextClassLoader();
612625
boolean overrideClassLoader = (this.resourceLoader != null &&
613-
!this.resourceLoader.getClassLoader().equals(threadContextClassLoader));
626+
this.resourceLoader.getClassLoader() != threadContextClassLoader);
614627
if (overrideClassLoader) {
615628
currentThread.setContextClassLoader(this.resourceLoader.getClassLoader());
616629
}
@@ -642,10 +655,10 @@ protected Scheduler createScheduler(SchedulerFactory schedulerFactory, String sc
642655
* Expose the specified context attributes and/or the current
643656
* ApplicationContext in the Quartz SchedulerContext.
644657
*/
645-
private void populateSchedulerContext() throws SchedulerException {
658+
private void populateSchedulerContext(Scheduler scheduler) throws SchedulerException {
646659
// Put specified objects into Scheduler context.
647660
if (this.schedulerContextMap != null) {
648-
getScheduler().getContext().putAll(this.schedulerContextMap);
661+
scheduler.getContext().putAll(this.schedulerContextMap);
649662
}
650663

651664
// Register ApplicationContext in Scheduler context.
@@ -655,7 +668,7 @@ private void populateSchedulerContext() throws SchedulerException {
655668
"SchedulerFactoryBean needs to be set up in an ApplicationContext " +
656669
"to be able to handle an 'applicationContextSchedulerContextKey'");
657670
}
658-
getScheduler().getContext().put(this.applicationContextSchedulerContextKey, this.applicationContext);
671+
scheduler.getContext().put(this.applicationContextSchedulerContextKey, this.applicationContext);
659672
}
660673
}
661674

0 commit comments

Comments
 (0)