Stopping Quartz job created using MethodInvokingJobDetailFactoryBean

Viewed 165

i create a job running a Spring bean class with this code



  MethodInvokingJobDetailFactoryBeanjobDetail = new MethodInvokingJobDetailFactoryBean();
        Class<?> businessClass = Class.forName(task.getBusinessClassType());
        jobDetail.setTargetObject(applicationContext.getBean(businessClass));
        jobDetail.setTargetMethod(task.getBusinessMethod());
        jobDetail.setName(task.getCode());
        jobDetail.setGroup(task.getGroup().getCode());
        jobDetail.setConcurrent(false);

        Object[] argumentArray = builArgumentArray(task.getBusinessMethodParams());
        jobDetail.setArguments(argumentArray);

        jobDetail.afterPropertiesSet();

        CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(task.getCode() + "_TRIGGER", task.getGroup().getCode() + "_TRIGGER_GROUP")
                      .withSchedule(CronScheduleBuilder.cronSchedule(task.getCronExpression())).build();

        dataSchedulazione = scheduler.scheduleJob((JobDetail) jobDetail.getObject(), trigger);
        scheduler.start();

sometimes the task stop to respond if i remove the trigger and the task from scheduler remain in
List ob = scheduler.getCurrentlyExecutingJobs();

The state of the trigger is NONE but is still in scheduler.getCurrentlyExecutingJobs();

I have tried to implent InterruptableJob in a class that extend MethodInvokingJobDetailFactoryBeanjobDetail

But when i use

scheduler.interrupt(jobKey);

It say that the InterruptableJob is not implemented. I think is because the instance of the class is MethodInvokingJobDetailFactoryBeanjobDetail

`scheduler.scheduleJob((JobDetail) jobDetail.getObject(), trigger);`

this is the code inside the quartz scheduler

`job = jec.getJobInstance();
                if (job instanceof InterruptableJob) {
                    ((InterruptableJob)job).interrupt();
                    interrupted = true;
                } else {
                    throw new UnableToInterruptJobException(
                            "Job " + jobDetail.getKey() +
                            " can not be interrupted, since it does not implement " +                        
                            InterruptableJob.class.getName());
                }
`

Is there another way to kill a single task?

I use Quartz 2.1.7 and java 1.6 and java 1.8

TIA

Andrea

1 Answers

There is no magic way to force JVM to stop execution of some piece of code.

You can implement different ways to interrupt the job. But the most appropriate way is to implement InterruptableJob.

Implementing this interface is not sufficient. You should implement a job in such way that it really reacts on such requests.

Example

Suppose, your job is processing 1 000 000 records in the database or in a file and it take relatively long time, let say 1 hour. Then one possible implementation can be following. In the method "interrupt()" you set some flag (member variable) to "true", let name it isInterruptionRequested. In the main logic part that is processing 1 000 000 records you can regularly, e.g. each 5 seconds or after each let say 100 records check if this flag isInterruptionRequested is set to "true". If set, you exit from the method where you implemented the main logic.

It is important that you don't check the condition too often. Otherwise, depending on the logic, it may happen that checking if the job interruption was requested may take 80-90% of CPU, much more than the actual logic :)

Thus, even when you implement the InterruptableJob interface properly, it doesn't mean that the job will be stopped immediately. It will be just a hint like "I would like to stop this job when it is possible". When it will be stopped (if at all) depends on how you implement it.

Related