You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2009/07/10 17:27:20 UTC
svn commit: r792981 - in
/sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler:
Scheduler.java impl/QuartzScheduler.java
Author: cziegeler
Date: Fri Jul 10 15:27:18 2009
New Revision: 792981
URL: http://svn.apache.org/viewvc?rev=792981&view=rev
Log:
SLING-1040 : Second attempt for cleanly handling lifecycle problems. As deactivate might happen during bind/unbind we should carefully check during bind/unbind. Clarify exception handling.
Modified:
sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/Scheduler.java
sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/QuartzScheduler.java
Modified: sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/Scheduler.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/Scheduler.java?rev=792981&r1=792980&r2=792981&view=diff
==============================================================================
--- sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/Scheduler.java (original)
+++ sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/Scheduler.java Fri Jul 10 15:27:18 2009
@@ -53,6 +53,8 @@
* @param config An optional configuration object - this configuration is only passed to the job the job implements {@link Job}.
* @param schedulingExpression The time specification using a scheduling expression.
* @param canRunConcurrently Whether this job can run even if previous scheduled runs are still running.
+ * @throws IllegalArgumentException If the scheduling expression can't be parsed or if the job has not the correct type.
+ * @throws Exception If the job can't be scheduled.
*/
void addJob(String name, Object job, Map<String, Serializable> config, String schedulingExpression, boolean canRunConcurrently)
throws Exception;
@@ -68,6 +70,8 @@
* @param config An optional configuration object - this configuration is only passed to the job the job implements {@link Job}.
* @param period Every period seconds this job is started.
* @param canRunConcurrently Whether this job can run even if previous scheduled runs are still running.
+ * @throws IllegalArgumentException If the job has not the correct type.
+ * @throws Exception If the job can't be scheduled.
*/
void addPeriodicJob(String name, Object job, Map<String, Serializable> config, long period, boolean canRunConcurrently)
throws Exception;
@@ -77,6 +81,8 @@
*
* @param job The job to execute (either {@link Job} or {@link Runnable}).
* @param config An optional configuration object - this configuration is only passed to the job the job implements {@link Job}.
+ * @throws IllegalArgumentException If the job has not the correct type.
+ * @throws Exception If the job can't be scheduled.
*/
void fireJob(Object job, Map<String, Serializable> config)
throws Exception;
@@ -90,6 +96,8 @@
* @param job The job to execute (either {@link Job} or {@link Runnable}).
* @param config An optional configuration object - this configuration is only passed to the job the job implements {@link Job}.
* @param date The date this job should be run.
+ * @throws IllegalArgumentException If the job has not the correct type.
+ * @throws Exception If the job can't be scheduled.
*/
void fireJobAt(String name, Object job, Map<String, Serializable> config, Date date)
throws Exception;
@@ -98,6 +106,7 @@
* Remove a scheduled job by name.
*
* @param name The name of the job.
+ * @throws NoSuchElementException If the job is not scheduled.
*/
void removeJob(String name)
throws NoSuchElementException;
Modified: sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/QuartzScheduler.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/QuartzScheduler.java?rev=792981&r1=792980&r2=792981&view=diff
==============================================================================
--- sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/QuartzScheduler.java (original)
+++ sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/QuartzScheduler.java Fri Jul 10 15:27:18 2009
@@ -89,7 +89,7 @@
protected final List<Registration> registeredJobs = new ArrayList<Registration>();
/** The component context. */
- protected ComponentContext context;
+ protected volatile ComponentContext context;
/** @scr.reference */
protected ThreadPoolManager threadPoolManager;
@@ -201,21 +201,28 @@
* @param trigger a Trigger
* @param canRunConcurrently whether this job can be run concurrently
*
- * @throws Exception thrown in case of errors
+ * @throws SchedulerException thrown in case of errors
*/
protected void scheduleJob(String name,
final Object job,
final Map<String, Serializable> config,
final Trigger trigger,
final boolean canRunConcurrently)
- throws Exception {
+ throws SchedulerException {
+ // this method is also called from bind - as deactivate might have been
+ // called in the meantime, we just check
+ final org.quartz.Scheduler s = this.scheduler;
+ if ( s == null ) {
+ throw new IllegalStateException("Scheduler is not available anymore.");
+ }
+
// check if the supplied object is valid
this.checkJob(job);
// if there is already a job with the name, remove it first
if ( name != null ) {
try {
- final JobDetail jobdetail = this.scheduler.getJobDetail(name, DEFAULT_QUARTZ_JOB_GROUP);
+ final JobDetail jobdetail = s.getJobDetail(name, DEFAULT_QUARTZ_JOB_GROUP);
if (jobdetail != null) {
this.removeJob(name);
}
@@ -231,7 +238,7 @@
final JobDetail detail = this.createJobDetail(name, jobDataMap);
this.logger.debug("Scheduling job {} with name {} and trigger {}", new Object[] {job, name, trigger});
- this.scheduler.scheduleJob(detail, trigger);
+ s.scheduleJob(detail, trigger);
}
/**
@@ -278,9 +285,9 @@
* Check the job object, either runnable or job is allowed
*/
protected void checkJob(Object job)
- throws Exception {
+ throws IllegalArgumentException {
if (!(job instanceof Runnable) && !(job instanceof Job)) {
- throw new Exception("Job object is neither an instance of " + Runnable.class.getName() + " nor " + Job.class.getName());
+ throw new IllegalArgumentException("Job object is neither an instance of " + Runnable.class.getName() + " nor " + Job.class.getName());
}
}
@@ -292,13 +299,13 @@
Map<String, Serializable> config,
String schedulingExpression,
boolean canRunConcurrently)
- throws Exception {
+ throws SchedulerException {
final CronTrigger cronJobEntry = new CronTrigger(name, DEFAULT_QUARTZ_JOB_GROUP);
try {
cronJobEntry.setCronExpression(schedulingExpression);
} catch (final ParseException pe) {
- throw new Exception(pe.getMessage(), pe);
+ throw new IllegalArgumentException("Error during parsing of cron '" + schedulingExpression + "' : " + pe.getMessage(), pe);
}
this.scheduleJob(name, job, config, cronJobEntry, canRunConcurrently);
}
@@ -307,7 +314,7 @@
* @see org.apache.sling.commons.scheduler.Scheduler#addPeriodicJob(java.lang.String, java.lang.Object, java.util.Map, long, boolean)
*/
public void addPeriodicJob(String name, Object job, Map<String, Serializable> config, long period, boolean canRunConcurrently)
- throws Exception {
+ throws SchedulerException {
final long ms = period * 1000;
if ( name == null ) {
name = PREFIX + UUID.randomUUID().toString();
@@ -323,7 +330,7 @@
* @see org.apache.sling.commons.scheduler.Scheduler#fireJob(java.lang.Object, java.util.Map)
*/
public void fireJob(Object job, Map<String, Serializable> config)
- throws Exception {
+ throws SchedulerException {
this.checkJob(job);
final String name = job.getClass().getName();
final JobDataMap dataMap = this.initDataMap(name, job, config, true);
@@ -337,7 +344,8 @@
/**
* @see org.apache.sling.commons.scheduler.Scheduler#fireJobAt(java.lang.String, java.lang.Object, java.util.Map, java.util.Date)
*/
- public void fireJobAt(String name, Object job, Map<String, Serializable> config, Date date) throws Exception {
+ public void fireJobAt(String name, Object job, Map<String, Serializable> config, Date date)
+ throws SchedulerException {
if ( name == null ) {
name = PREFIX + UUID.randomUUID().toString();
}
@@ -349,11 +357,16 @@
* @see org.apache.sling.commons.scheduler.Scheduler#removeJob(java.lang.String)
*/
public void removeJob(String name) throws NoSuchElementException {
- try {
- this.scheduler.deleteJob(name, DEFAULT_QUARTZ_JOB_GROUP);
- this.logger.debug("Unscheduling job with name {}", name);
- } catch (final SchedulerException se) {
- throw new NoSuchElementException(se.getMessage());
+ // as this method might be called from unbind and during
+ // unbind a deactivate could happen, we check the scheduler first
+ final org.quartz.Scheduler s = this.scheduler;
+ if ( s != null ) {
+ try {
+ this.scheduler.deleteJob(name, DEFAULT_QUARTZ_JOB_GROUP);
+ this.logger.debug("Unscheduling job with name {}", name);
+ } catch (final SchedulerException se) {
+ throw new NoSuchElementException(se.getMessage());
+ }
}
}
@@ -380,23 +393,32 @@
* Register a job or task
* @param type The type (job or task)
* @param ref The service reference
- * @throws Exception If the registration can't be performed
*/
- private void register(String type, ServiceReference ref)
- throws Exception {
- final Object job = this.context.locateService(type, ref);
- if ( ref != null ) {
- this.checkJob(job);
- final String name = getServiceIdentifier(ref);
- final Boolean concurrent = (Boolean)ref.getProperty(Scheduler.PROPERTY_SCHEDULER_CONCURRENT);
- final String expression = (String)ref.getProperty(Scheduler.PROPERTY_SCHEDULER_EXPRESSION);
- if ( expression != null ) {
- this.addJob(name, job, null, expression, (concurrent != null ? concurrent : true));
- } else {
- final Long period = (Long)ref.getProperty(Scheduler.PROPERTY_SCHEDULER_PERIOD);
- if ( period != null ) {
- this.addPeriodicJob(name, job, null, period, (concurrent != null ? concurrent : true));
+ private void register(String type, ServiceReference ref) {
+ // we called from bind, it might be that deactivate has been
+ // called in the meantime
+ final ComponentContext ctx = this.context;
+ if ( ctx != null ) {
+ try {
+ final Object job = ctx.locateService(type, ref);
+ if ( ref != null ) {
+ this.checkJob(job);
+ final String name = getServiceIdentifier(ref);
+ final Boolean concurrent = (Boolean)ref.getProperty(Scheduler.PROPERTY_SCHEDULER_CONCURRENT);
+ final String expression = (String)ref.getProperty(Scheduler.PROPERTY_SCHEDULER_EXPRESSION);
+ if ( expression != null ) {
+ this.addJob(name, job, null, expression, (concurrent != null ? concurrent : true));
+ } else {
+ final Long period = (Long)ref.getProperty(Scheduler.PROPERTY_SCHEDULER_PERIOD);
+ if ( period != null ) {
+ this.addPeriodicJob(name, job, null, period, (concurrent != null ? concurrent : true));
+ }
+ }
}
+ } catch (IllegalStateException e) {
+ // this can happen if deactivate has been called - therefore ignoring
+ } catch (SchedulerException e) {
+ // this can happen if deactivate has been called - therefore ignoring
}
}
}
@@ -406,8 +428,12 @@
* @param ref The service reference.
*/
private void unregister(ServiceReference ref) {
- final String name = getServiceIdentifier(ref);
- this.removeJob(name);
+ try {
+ final String name = getServiceIdentifier(ref);
+ this.removeJob(name);
+ } catch (NoSuchElementException nsee) {
+ // we ignore this
+ }
}
/**
@@ -415,8 +441,7 @@
* @param ref
* @throws Exception
*/
- protected void bindJob(ServiceReference ref)
- throws Exception {
+ protected void bindJob(ServiceReference ref) {
if ( this.scheduler != null ) {
this.register(Registration.JOB, ref);
} else {
@@ -445,8 +470,7 @@
* @param ref
* @throws Exception
*/
- protected void bindTask(ServiceReference ref)
- throws Exception {
+ protected void bindTask(ServiceReference ref) {
if ( this.scheduler != null ) {
this.register(Registration.TASK, ref);
} else {