From c2459b4a616b3816aa67e6d34827aa5544d8c66a Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Sun, 5 Jan 2014 17:24:18 +0100 Subject: [PATCH] Full Quartz 2.2 support, including LocalDataSourceJobStore While we've had basic Quartz 2.2 support before, a few details were missing: * LocalDataSourceJobStore's ConnectionProvider adapters need to provide an empty implementation of Quartz 2.2's new initialize method. * SchedulerFactoryBean's "schedulerContextMap" needs to be explicitly declared with String keys, otherwise it can't be compiled against Quartz 2.2 (forward compatibility once we're dropping Quartz 1.x support). This doesn't hurt against older Quartz versions either, since the keys need to be Strings anyway. Issue: SPR-11284 (cherry picked from commit 38a8ace) --- .../quartz/LocalDataSourceJobStore.java | 27 +++++++++++-------- .../quartz/SchedulerFactoryBean.java | 15 +++++------ 2 files changed, 23 insertions(+), 19 deletions(-) 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 c9664b28f8..86cb3ed6d2 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-2012 the original author or authors. + * Copyright 2002-2013 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,7 +18,6 @@ package org.springframework.scheduling.quartz; import java.sql.Connection; import java.sql.SQLException; - import javax.sql.DataSource; import org.quartz.SchedulerConfigException; @@ -108,14 +107,17 @@ public class LocalDataSourceJobStore extends JobStoreCMT { public void shutdown() { // Do nothing - a Spring-managed DataSource has its own lifecycle. } + /* Quartz 2.2 initialize method */ + public void initialize() { + // Do nothing - a Spring-managed DataSource has its own lifecycle. + } } ); // Non-transactional DataSource is optional: fall back to default // DataSource if not explicitly specified. DataSource nonTxDataSource = SchedulerFactoryBean.getConfigTimeNonTransactionalDataSource(); - final DataSource nonTxDataSourceToUse = - (nonTxDataSource != null ? nonTxDataSource : this.dataSource); + final DataSource nonTxDataSourceToUse = (nonTxDataSource != null ? nonTxDataSource : this.dataSource); // Configure non-transactional connection settings for Quartz. setNonManagedTXDataSource(NON_TX_DATA_SOURCE_PREFIX + getInstanceName()); @@ -131,21 +133,24 @@ public class LocalDataSourceJobStore extends JobStoreCMT { public void shutdown() { // Do nothing - a Spring-managed DataSource has its own lifecycle. } + /* Quartz 2.2 initialize method */ + public void initialize() { + // Do nothing - a Spring-managed DataSource has its own lifecycle. + } } ); - // No, if HSQL is the platform, we really don't want to use locks + // No, if HSQL is the platform, we really don't want to use locks... try { - String productName = JdbcUtils.extractDatabaseMetaData(dataSource, - "getDatabaseProductName").toString(); + String productName = JdbcUtils.extractDatabaseMetaData(this.dataSource, "getDatabaseProductName").toString(); productName = JdbcUtils.commonDatabaseName(productName); - if (productName != null - && productName.toLowerCase().contains("hsql")) { + if (productName != null && productName.toLowerCase().contains("hsql")) { setUseDBLocks(false); setLockHandler(new SimpleSemaphore()); } - } catch (MetaDataAccessException e) { - logWarnIfNonZero(1, "Could not detect database type. Assuming locks can be taken."); + } + catch (MetaDataAccessException ex) { + logWarnIfNonZero(1, "Could not detect database type. Assuming locks can be taken."); } super.initialize(loadHelper, signaler); 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 6279ac28f0..01cec637e7 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 @@ -43,6 +43,7 @@ import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; import org.springframework.core.io.support.PropertiesLoaderUtils; import org.springframework.scheduling.SchedulingException; +import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; /** @@ -157,7 +158,7 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe } - private Class schedulerFactoryClass = StdSchedulerFactory.class; + private Class schedulerFactoryClass = StdSchedulerFactory.class; private String schedulerName; @@ -173,7 +174,7 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe private DataSource nonTransactionalDataSource; - private Map schedulerContextMap; + private Map schedulerContextMap; private ApplicationContext applicationContext; @@ -200,7 +201,7 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe /** * Set the Quartz SchedulerFactory implementation to use. - *

Default is StdSchedulerFactory, reading in the standard + *

Default is {@link StdSchedulerFactory}, reading in the standard * {@code quartz.properties} from {@code quartz.jar}. * To use custom Quartz properties, specify the "configLocation" * or "quartzProperties" bean property on this FactoryBean. @@ -208,10 +209,8 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe * @see #setConfigLocation * @see #setQuartzProperties */ - public void setSchedulerFactoryClass(Class schedulerFactoryClass) { - if (schedulerFactoryClass == null || !SchedulerFactory.class.isAssignableFrom(schedulerFactoryClass)) { - throw new IllegalArgumentException("schedulerFactoryClass must implement [org.quartz.SchedulerFactory]"); - } + public void setSchedulerFactoryClass(Class schedulerFactoryClass) { + Assert.isAssignable(SchedulerFactory.class, schedulerFactoryClass); this.schedulerFactoryClass = schedulerFactoryClass; } @@ -313,7 +312,7 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe * values (for example Spring-managed beans) * @see JobDetailBean#setJobDataAsMap */ - public void setSchedulerContextAsMap(Map schedulerContextAsMap) { + public void setSchedulerContextAsMap(Map schedulerContextAsMap) { this.schedulerContextMap = schedulerContextAsMap; }