Index: src/main/java/org/jboss/resource/adapter/quartz/inflow/QuartzActivationSpec.java =================================================================== --- src/main/java/org/jboss/resource/adapter/quartz/inflow/QuartzActivationSpec.java (revision 103813) +++ src/main/java/org/jboss/resource/adapter/quartz/inflow/QuartzActivationSpec.java (working copy) @@ -56,6 +56,13 @@ private String triggerGroup = "default"; private String cronTrigger; private boolean stateful; + /** + * <0 : immediately shutdown job, 0 : job must completed before shutdown, >0 : time in ms to wait before hard + * shutdown + */ + private int shutdownTimeoutMillis = -1; + + //---- required ActivationSpec methods @@ -134,7 +141,16 @@ { this.cronTrigger = cronTrigger; } + + public int getShutdownTimeoutMillis() { + return shutdownTimeoutMillis; + } + public void setShutdownTimeoutMillis(int shutdownTimeoutMillis) { + this.shutdownTimeoutMillis = shutdownTimeoutMillis; + } + + public String toString() { return "jobName=" + jobName + ",jobGroup="+jobGroup+",triggerName="+triggerName+",triggerGroup="+triggerGroup+",cronTrigger="+cronTrigger; Index: src/main/java/org/jboss/resource/adapter/quartz/inflow/QuartzResourceAdapter.java =================================================================== --- src/main/java/org/jboss/resource/adapter/quartz/inflow/QuartzResourceAdapter.java (revision 103813) +++ src/main/java/org/jboss/resource/adapter/quartz/inflow/QuartzResourceAdapter.java (working copy) @@ -22,6 +22,7 @@ package org.jboss.resource.adapter.quartz.inflow; import org.jboss.logging.Logger; +import org.jboss.resource.adapter.quartz.inflow.QuartzActivationSpec; import org.quartz.*; import org.quartz.impl.StdSchedulerFactory; @@ -86,6 +87,10 @@ throw new RuntimeException(e); } } + + protected String getJobCompletedListenerName(QuartzActivationSpec quartzActivationSpec) { + return quartzActivationSpec.getJobName() + "-listener"; + } public void endpointActivation(MessageEndpointFactory endpointFactory, ActivationSpec spec) @@ -102,9 +107,14 @@ try { + JobListener jobListener = new JobCompletedListener(quartzSpec); + + sched.addJobListener(jobListener); + JobDetail jobDetail = new JobDetail(quartzSpec.getJobName(), quartzSpec.getJobGroup(), clazz, true, false, false); jobDetail.getJobDataMap().setAllowsTransientData(true); jobDetail.getJobDataMap().put("endpointFactory", endpointFactory); + jobDetail.addJobListener(jobListener.getName()); log.debug("adding job: " + quartzSpec); CronTrigger trigger = new CronTrigger(quartzSpec.getTriggerName(), quartzSpec.getTriggerGroup(), quartzSpec.getCronTrigger()); sched.scheduleJob(jobDetail, trigger); @@ -120,14 +130,38 @@ ActivationSpec spec) { QuartzActivationSpec quartzSpec = (QuartzActivationSpec) spec; - try - { - log.debug("****endpointDeactivation: " + quartzSpec); - sched.deleteJob(quartzSpec.getJobName(), quartzSpec.getJobGroup()); - } - catch (SchedulerException e) - { - throw new RuntimeException(e); + try { + try { + JobCompletedListener jobCompletedListener = (JobCompletedListener) sched + .getJobListener(getJobCompletedListenerName(quartzSpec)); + + log.debug("****endpointDeactivation: " + quartzSpec); + + sched.pauseJob(quartzSpec.getJobName(), quartzSpec.getJobGroup()); + + if (quartzSpec.getShutdownTimeoutMillis() > -1) { + int pollingPeriod = quartzSpec.getShutdownTimeoutMillis(); + if (pollingPeriod == 0) { + pollingPeriod = 1000; + } + while (!jobCompletedListener.isJobCompleted()) { + try { + Thread.sleep(pollingPeriod); + if (quartzSpec.getShutdownTimeoutMillis() > 0) + break; + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + } + + sched.deleteJob(quartzSpec.getJobName(), quartzSpec.getJobGroup()); + } finally { + sched.removeJobListener(getJobCompletedListenerName(quartzSpec)); + } + + } catch (SchedulerException e) { + throw new RuntimeException(e); } } @@ -135,5 +169,35 @@ { return new XAResource[0]; } + + private class JobCompletedListener implements JobListener { + + private QuartzActivationSpec quartzActivationSpec; + + private boolean jobCompleted; + + public JobCompletedListener(QuartzActivationSpec quartzActivationSpec) { + this.quartzActivationSpec = quartzActivationSpec; + } + + public String getName() { + return getJobCompletedListenerName(quartzActivationSpec); + } + + public void jobExecutionVetoed(JobExecutionContext arg0) { + } + + public void jobToBeExecuted(JobExecutionContext arg0) { + jobCompleted = false; + } + + public void jobWasExecuted(JobExecutionContext arg0, JobExecutionException arg1) { + jobCompleted = true; + } + + public boolean isJobCompleted() { + return jobCompleted; + } + } }