下面列出了怎么用org.quartz.spi.ClassLoadHelper的API类实例代码及写法,或者点击链接到github查看源代码。
@Override
public void initialize(ClassLoadHelper loadHelper, SchedulerSignaler signaler) throws SchedulerConfigException {
init();
realJobStore.setInstanceId(schedInstId);
realJobStore.setInstanceName(schedName);
realJobStore.setTcRetryInterval(tcRetryInterval);
if (misFireThreshold != null) {
realJobStore.setMisfireThreshold(misFireThreshold);
}
if (synchWrite != null) {
realJobStore.setSynchronousWrite(synchWrite);
}
if (estimatedTimeToReleaseAndAcquireTrigger != null) {
realJobStore.setEstimatedTimeToReleaseAndAcquireTrigger(estimatedTimeToReleaseAndAcquireTrigger);
}
realJobStore.initialize(loadHelper, signaler);
}
/**
* <p>
* Called by the QuartzScheduler before the <code>JobStore</code> is used, in order to give the it a chance to
* initialize.
* </p>
*/
@Override
// XXX: remove this suppression
@SuppressWarnings("unchecked")
public void initialize(ClassLoadHelper loadHelper, SchedulerSignaler schedulerSignaler) {
this.terracottaClientId = clusterInfo.getCurrentNode().getId();
this.ftrCtr = System.currentTimeMillis();
// this MUST happen before initializing the trigger set (otherwise we might receive an update which get an NPE)
// this.serializer.setClassLoadHelper(loadHelper);
this.signaler = schedulerSignaler;
getLog().info(getClass().getSimpleName() + " initialized.");
((ToolkitInternal) toolkit).registerBeforeShutdownHook(new ShutdownHook(this));
}
@Override
public synchronized void initialize(ClassLoadHelper loadHelper, SchedulerSignaler signaler)
throws SchedulerConfigException {
if (clusteredJobStore != null) { throw new IllegalStateException("already initialized"); }
clusteredJobStore = createNewJobStoreInstance(schedName, Boolean.valueOf(synchWrite));
clusteredJobStore.setThreadPoolSize(threadPoolSize);
// apply deferred misfire threshold if present
if (misfireThreshold != null) {
clusteredJobStore.setMisfireThreshold(misfireThreshold);
misfireThreshold = null;
}
if (estimatedTimeToReleaseAndAcquireTrigger != null) {
clusteredJobStore.setEstimatedTimeToReleaseAndAcquireTrigger(estimatedTimeToReleaseAndAcquireTrigger);
estimatedTimeToReleaseAndAcquireTrigger = null;
}
clusteredJobStore.setInstanceId(schedInstanceId);
clusteredJobStore.setTcRetryInterval(tcRetryInterval);
clusteredJobStore.initialize(loadHelper, signaler);
// update check
scheduleUpdateCheck();
}
@Override
public void initialize(ClassLoadHelper loadHelper,
SchedulerSignaler signaler) throws SchedulerConfigException {
if (nonManagedTxDsName == null) {
throw new SchedulerConfigException(
"Non-ManagedTX DataSource name not set! " +
"If your 'org.quartz.jobStore.dataSource' is XA, then set " +
"'org.quartz.jobStore.nonManagedTXDataSource' to a non-XA "+
"datasource (for the same DB). " +
"Otherwise, you can set them to be the same.");
}
if (getLockHandler() == null) {
// If the user hasn't specified an explicit lock handler,
// then we *must* use DB locks with CMT...
setUseDBLocks(true);
}
super.initialize(loadHelper, signaler);
getLog().info("JobStoreCMT initialized.");
}
/**
* <p>
* Called during creation of the <code>Scheduler</code> in order to give
* the <code>SchedulerPlugin</code> a chance to initialize.
* </p>
*
* @throws SchedulerConfigException
* if there is an error initializing.
*/
public void initialize(String name, final Scheduler scheduler, ClassLoadHelper classLoadHelper)
throws SchedulerException {
getLog().info("Registering Quartz shutdown hook.");
Thread t = new Thread("Quartz Shutdown-Hook "
+ scheduler.getSchedulerName()) {
@Override
public void run() {
getLog().info("Shutting down Quartz...");
try {
scheduler.shutdown(isCleanShutdown());
} catch (SchedulerException e) {
getLog().info(
"Error shutting down Quartz: " + e.getMessage(), e);
}
}
};
Runtime.getRuntime().addShutdownHook(t);
}
/**
* <p>
* Called during creation of the <code>Scheduler</code> in order to give
* the <code>SchedulerPlugin</code> a chance to initialize.
* </p>
*
* @throws org.quartz.SchedulerConfigException
* if there is an error initializing.
*/
public void initialize(String name, final Scheduler scheduler, ClassLoadHelper schedulerFactoryClassLoadHelper)
throws SchedulerException {
super.initialize(name, scheduler);
this.classLoadHelper = schedulerFactoryClassLoadHelper;
getLog().info("Registering Quartz Job Initialization Plug-in.");
// Create JobFile objects
StringTokenizer stok = new StringTokenizer(fileNames, FILE_NAME_DELIMITERS);
while (stok.hasMoreTokens()) {
final String fileName = stok.nextToken();
final JobFile jobFile = new JobFile(fileName);
jobFiles.put(fileName, jobFile);
}
}
public void initialize(ClassLoadHelper loadHelper,
SchedulerSignaler signaler) throws SchedulerConfigException {
if (nonManagedTxDsName == null) {
throw new SchedulerConfigException(
"Non-ManagedTX DataSource name not set! " +
"If your 'org.quartz.jobStore.dataSource' is XA, then set " +
"'org.quartz.jobStore.nonManagedTXDataSource' to a non-XA "+
"datasource (for the same DB). " +
"Otherwise, you can set them to be the same.");
}
if (getLockHandler() == null) {
// If the user hasn't specified an explicit lock handler,
// then we *must* use DB locks with CMT...
setUseDBLocks(true);
}
super.initialize(loadHelper, signaler);
getLog().info("JobStoreCMT initialized.");
}
public void init() throws ParserConfigurationException, XPathException, ParseException, IOException, ValidationException, SchedulerException, SAXException, ClassNotFoundException {
boolean noFiles = files == null || files.isEmpty();
if (noFiles || !schedulerManager.isAutoProvisioning()) {
log.info("Not auto provisioning jobs: "+ ((noFiles)?"no files.":String.join(", ", files)));
return;
}
Scheduler scheduler = schedulerManager.getScheduler();
ClassLoadHelper clh = new CascadingClassLoadHelper();
clh.initialize();
for (String file : files ) {
XMLSchedulingDataProcessor proc = new XMLSchedulingDataProcessor(clh);
InputStream in = getClass().getResourceAsStream(file);
if (in == null) {
throw new IllegalArgumentException("Couldn't find resource on classpath: "+ file);
}
try {
proc.processStreamAndScheduleJobs(in, file, scheduler);
log.info("Successfully provisioned jobs/triggers from :"+ file);
} catch (ObjectAlreadyExistsException e) {
log.info("Not fully processing: "+ file+ " because some parts already exist");
}
}
}
public void init() throws ParserConfigurationException, XPathException, ParseException, IOException, ValidationException, SchedulerException, SAXException, ClassNotFoundException {
boolean noFiles = files == null || files.isEmpty();
if (noFiles || !schedulerManager.isAutoProvisioning()) {
log.info("Not auto provisioning jobs: "+ ((noFiles)?"no files.":String.join(", ", files)));
return;
}
Scheduler scheduler = schedulerManager.getScheduler();
ClassLoadHelper clh = new CascadingClassLoadHelper();
clh.initialize();
for (String file : files ) {
XMLSchedulingDataProcessor proc = new XMLSchedulingDataProcessor(clh);
InputStream in = getClass().getResourceAsStream(file);
if (in == null) {
throw new IllegalArgumentException("Couldn't find resource on classpath: "+ file);
}
try {
proc.processStreamAndScheduleJobs(in, file, scheduler);
log.info("Successfully provisioned jobs/triggers from :"+ file);
} catch (ObjectAlreadyExistsException e) {
log.info("Not fully processing: "+ file+ " because some parts already exist");
}
}
}
/**
* Called to give the ClassLoadHelper a chance to initialize itself,
* including the opportunity to "steal" the class loader off of the calling
* thread, which is the thread that is initializing Quartz.
*/
public void initialize() {
loadHelpers = new LinkedList<ClassLoadHelper>();
loadHelpers.add(new LoadingLoaderClassLoadHelper());
loadHelpers.add(new SimpleClassLoadHelper());
loadHelpers.add(new ThreadContextClassLoadHelper());
loadHelpers.add(new InitThreadContextClassLoadHelper());
for(ClassLoadHelper loadHelper: loadHelpers) {
loadHelper.initialize();
}
}
/**
* Finds a resource with a given name. This method returns null if no
* resource with this name is found.
* @param name name of the desired resource
* @return a java.net.URL object
*/
public URL getResource(String name) {
URL result = null;
if (bestCandidate != null) {
result = bestCandidate.getResource(name);
if(result == null) {
bestCandidate = null;
}
else {
return result;
}
}
ClassLoadHelper loadHelper = null;
Iterator<ClassLoadHelper> iter = loadHelpers.iterator();
while (iter.hasNext()) {
loadHelper = iter.next();
result = loadHelper.getResource(name);
if (result != null) {
break;
}
}
bestCandidate = loadHelper;
return result;
}
/**
* Finds a resource with a given name. This method returns null if no
* resource with this name is found.
* @param name name of the desired resource
* @return a java.io.InputStream object
*/
public InputStream getResourceAsStream(String name) {
InputStream result = null;
if (bestCandidate != null) {
result = bestCandidate.getResourceAsStream(name);
if(result == null) {
bestCandidate = null;
}
else {
return result;
}
}
ClassLoadHelper loadHelper = null;
Iterator<ClassLoadHelper> iter = loadHelpers.iterator();
while (iter.hasNext()) {
loadHelper = iter.next();
result = loadHelper.getResourceAsStream(name);
if (result != null) {
break;
}
}
bestCandidate = loadHelper;
return result;
}
@Override
public void initialize(ClassLoadHelper classLoadHelper,
SchedulerSignaler schedSignaler) throws SchedulerConfigException {
super.initialize(classLoadHelper, schedSignaler);
getLog().info("JobStoreTX initialized.");
}
/**
* @param initString of the format: settingName=settingValue|otherSettingName=otherSettingValue|...
* @throws NoSuchDelegateException
*/
public void initialize(Logger logger, String tablePrefix, String schedName, String instanceId, ClassLoadHelper classLoadHelper, boolean useProperties, String initString) throws NoSuchDelegateException {
this.logger = logger;
this.tablePrefix = tablePrefix;
this.schedName = schedName;
this.instanceId = instanceId;
this.useProperties = useProperties;
this.classLoadHelper = classLoadHelper;
addDefaultTriggerPersistenceDelegates();
if(initString == null)
return;
String[] settings = initString.split("\\|");
for(String setting: settings) {
String[] parts = setting.split("=");
String name = parts[0];
if(parts.length == 1 || parts[1] == null || parts[1].equals(""))
continue;
if(name.equals("triggerPersistenceDelegateClasses")) {
String[] trigDelegates = parts[1].split(",");
for(String trigDelClassName: trigDelegates) {
try {
Class<?> trigDelClass = classLoadHelper.loadClass(trigDelClassName);
addTriggerPersistenceDelegate((TriggerPersistenceDelegate) trigDelClass.newInstance());
} catch (Exception e) {
throw new NoSuchDelegateException("Error instantiating TriggerPersistenceDelegate of type: " + trigDelClassName, e);
}
}
}
else
throw new NoSuchDelegateException("Unknown setting: '" + name + "'");
}
}
/**
* <p>
* Select the job to which the trigger is associated. Allow option to load actual job class or not. When case of
* remove, we do not need to load the class, which in many cases, it's no longer exists.
*
* </p>
*
* @param conn
* the DB Connection
* @return the <code>{@link org.quartz.JobDetail}</code> object
* associated with the given trigger
* @throws SQLException
* @throws ClassNotFoundException
*/
public JobDetail selectJobForTrigger(Connection conn, ClassLoadHelper loadHelper,
TriggerKey triggerKey, boolean loadJobClass) throws ClassNotFoundException, SQLException {
PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = conn.prepareStatement(rtp(SELECT_JOB_FOR_TRIGGER));
ps.setString(1, triggerKey.getName());
ps.setString(2, triggerKey.getGroup());
rs = ps.executeQuery();
if (rs.next()) {
JobDetailImpl job = new JobDetailImpl();
job.setName(rs.getString(1));
job.setGroup(rs.getString(2));
job.setDurability(getBoolean(rs, 3));
if (loadJobClass)
job.setJobClass(loadHelper.loadClass(rs.getString(4), Job.class));
job.setRequestsRecovery(getBoolean(rs, 5));
return job;
} else {
if (logger.isDebugEnabled()) {
logger.debug("No job for trigger '" + triggerKey + "'.");
}
return null;
}
} finally {
closeResultSet(rs);
closeStatement(ps);
}
}
/**
* Called to give the ClassLoadHelper a chance to initialize itself,
* including the opportunity to "steal" the class loader off of the calling
* thread, which is the thread that is initializing Quartz.
*/
public void initialize() {
loadHelpers = new LinkedList();
loadHelpers.add(new LoadingLoaderClassLoadHelper());
loadHelpers.add(new SimpleClassLoadHelper());
loadHelpers.add(new ThreadContextClassLoadHelper());
loadHelpers.add(new InitThreadContextClassLoadHelper());
Iterator iter = loadHelpers.iterator();
while (iter.hasNext()) {
ClassLoadHelper loadHelper = (ClassLoadHelper) iter.next();
loadHelper.initialize();
}
}
/**
* <p>
* Called by the QuartzScheduler before the <code>JobStore</code> is
* used, in order to give the it a chance to initialize.
* </p>
*/
public void initialize(ClassLoadHelper loadHelper,
SchedulerSignaler signaler) {
this.signaler = signaler;
getLog().info("RAMJobStore initialized.");
}
/**
* <p>
* Select the job to which the trigger is associated.
* </p>
*
* @param conn
* the DB Connection
* @param triggerName
* the name of the trigger
* @param groupName
* the group containing the trigger
* @return the <code>{@link org.quartz.JobDetail}</code> object
* associated with the given trigger
* @throws SQLException
* @throws ClassNotFoundException
*/
public JobDetail selectJobForTrigger(Connection conn, String triggerName,
String groupName, ClassLoadHelper loadHelper) throws ClassNotFoundException, SQLException {
PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = conn.prepareStatement(rtp(SELECT_JOB_FOR_TRIGGER));
ps.setString(1, triggerName);
ps.setString(2, groupName);
rs = ps.executeQuery();
if (rs.next()) {
JobDetail job = new JobDetail();
job.setName(rs.getString(1));
job.setGroup(rs.getString(2));
job.setDurability(getBoolean(rs, 3));
job.setJobClass(loadHelper.loadClass(rs
.getString(4)));
job.setRequestsRecovery(getBoolean(rs, 5));
return job;
} else {
if (logger.isDebugEnabled()) {
logger.debug("No job for trigger '" + groupName + "."
+ triggerName + "'.");
}
return null;
}
} finally {
closeResultSet(rs);
closeStatement(ps);
}
}
@Override
public void initialize(final ClassLoadHelper loadHelper, final SchedulerSignaler signaler)
throws SchedulerConfigException
{
log.info("Instance name: {}; ID: {}", instanceName, instanceId);
// TODO: Should we consider using ClassLoadHelper?
this.signaler = checkNotNull(signaler);
log.info("Initialized");
}
@Before
public void setUp() throws Exception {
ClassLoadHelper loadHelper = new CascadingClassLoadHelper();
nodeAccess = mock(NodeAccess.class);
loadHelper.initialize();
this.jobStore = createJobStore();
this.jobStore.start();
this.jobStore.initialize(loadHelper, new SampleSignaler());
this.jobStore.schedulerStarted();
}
@SuppressWarnings("deprecation")
@Before
public void setUp() throws Exception {
this.fSignaler = new SampleSignaler();
ClassLoadHelper loadHelper = new CascadingClassLoadHelper();
loadHelper.initialize();
this.fJobStore = createJobStore("AbstractJobStoreTest");
this.fJobStore.initialize(loadHelper, this.fSignaler);
this.fJobStore.schedulerStarted();
this.fJobDetail = new JobDetailImpl("job1", "jobGroup1", MyJob.class);
this.fJobDetail.setDurability(true);
this.fJobStore.storeJob(this.fJobDetail, false);
}
@Test
public void testAcquireTriggers() throws Exception {
SchedulerSignaler schedSignaler = new SampleSignaler();
ClassLoadHelper loadHelper = new CascadingClassLoadHelper();
loadHelper.initialize();
JobStore store = createJobStore("testAcquireTriggers");
store.initialize(loadHelper, schedSignaler);
// Setup: Store jobs and triggers.
long MIN = 60 * 1000L;
Date startTime0 = new Date(System.currentTimeMillis() + MIN); // a min from now.
for (int i=0; i < 10; i++) {
Date startTime = new Date(startTime0.getTime() + i * MIN); // a min apart
JobDetail job = JobBuilder.newJob(MyJob.class).withIdentity("job" + i).build();
SimpleScheduleBuilder schedule = SimpleScheduleBuilder.repeatMinutelyForever(2);
OperableTrigger trigger = (OperableTrigger)TriggerBuilder.newTrigger().withIdentity("job" + i).withSchedule(schedule).forJob(job).startAt(startTime).build();
// Manually trigger the first fire time computation that scheduler would do. Otherwise
// the store.acquireNextTriggers() will not work properly.
Date fireTime = trigger.computeFirstFireTime(null);
Assert.assertEquals(true, fireTime != null);
store.storeJobAndTrigger(job, trigger);
}
// Test acquire one trigger at a time
for (int i=0; i < 10; i++) {
long noLaterThan = (startTime0.getTime() + i * MIN);
int maxCount = 1;
long timeWindow = 0;
List<OperableTrigger> triggers = store.acquireNextTriggers(noLaterThan, maxCount, timeWindow);
Assert.assertEquals(1, triggers.size());
Assert.assertEquals("job" + i, triggers.get(0).getKey().getName());
// Let's remove the trigger now.
store.removeJob(triggers.get(0).getJobKey());
}
}
@Test
public void testAcquireTriggersInBatch() throws Exception {
SchedulerSignaler schedSignaler = new SampleSignaler();
ClassLoadHelper loadHelper = new CascadingClassLoadHelper();
loadHelper.initialize();
JobStore store = createJobStore("testAcquireTriggersInBatch");
store.initialize(loadHelper, schedSignaler);
// Setup: Store jobs and triggers.
long MIN = 60 * 1000L;
Date startTime0 = new Date(System.currentTimeMillis() + MIN); // a min from now.
for (int i=0; i < 10; i++) {
Date startTime = new Date(startTime0.getTime() + i * MIN); // a min apart
JobDetail job = JobBuilder.newJob(MyJob.class).withIdentity("job" + i).build();
SimpleScheduleBuilder schedule = SimpleScheduleBuilder.repeatMinutelyForever(2);
OperableTrigger trigger = (OperableTrigger)TriggerBuilder.newTrigger().withIdentity("job" + i).withSchedule(schedule).forJob(job).startAt(startTime).build();
// Manually trigger the first fire time computation that scheduler would do. Otherwise
// the store.acquireNextTriggers() will not work properly.
Date fireTime = trigger.computeFirstFireTime(null);
Assert.assertEquals(true, fireTime != null);
store.storeJobAndTrigger(job, trigger);
}
// Test acquire batch of triggers at a time
long noLaterThan = startTime0.getTime() + 10 * MIN;
int maxCount = 7;
// time window needs to be big to be able to pick up multiple triggers when they are a minute apart
long timeWindow = 8 * MIN;
List<OperableTrigger> triggers = store.acquireNextTriggers(noLaterThan, maxCount, timeWindow);
Assert.assertEquals(7, triggers.size());
for (int i=0; i < 7; i++) {
Assert.assertEquals("job" + i, triggers.get(i).getKey().getName());
}
}
@Override
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");
}
// Configure transactional connection settings for Quartz.
setDataSource(TX_DATA_SOURCE_PREFIX + getInstanceName());
setDontSetAutoCommitFalse(true);
// Register transactional ConnectionProvider for Quartz.
DBConnectionManager.getInstance().addConnectionProvider(
TX_DATA_SOURCE_PREFIX + getInstanceName(),
new ConnectionProvider() {
@Override
public Connection getConnection() throws SQLException {
// Return a transactional Connection, if any.
return DataSourceUtils.doGetConnection(dataSource);
}
@Override
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);
// Configure non-transactional connection settings for Quartz.
setNonManagedTXDataSource(NON_TX_DATA_SOURCE_PREFIX + getInstanceName());
// Register non-transactional ConnectionProvider for Quartz.
DBConnectionManager.getInstance().addConnectionProvider(
NON_TX_DATA_SOURCE_PREFIX + getInstanceName(),
new ConnectionProvider() {
@Override
public Connection getConnection() throws SQLException {
// Always return a non-transactional Connection.
return nonTxDataSourceToUse.getConnection();
}
@Override
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...
try {
String productName = JdbcUtils.extractDatabaseMetaData(this.dataSource, "getDatabaseProductName");
productName = JdbcUtils.commonDatabaseName(productName);
if (productName != null && productName.toLowerCase().contains("hsql")) {
setUseDBLocks(false);
setLockHandler(new SimpleSemaphore());
}
}
catch (MetaDataAccessException ex) {
logWarnIfNonZero(1, "Could not detect database type. Assuming locks can be taken.");
}
super.initialize(loadHelper, signaler);
}
/**
* Register jobs and triggers (within a transaction, if possible).
*/
protected void registerJobsAndTriggers() throws SchedulerException {
TransactionStatus transactionStatus = null;
if (this.transactionManager != null) {
transactionStatus = this.transactionManager.getTransaction(TransactionDefinition.withDefaults());
}
try {
if (this.jobSchedulingDataLocations != null) {
ClassLoadHelper clh = new ResourceLoaderClassLoadHelper(this.resourceLoader);
clh.initialize();
XMLSchedulingDataProcessor dataProcessor = new XMLSchedulingDataProcessor(clh);
for (String location : this.jobSchedulingDataLocations) {
dataProcessor.processFileAndScheduleJobs(location, getScheduler());
}
}
// Register JobDetails.
if (this.jobDetails != null) {
for (JobDetail jobDetail : this.jobDetails) {
addJobToScheduler(jobDetail);
}
}
else {
// Create empty list for easier checks when registering triggers.
this.jobDetails = new LinkedList<>();
}
// Register Calendars.
if (this.calendars != null) {
for (String calendarName : this.calendars.keySet()) {
Calendar calendar = this.calendars.get(calendarName);
getScheduler().addCalendar(calendarName, calendar, true, true);
}
}
// Register Triggers.
if (this.triggers != null) {
for (Trigger trigger : this.triggers) {
addTriggerToScheduler(trigger);
}
}
}
catch (Throwable ex) {
if (transactionStatus != null) {
try {
this.transactionManager.rollback(transactionStatus);
}
catch (TransactionException tex) {
logger.error("Job registration exception overridden by rollback exception", ex);
throw tex;
}
}
if (ex instanceof SchedulerException) {
throw (SchedulerException) ex;
}
if (ex instanceof Exception) {
throw new SchedulerException("Registration of jobs and triggers failed: " + ex.getMessage(), ex);
}
throw new SchedulerException("Registration of jobs and triggers failed: " + ex.getMessage());
}
if (transactionStatus != null) {
this.transactionManager.commit(transactionStatus);
}
}
@Override
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");
}
// Configure transactional connection settings for Quartz.
setDataSource(TX_DATA_SOURCE_PREFIX + getInstanceName());
setDontSetAutoCommitFalse(true);
// Register transactional ConnectionProvider for Quartz.
DBConnectionManager.getInstance().addConnectionProvider(
TX_DATA_SOURCE_PREFIX + getInstanceName(),
new ConnectionProvider() {
@Override
public Connection getConnection() throws SQLException {
// Return a transactional Connection, if any.
return DataSourceUtils.doGetConnection(dataSource);
}
@Override
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);
// Configure non-transactional connection settings for Quartz.
setNonManagedTXDataSource(NON_TX_DATA_SOURCE_PREFIX + getInstanceName());
// Register non-transactional ConnectionProvider for Quartz.
DBConnectionManager.getInstance().addConnectionProvider(
NON_TX_DATA_SOURCE_PREFIX + getInstanceName(),
new ConnectionProvider() {
@Override
public Connection getConnection() throws SQLException {
// Always return a non-transactional Connection.
return nonTxDataSourceToUse.getConnection();
}
@Override
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...
try {
String productName = JdbcUtils.extractDatabaseMetaData(this.dataSource, "getDatabaseProductName");
productName = JdbcUtils.commonDatabaseName(productName);
if (productName != null && productName.toLowerCase().contains("hsql")) {
setUseDBLocks(false);
setLockHandler(new SimpleSemaphore());
}
}
catch (MetaDataAccessException ex) {
logWarnIfNonZero(1, "Could not detect database type. Assuming locks can be taken.");
}
super.initialize(loadHelper, signaler);
}
/**
* Register jobs and triggers (within a transaction, if possible).
*/
protected void registerJobsAndTriggers() throws SchedulerException {
TransactionStatus transactionStatus = null;
if (this.transactionManager != null) {
transactionStatus = this.transactionManager.getTransaction(new DefaultTransactionDefinition());
}
try {
if (this.jobSchedulingDataLocations != null) {
ClassLoadHelper clh = new ResourceLoaderClassLoadHelper(this.resourceLoader);
clh.initialize();
XMLSchedulingDataProcessor dataProcessor = new XMLSchedulingDataProcessor(clh);
for (String location : this.jobSchedulingDataLocations) {
dataProcessor.processFileAndScheduleJobs(location, getScheduler());
}
}
// Register JobDetails.
if (this.jobDetails != null) {
for (JobDetail jobDetail : this.jobDetails) {
addJobToScheduler(jobDetail);
}
}
else {
// Create empty list for easier checks when registering triggers.
this.jobDetails = new LinkedList<>();
}
// Register Calendars.
if (this.calendars != null) {
for (String calendarName : this.calendars.keySet()) {
Calendar calendar = this.calendars.get(calendarName);
getScheduler().addCalendar(calendarName, calendar, true, true);
}
}
// Register Triggers.
if (this.triggers != null) {
for (Trigger trigger : this.triggers) {
addTriggerToScheduler(trigger);
}
}
}
catch (Throwable ex) {
if (transactionStatus != null) {
try {
this.transactionManager.rollback(transactionStatus);
}
catch (TransactionException tex) {
logger.error("Job registration exception overridden by rollback exception", ex);
throw tex;
}
}
if (ex instanceof SchedulerException) {
throw (SchedulerException) ex;
}
if (ex instanceof Exception) {
throw new SchedulerException("Registration of jobs and triggers failed: " + ex.getMessage(), ex);
}
throw new SchedulerException("Registration of jobs and triggers failed: " + ex.getMessage());
}
if (transactionStatus != null) {
this.transactionManager.commit(transactionStatus);
}
}
@Override
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");
}
// Configure transactional connection settings for Quartz.
setDataSource(TX_DATA_SOURCE_PREFIX + getInstanceName());
setDontSetAutoCommitFalse(true);
// Register transactional ConnectionProvider for Quartz.
DBConnectionManager.getInstance().addConnectionProvider(
TX_DATA_SOURCE_PREFIX + getInstanceName(),
new ConnectionProvider() {
@Override
public Connection getConnection() throws SQLException {
// Return a transactional Connection, if any.
return DataSourceUtils.doGetConnection(dataSource);
}
@Override
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);
// Configure non-transactional connection settings for Quartz.
setNonManagedTXDataSource(NON_TX_DATA_SOURCE_PREFIX + getInstanceName());
// Register non-transactional ConnectionProvider for Quartz.
DBConnectionManager.getInstance().addConnectionProvider(
NON_TX_DATA_SOURCE_PREFIX + getInstanceName(),
new ConnectionProvider() {
@Override
public Connection getConnection() throws SQLException {
// Always return a non-transactional Connection.
return nonTxDataSourceToUse.getConnection();
}
@Override
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...
try {
String productName = JdbcUtils.extractDatabaseMetaData(this.dataSource, "getDatabaseProductName").toString();
productName = JdbcUtils.commonDatabaseName(productName);
if (productName != null && productName.toLowerCase().contains("hsql")) {
setUseDBLocks(false);
setLockHandler(new SimpleSemaphore());
}
}
catch (MetaDataAccessException ex) {
logWarnIfNonZero(1, "Could not detect database type. Assuming locks can be taken.");
}
super.initialize(loadHelper, signaler);
}
/**
* Register jobs and triggers (within a transaction, if possible).
*/
protected void registerJobsAndTriggers() throws SchedulerException {
TransactionStatus transactionStatus = null;
if (this.transactionManager != null) {
transactionStatus = this.transactionManager.getTransaction(new DefaultTransactionDefinition());
}
try {
if (this.jobSchedulingDataLocations != null) {
ClassLoadHelper clh = new ResourceLoaderClassLoadHelper(this.resourceLoader);
clh.initialize();
XMLSchedulingDataProcessor dataProcessor = new XMLSchedulingDataProcessor(clh);
for (String location : this.jobSchedulingDataLocations) {
dataProcessor.processFileAndScheduleJobs(location, getScheduler());
}
}
// Register JobDetails.
if (this.jobDetails != null) {
for (JobDetail jobDetail : this.jobDetails) {
addJobToScheduler(jobDetail);
}
}
else {
// Create empty list for easier checks when registering triggers.
this.jobDetails = new LinkedList<JobDetail>();
}
// Register Calendars.
if (this.calendars != null) {
for (String calendarName : this.calendars.keySet()) {
Calendar calendar = this.calendars.get(calendarName);
getScheduler().addCalendar(calendarName, calendar, true, true);
}
}
// Register Triggers.
if (this.triggers != null) {
for (Trigger trigger : this.triggers) {
addTriggerToScheduler(trigger);
}
}
}
catch (Throwable ex) {
if (transactionStatus != null) {
try {
this.transactionManager.rollback(transactionStatus);
}
catch (TransactionException tex) {
logger.error("Job registration exception overridden by rollback exception", ex);
throw tex;
}
}
if (ex instanceof SchedulerException) {
throw (SchedulerException) ex;
}
if (ex instanceof Exception) {
throw new SchedulerException("Registration of jobs and triggers failed: " + ex.getMessage(), ex);
}
throw new SchedulerException("Registration of jobs and triggers failed: " + ex.getMessage());
}
if (transactionStatus != null) {
this.transactionManager.commit(transactionStatus);
}
}
protected ClassLoadHelper getClassLoadHelper() {
return classLoadHelper;
}