All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.quartz.QuartzScheduler Maven / Gradle / Ivy

There is a newer version: 2.3.0
Show newest version
/**
 * Copyright 2015 Knowm Inc. (http://knowm.org) and contributors.
 * Copyright 2013-2015 Xeiam LLC (http://xeiam.com) and contributors.
 * Copyright 2001-2011 Terracotta Inc. (http://terracotta.org).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.quartz;

import static org.quartz.builders.SimpleTriggerBuilder.simpleTriggerBuilder;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

import org.quartz.classloading.CascadingClassLoadHelper;
import org.quartz.core.Calendar;
import org.quartz.core.JobExecutionContext;
import org.quartz.core.QuartzSchedulerResources;
import org.quartz.core.QuartzSchedulerThread;
import org.quartz.core.Scheduler;
import org.quartz.core.SchedulerSignaler;
import org.quartz.core.SchedulerSignalerImpl;
import org.quartz.exceptions.JobExecutionException;
import org.quartz.exceptions.JobPersistenceException;
import org.quartz.exceptions.ObjectAlreadyExistsException;
import org.quartz.exceptions.SchedulerException;
import org.quartz.jobs.InterruptableJob;
import org.quartz.jobs.Job;
import org.quartz.jobs.JobDataMap;
import org.quartz.jobs.JobDetail;
import org.quartz.jobs.JobFactory;
import org.quartz.jobs.SimpleJobFactory;
import org.quartz.listeners.JobListener;
import org.quartz.listeners.ListenerManager;
import org.quartz.listeners.ListenerManagerImpl;
import org.quartz.listeners.SchedulerListener;
import org.quartz.listeners.SchedulerListenerSupport;
import org.quartz.listeners.TriggerListener;
import org.quartz.plugins.SchedulerPlugin;
import org.quartz.triggers.OperableTrigger;
import org.quartz.triggers.Trigger;
import org.quartz.triggers.Trigger.CompletedExecutionInstruction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 

* This is the heart of Quartz, an indirect implementation of the {@link org.quartz.core.Scheduler} interface, containing methods to * schedule {@link org.quartz.jobs.Job}s, register {@link org.quartz.listeners.JobListener} instances, etc. *

* * @author James House */ public class QuartzScheduler implements Scheduler { /* * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Data members. * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ private final QuartzSchedulerResources quartzSchedulerResources; private final QuartzSchedulerThread quartzSchedulerThread; private ThreadGroup threadGroup; private final ListenerManager listenerManager = new ListenerManagerImpl(); private final Map internalJobListeners = new HashMap(10); private final Map internalTriggerListeners = new HashMap(10); private final List internalSchedulerListeners = new ArrayList(10); private JobFactory jobFactory = new SimpleJobFactory(); private ExecutingJobsManager jobMgr = null; private ErrorLoggingScheduleListener errLogger = null; private final SchedulerSignaler signaler; private final Random random = new Random(); private boolean signalOnSchedulingChange = true; private volatile boolean closed = false; private volatile boolean shuttingDown = false; private Date initialStart = null; CascadingClassLoadHelper cascadingClassLoadHelper = new CascadingClassLoadHelper(); private final Logger logger = LoggerFactory.getLogger(QuartzScheduler.class); /* * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Constructors. * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /** *

* Create a QuartzScheduler with the given configuration properties. *

* * @see QuartzSchedulerResources */ public QuartzScheduler(QuartzSchedulerResources quartzSchedulerResources) throws SchedulerException { this.quartzSchedulerResources = quartzSchedulerResources; if (quartzSchedulerResources.getJobStore() instanceof JobListener) { addInternalJobListener((JobListener) quartzSchedulerResources.getJobStore()); } this.quartzSchedulerThread = new QuartzSchedulerThread(this, quartzSchedulerResources); jobMgr = new ExecutingJobsManager(); addInternalJobListener(jobMgr); errLogger = new ErrorLoggingScheduleListener(); addInternalSchedulerListener(errLogger); signaler = new SchedulerSignalerImpl(this, this.quartzSchedulerThread); cascadingClassLoadHelper.initialize(); } public void initialize() throws SchedulerException { this.quartzSchedulerThread.start(); } /* * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Interface. * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ public SchedulerSignaler getSchedulerSignaler() { return signaler; } /** *

* Returns the name of the thread group for Quartz's main threads. *

*/ public ThreadGroup getSchedulerThreadGroup() { if (threadGroup == null) { threadGroup = new ThreadGroup("QuartzScheduler"); if (quartzSchedulerResources.getMakeSchedulerThreadDaemon()) { threadGroup.setDaemon(true); } } return threadGroup; } public boolean isSignalOnSchedulingChange() { return signalOnSchedulingChange; } public void setSignalOnSchedulingChange(boolean signalOnSchedulingChange) { this.signalOnSchedulingChange = signalOnSchedulingChange; } // ///////////////////////////////////////////////////////////////////////// // / // / Scheduler State Management Methods // / // ///////////////////////////////////////////////////////////////////////// /** *

* Starts the QuartzScheduler's threads that fire {@link org.quartz.triggers.Trigger}s. *

*

* All {@link org.quartz.triggers.Trigger}s that have misfired will be passed to the appropriate TriggerListener(s). *

*/ @Override public void start() throws SchedulerException { if (shuttingDown || closed) { throw new SchedulerException("The Scheduler cannot be restarted after shutdown() has been called."); } if (initialStart == null) { initialStart = new Date(); quartzSchedulerResources.getJobStore().schedulerStarted(); startPlugins(); } this.quartzSchedulerThread.togglePause(false); logger.info("Scheduler started."); notifySchedulerListenersStarted(); } @Override public void startDelayed(final int seconds) throws SchedulerException { Thread t = new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(seconds * 1000L); } catch (InterruptedException ignore) { } try { start(); } catch (SchedulerException se) { logger.error("Unable to start secheduler after startup delay.", se); } } }); t.start(); } /** *

* Temporarily halts the QuartzScheduler's firing of {@link org.quartz.triggers.Trigger}s. *

*

* The scheduler is not destroyed, and can be re-started at any time. *

*/ @Override public void standby() { this.quartzSchedulerThread.togglePause(true); logger.info("Scheduler paused."); notifySchedulerListenersInStandbyMode(); } /** *

* Reports whether the Scheduler is paused. *

*/ @Override public boolean isInStandbyMode() { return this.quartzSchedulerThread.isPaused(); } public Class getJobStoreClass() { return quartzSchedulerResources.getJobStore().getClass(); } public Class getThreadPoolClass() { return quartzSchedulerResources.getThreadPool().getClass(); } public int getThreadPoolSize() { return quartzSchedulerResources.getThreadPool().getPoolSize(); } /** *

* Halts the QuartzScheduler's firing of {@link org.quartz.triggers.Trigger}s, and cleans up all resources associated with * the QuartzScheduler. *

*

* The scheduler cannot be re-started. *

* * @param waitForJobsToComplete if true the scheduler will not allow this method to return until all currently executing jobs have * completed. */ @Override public void shutdown(boolean waitForJobsToComplete) { if (shuttingDown || closed) { return; } shuttingDown = true; logger.info("Scheduler shutting down..."); standby(); this.quartzSchedulerThread.halt(); notifySchedulerListenersShuttingdown(); if ((quartzSchedulerResources.isInterruptJobsOnShutdown() && !waitForJobsToComplete) || (quartzSchedulerResources.isInterruptJobsOnShutdownWithWait() && waitForJobsToComplete)) { List jobs = getCurrentlyExecutingJobs(); for (JobExecutionContext job : jobs) { if (job.getJobInstance() instanceof InterruptableJob) { try { ((InterruptableJob) job.getJobInstance()).interrupt(); } catch (Throwable e) { // do nothing, this was just a courtesy effort logger.warn("Encountered error when interrupting job {} during shutdown: {}", job.getJobDetail().getName(), e); } } } } quartzSchedulerResources.getThreadPool().shutdown(waitForJobsToComplete); if (waitForJobsToComplete) { while (jobMgr.getNumJobsCurrentlyExecuting() > 0) { try { Thread.sleep(100); } catch (Exception ignore) { } } } // Scheduler thread may have be waiting for the fire time of an acquired // trigger and need time to release the trigger once halted, so make sure // the thread is dead before continuing to shutdown the job store. try { this.quartzSchedulerThread.join(); } catch (InterruptedException ignore) { } closed = true; shutdownPlugins(); notifySchedulerListenersShutdown(); logger.info("Scheduler shutdown complete."); } /** *

* Reports whether the Scheduler has been shutdown. *

*/ @Override public boolean isShutdown() { return closed; } public boolean isShuttingDown() { return shuttingDown; } @Override public boolean isStarted() { return !shuttingDown && !closed && !isInStandbyMode() && initialStart != null; } private void validateState() throws SchedulerException { if (isShutdown()) { throw new SchedulerException("The Scheduler has been shutdown."); } // other conditions to check (?) } /** *

* Return a list of JobExecutionContext objects that represent all currently executing Jobs in this Scheduler instance. *

*

* This method is not cluster aware. That is, it will only return Jobs currently executing in this Scheduler instance, not across the entire * cluster. *

*

* Note that the list returned is an 'instantaneous' snap-shot, and that as soon as it's returned, the true list of executing jobs may be different. *

*/ @Override public List getCurrentlyExecutingJobs() { return jobMgr.getExecutingJobs(); } // ///////////////////////////////////////////////////////////////////////// // / // / Scheduling-related Methods // / // ///////////////////////////////////////////////////////////////////////// /** *

* Add the {@link org.quartz.jobs.Job} identified by the given {@link org.quartz.jobs.JobDetail} to the Scheduler, and * associate the given {@link org.quartz.triggers.Trigger} with it. *

*

* If the given Trigger does not reference any Job, then it will be set to reference the Job passed with it into this method. *

* * @throws SchedulerException if the Job or Trigger cannot be added to the Scheduler, or there is an internal Scheduler error. */ @Override public Date scheduleJob(JobDetail jobDetail, OperableTrigger trigger) throws SchedulerException { validateState(); if (jobDetail == null) { throw new SchedulerException("JobDetail cannot be null"); } if (trigger == null) { throw new SchedulerException("Trigger cannot be null"); } if (jobDetail.getName() == null) { throw new SchedulerException("Job's key cannot be null"); } if (jobDetail.getJobClass() == null) { throw new SchedulerException("Job's class cannot be null"); } OperableTrigger trig = trigger; if (trigger.getJobName() == null) { trig.setJobName(jobDetail.getName()); } else if (!trigger.getJobName().equals(jobDetail.getName())) { throw new SchedulerException("Trigger does not reference given job!"); } trig.validate(); Calendar cal = null; if (trigger.getCalendarName() != null) { cal = quartzSchedulerResources.getJobStore().retrieveCalendar(trigger.getCalendarName()); if (cal == null) { throw new SchedulerException("Calendar not found: " + trigger.getCalendarName()); } } Date ft = trig.computeFirstFireTime(cal); if (ft == null) { throw new SchedulerException("Based on configured schedule, the given trigger will never fire."); } quartzSchedulerResources.getJobStore().storeJobAndTrigger(jobDetail, trig); notifySchedulerListenersJobAdded(jobDetail); notifySchedulerThread(trigger.getNextFireTime().getTime()); notifySchedulerListenersScheduled(trigger); return ft; } /** *

* Schedule the given {@link org.quartz.triggers.Trigger} with the Job identified by the Trigger's settings. *

* * @throws SchedulerException if the indicated Job does not exist, or the Trigger cannot be added to the Scheduler, or there is an internal * Scheduler error. */ @Override public Date scheduleJob(OperableTrigger trigger) throws SchedulerException { validateState(); if (trigger == null) { throw new SchedulerException("Trigger cannot be null"); } OperableTrigger trig = trigger; trig.validate(); Calendar cal = null; if (trigger.getCalendarName() != null) { cal = quartzSchedulerResources.getJobStore().retrieveCalendar(trigger.getCalendarName()); if (cal == null) { throw new SchedulerException("Calendar not found: " + trigger.getCalendarName()); } } Date ft = trig.computeFirstFireTime(cal); if (ft == null) { throw new SchedulerException("Based on configured schedule, the given trigger will never fire."); } quartzSchedulerResources.getJobStore().storeTrigger(trig, false); notifySchedulerThread(trigger.getNextFireTime().getTime()); notifySchedulerListenersScheduled(trigger); return ft; } /** *

* Add the given Job to the Scheduler - with no associated Trigger. The Job will be 'dormant' until it is * scheduled with a Trigger, or Scheduler.triggerJob() is called for it. *

*/ @Override public void addJob(JobDetail jobDetail) throws SchedulerException { validateState(); quartzSchedulerResources.getJobStore().storeJob(jobDetail, true); notifySchedulerThread(0L); notifySchedulerListenersJobAdded(jobDetail); } @Override public void deleteJob(String jobKey) throws SchedulerException { validateState(); List triggers = getTriggersOfJob(jobKey); for (Trigger trigger : triggers) { unscheduleJob(trigger.getName()); } boolean result = quartzSchedulerResources.getJobStore().removeJob(jobKey); if (result) { notifySchedulerThread(0L); notifySchedulerListenersJobDeleted(jobKey); } } @Override public void unscheduleJob(String triggerKey) throws SchedulerException { validateState(); if (quartzSchedulerResources.getJobStore().removeTrigger(triggerKey)) { notifySchedulerThread(0L); notifySchedulerListenersUnscheduled(triggerKey); } } @Override public Date rescheduleJob(String triggerName, OperableTrigger newTrigger) throws SchedulerException { validateState(); if (triggerName == null) { throw new IllegalArgumentException("triggerKey cannot be null"); } if (newTrigger == null) { throw new IllegalArgumentException("newTrigger cannot be null"); } OperableTrigger trig = newTrigger; Trigger oldTrigger = getTrigger(triggerName); if (oldTrigger == null) { return null; } else { trig.setJobName(oldTrigger.getJobName()); } trig.validate(); Calendar cal = null; if (newTrigger.getCalendarName() != null) { cal = quartzSchedulerResources.getJobStore().retrieveCalendar(newTrigger.getCalendarName()); } Date ft = trig.computeFirstFireTime(cal); if (ft == null) { throw new SchedulerException("Based on configured schedule, the given trigger will never fire."); } if (quartzSchedulerResources.getJobStore().replaceTrigger(triggerName, trig)) { notifySchedulerThread(newTrigger.getNextFireTime().getTime()); notifySchedulerListenersUnscheduled(triggerName); notifySchedulerListenersScheduled(newTrigger); } else { return null; } return ft; } private String newTriggerId() { long r = random.nextLong(); if (r < 0) { r = -r; } return "MT_" + Long.toString(r, 30 + (int) (System.currentTimeMillis() % 7)); } /** *

* Trigger the identified {@link org.quartz.jobs.Job} (execute it now) - with a non-volatile trigger. *

*/ @Override public void triggerJob(String jobKey, JobDataMap data) throws SchedulerException { validateState(); OperableTrigger operableTrigger = simpleTriggerBuilder().withIdentity(jobKey + "-trigger").forJob(jobKey).startAt(new Date()).build(); // OperableTrigger operableTrigger = TriggerBuilder.newTriggerBuilder().withIdentity(jobKey + "-trigger").forJob(jobKey) // .withTriggerImplementation(SimpleScheduleBuilder.simpleScheduleBuilderBuilder().instantiate()).startAt(new Date()).build(); // TODO what does this accomplish??? Seems to sets it's next fire time internally operableTrigger.computeFirstFireTime(null); if (data != null) { operableTrigger.setJobDataMap(data); } boolean collision = true; while (collision) { try { quartzSchedulerResources.getJobStore().storeTrigger(operableTrigger, false); collision = false; } catch (ObjectAlreadyExistsException oaee) { operableTrigger.setName(newTriggerId()); } } notifySchedulerThread(operableTrigger.getNextFireTime().getTime()); notifySchedulerListenersScheduled(operableTrigger); } /** *

* Get all {@link Trigger} s that are associated with the identified {@link org.quartz.jobs.JobDetail}. *

*/ @Override public List getTriggersOfJob(String jobKey) throws SchedulerException { validateState(); return quartzSchedulerResources.getJobStore().getTriggersForJob(jobKey); } /** *

* Get the {@link JobDetail} for the Job instance with the given name and group. *

*/ @Override public JobDetail getJobDetail(String jobKey) throws SchedulerException { validateState(); return quartzSchedulerResources.getJobStore().retrieveJob(jobKey); } /** *

* Get the {@link Trigger} instance with the given name and group. *

*/ @Override public Trigger getTrigger(String triggerKey) throws SchedulerException { validateState(); return quartzSchedulerResources.getJobStore().retrieveTrigger(triggerKey); } /** * Clears (deletes!) all scheduling data - all {@link Job}s, {@link Trigger}s {@link Calendar}s. * * @throws SchedulerException */ @Override public ListenerManager getListenerManager() { return listenerManager; } /** *

* Add the given {@link org.quartz.listeners.JobListener} to the Scheduler's internal list. *

*/ private void addInternalJobListener(JobListener jobListener) { if (jobListener.getName() == null || jobListener.getName().length() == 0) { throw new IllegalArgumentException("JobListener name cannot be empty."); } synchronized (internalJobListeners) { internalJobListeners.put(jobListener.getName(), jobListener); } } /** *

* Get a List containing all of the {@link org.quartz.listeners.JobListener}s in the Scheduler's internal list. *

*/ public List getInternalJobListeners() { synchronized (internalJobListeners) { return java.util.Collections.unmodifiableList(new LinkedList(internalJobListeners.values())); } } /** *

* Get a list containing all of the {@link org.quartz.listeners.TriggerListener}s in the Scheduler's internal list. *

*/ public List getInternalTriggerListeners() { synchronized (internalTriggerListeners) { return java.util.Collections.unmodifiableList(new LinkedList(internalTriggerListeners.values())); } } /** *

* Register the given {@link SchedulerListener} with the Scheduler's list of internal listeners. *

*/ public void addInternalSchedulerListener(SchedulerListener schedulerListener) { synchronized (internalSchedulerListeners) { internalSchedulerListeners.add(schedulerListener); } } /** *

* Remove the given {@link SchedulerListener} from the Scheduler's list of internal listeners. *

* * @return true if the identified listener was found in the list, and removed. */ public boolean removeInternalSchedulerListener(SchedulerListener schedulerListener) { synchronized (internalSchedulerListeners) { return internalSchedulerListeners.remove(schedulerListener); } } /** *

* Get a List containing all of the internal {@link SchedulerListener}s registered with the Scheduler. *

*/ public List getInternalSchedulerListeners() { synchronized (internalSchedulerListeners) { return java.util.Collections.unmodifiableList(new ArrayList(internalSchedulerListeners)); } } public void notifyJobStoreJobComplete(OperableTrigger trigger, JobDetail detail, CompletedExecutionInstruction instCode) throws JobPersistenceException { quartzSchedulerResources.getJobStore().triggeredJobComplete(trigger, detail, instCode); } public void notifyJobStoreJobVetoed(OperableTrigger trigger, JobDetail detail, CompletedExecutionInstruction instCode) throws JobPersistenceException { quartzSchedulerResources.getJobStore().triggeredJobComplete(trigger, detail, instCode); } private void notifySchedulerThread(long candidateNewNextFireTime) { if (isSignalOnSchedulingChange()) { signaler.signalSchedulingChange(candidateNewNextFireTime); } } private List buildTriggerListenerList() throws SchedulerException { List allListeners = new LinkedList(); allListeners.addAll(getListenerManager().getTriggerListeners()); allListeners.addAll(getInternalTriggerListeners()); return allListeners; } private List buildJobListenerList() throws SchedulerException { List allListeners = new LinkedList(); allListeners.addAll(getListenerManager().getJobListeners()); allListeners.addAll(getInternalJobListeners()); return allListeners; } private List buildSchedulerListenerList() { List allListeners = new LinkedList(); allListeners.addAll(getListenerManager().getSchedulerListeners()); allListeners.addAll(getInternalSchedulerListeners()); return allListeners; } public boolean notifyTriggerListenersFired(JobExecutionContext jec) throws SchedulerException { boolean vetoedExecution = false; // build a list of all trigger listeners that are to be notified... List triggerListeners = buildTriggerListenerList(); // notify all trigger listeners in the list for (TriggerListener tl : triggerListeners) { try { tl.triggerFired(jec.getTrigger(), jec); if (tl.vetoJobExecution(jec.getTrigger(), jec)) { vetoedExecution = true; } } catch (Exception e) { SchedulerException se = new SchedulerException("TriggerListener '" + tl.getName() + "' threw exception: " + e.getMessage(), e); throw se; } } return vetoedExecution; } public void notifyTriggerListenersMisfired(Trigger trigger) throws SchedulerException { // build a list of all trigger listeners that are to be notified... List triggerListeners = buildTriggerListenerList(); // notify all trigger listeners in the list for (TriggerListener tl : triggerListeners) { try { tl.triggerMisfired(trigger); } catch (Exception e) { SchedulerException se = new SchedulerException("TriggerListener '" + tl.getName() + "' threw exception: " + e.getMessage(), e); throw se; } } } public void notifyTriggerListenersComplete(JobExecutionContext jec, CompletedExecutionInstruction instCode) throws SchedulerException { // build a list of all trigger listeners that are to be notified... List triggerListeners = buildTriggerListenerList(); // notify all trigger listeners in the list for (TriggerListener tl : triggerListeners) { try { tl.triggerComplete(jec.getTrigger(), jec, instCode); } catch (Exception e) { SchedulerException se = new SchedulerException("TriggerListener '" + tl.getName() + "' threw exception: " + e.getMessage(), e); throw se; } } } public void notifyJobListenersToBeExecuted(JobExecutionContext jec) throws SchedulerException { // build a list of all job listeners that are to be notified... List jobListeners = buildJobListenerList(); // notify all job listeners for (JobListener jl : jobListeners) { try { jl.jobToBeExecuted(jec); } catch (Exception e) { SchedulerException se = new SchedulerException("JobListener '" + jl.getName() + "' threw exception: " + e.getMessage(), e); throw se; } } } public void notifyJobListenersWasVetoed(JobExecutionContext jec) throws SchedulerException { // build a list of all job listeners that are to be notified... List jobListeners = buildJobListenerList(); // notify all job listeners for (JobListener jl : jobListeners) { try { jl.jobExecutionVetoed(jec); } catch (Exception e) { SchedulerException se = new SchedulerException("JobListener '" + jl.getName() + "' threw exception: " + e.getMessage(), e); throw se; } } } public void notifyJobListenersWasExecuted(JobExecutionContext jec, JobExecutionException je) throws SchedulerException { // build a list of all job listeners that are to be notified... List jobListeners = buildJobListenerList(); // notify all job listeners for (JobListener jl : jobListeners) { try { jl.jobWasExecuted(jec, je); } catch (Exception e) { SchedulerException se = new SchedulerException("JobListener '" + jl.getName() + "' threw exception: " + e.getMessage(), e); throw se; } } } public void notifySchedulerListenersError(String msg, SchedulerException se) { // build a list of all scheduler listeners that are to be notified... List schedListeners = buildSchedulerListenerList(); // notify all scheduler listeners for (SchedulerListener sl : schedListeners) { try { sl.schedulerError(msg, se); } catch (Exception e) { logger.error("Error while notifying SchedulerListener of error: ", e); logger.error(" Original error (for notification) was: " + msg, se); } } } private void notifySchedulerListenersScheduled(Trigger trigger) { // build a list of all scheduler listeners that are to be notified... List schedListeners = buildSchedulerListenerList(); // notify all scheduler listeners for (SchedulerListener sl : schedListeners) { try { sl.jobScheduled(trigger); } catch (Exception e) { logger.error("Error while notifying SchedulerListener of scheduled job." + " Triger=" + trigger.getName(), e); } } } private void notifySchedulerListenersUnscheduled(String triggerKey) { // build a list of all scheduler listeners that are to be notified... List schedListeners = buildSchedulerListenerList(); // notify all scheduler listeners for (SchedulerListener sl : schedListeners) { try { if (triggerKey == null) { sl.schedulingDataCleared(); } else { sl.jobUnscheduled(triggerKey); } } catch (Exception e) { logger.error("Error while notifying SchedulerListener of unscheduled job." + " Triger=" + (triggerKey == null ? "ALL DATA" : triggerKey), e); } } } public void notifySchedulerListenersFinalized(Trigger trigger) { // build a list of all scheduler listeners that are to be notified... List schedListeners = buildSchedulerListenerList(); // notify all scheduler listeners for (SchedulerListener sl : schedListeners) { try { sl.triggerFinalized(trigger); } catch (Exception e) { logger.error("Error while notifying SchedulerListener of finalized trigger." + " Triger=" + trigger.getName(), e); } } } private void notifySchedulerListenersInStandbyMode() { // build a list of all scheduler listeners that are to be notified... List schedListeners = buildSchedulerListenerList(); // notify all scheduler listeners for (SchedulerListener sl : schedListeners) { try { sl.schedulerInStandbyMode(); } catch (Exception e) { logger.error("Error while notifying SchedulerListener of inStandByMode.", e); } } } private void notifySchedulerListenersStarted() { // build a list of all scheduler listeners that are to be notified... List schedListeners = buildSchedulerListenerList(); // notify all scheduler listeners for (SchedulerListener sl : schedListeners) { try { sl.schedulerStarted(); } catch (Exception e) { logger.error("Error while notifying SchedulerListener of startup.", e); } } } private void notifySchedulerListenersShutdown() { // build a list of all scheduler listeners that are to be notified... List schedListeners = buildSchedulerListenerList(); // notify all scheduler listeners for (SchedulerListener sl : schedListeners) { try { sl.schedulerShutdown(); } catch (Exception e) { logger.error("Error while notifying SchedulerListener of shutdown.", e); } } } private void notifySchedulerListenersShuttingdown() { // build a list of all scheduler listeners that are to be notified... List schedListeners = buildSchedulerListenerList(); // notify all scheduler listeners for (SchedulerListener sl : schedListeners) { try { sl.schedulerShuttingdown(); } catch (Exception e) { logger.error("Error while notifying SchedulerListener of shutdown.", e); } } } private void notifySchedulerListenersJobAdded(JobDetail jobDetail) { // build a list of all scheduler listeners that are to be notified... List schedListeners = buildSchedulerListenerList(); // notify all scheduler listeners for (SchedulerListener sl : schedListeners) { try { sl.jobAdded(jobDetail); } catch (Exception e) { logger.error("Error while notifying SchedulerListener of Job Added.", e); } } } public void notifySchedulerListenersJobDeleted(String jobKey) { // build a list of all scheduler listeners that are to be notified... List schedListeners = buildSchedulerListenerList(); // notify all scheduler listeners for (SchedulerListener sl : schedListeners) { try { sl.jobDeleted(jobKey); } catch (Exception e) { logger.error("Error while notifying SchedulerListener of Job Deleted.", e); } } } @Override public void setJobFactory(JobFactory factory) throws SchedulerException { if(factory == null) { throw new IllegalArgumentException("JobFactory cannot be set to null!"); } logger.info("JobFactory set to: " + factory); this.jobFactory = factory; } public JobFactory getJobFactory() { return jobFactory; } private void shutdownPlugins() { java.util.Iterator itr = quartzSchedulerResources.getSchedulerPlugins().iterator(); while (itr.hasNext()) { SchedulerPlugin plugin = (SchedulerPlugin) itr.next(); plugin.shutdown(); } } private void startPlugins() { java.util.Iterator itr = quartzSchedulerResources.getSchedulerPlugins().iterator(); while (itr.hasNext()) { SchedulerPlugin plugin = (SchedulerPlugin) itr.next(); plugin.start(); } } @Override public CascadingClassLoadHelper getCascadingClassLoadHelper() { return this.cascadingClassLoadHelper; } /** *

* Get the names of all the {@link org.quartz.jobs.Job}s in the matching groups. *

*/ @Override public Set getJobKeys() throws SchedulerException { validateState(); return quartzSchedulerResources.getJobStore().getJobKeys(); } } // /////////////////////////////////////////////////////////////////////////// // // ErrorLogger - Scheduler Listener Class // // /////////////////////////////////////////////////////////////////////////// class ErrorLoggingScheduleListener extends SchedulerListenerSupport { private final Logger logger = LoggerFactory.getLogger(ErrorLoggingScheduleListener.class); /** * Constructor */ ErrorLoggingScheduleListener() { } @Override public void schedulerError(String msg, SchedulerException cause) { logger.error(msg, cause); } } // /////////////////////////////////////////////////////////////////////////// // // ExecutingJobsManager - Job Listener Class // // /////////////////////////////////////////////////////////////////////////// class ExecutingJobsManager implements JobListener { private HashMap executingJobs = new HashMap(); private AtomicInteger numJobsFired = new AtomicInteger(0); ExecutingJobsManager() { } @Override public String getName() { return getClass().getName(); } public int getNumJobsCurrentlyExecuting() { synchronized (executingJobs) { return executingJobs.size(); } } @Override public void jobToBeExecuted(JobExecutionContext context) { numJobsFired.incrementAndGet(); synchronized (executingJobs) { executingJobs.put(((OperableTrigger) context.getTrigger()).getFireInstanceId(), context); } } @Override public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) { synchronized (executingJobs) { executingJobs.remove(((OperableTrigger) context.getTrigger()).getFireInstanceId()); } } public int getNumJobsFired() { return numJobsFired.get(); } public List getExecutingJobs() { synchronized (executingJobs) { return java.util.Collections.unmodifiableList(new ArrayList(executingJobs.values())); } } @Override public void jobExecutionVetoed(JobExecutionContext context) { } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy