14

I remember that we cannot kill the current running Quartz Job but we can interrupt and have a boolean check wherever is necessary whether we need to proceed further with the subsequent operations or not.

Even when we implement the InterruptableJob and call the scheduler.interrupt to interrupt the Job, the current executed job will be still running in the server.

Ex:

  1. A named SQL query has been triggered by the job via Hibernate which takes a long time
  2. A call has been made to a third party server where the third party server takes a long time to respond

http://neopatel.blogspot.in/2011/05/quartz-stop-job.html http://forums.terracotta.org/forums/posts/list/3191.page

Could someone corrects my understanding and explain me how we can kill or stop the "currently" executing Job ?

walen
  • 7,103
  • 2
  • 37
  • 58
Kathir
  • 2,733
  • 12
  • 39
  • 67

3 Answers3

10

you can create new abstract class called JobBase for example that implements IJob interface and insert abstract method: public abstract void ExecuteJob(IJobExecutionContext context);

On JobBase you can implements method Execute like this

public abstract class JobBase : IJob,IInterruptableJob
{
     private Thread currentThread;
     private ILog logger;
     public JobBase(ILog logger)
     {
        this.logger=logger;
     }
        public void Execute(IJobExecutionContext context)
        {

            var thread = new Thread(()=> 
            {
                try
                {
                    this.ExecuteJob(context);
                }
                catch(Exception ex)
                {
                    this.logger.ErrorFormat("Unhandled exception {0}",ex.ToString());

                }
            });

            thread.Start();
            this.currentThread = thread;
            this.currentThread.Join();  
        }
        public abstract void ExecuteJob(IJobExecutionContext context);

        public void Interrupt()
        {   
            currentThread.Abort();
        }
}

Each Job will implements JobExecute method.

  public class TestJob :JobBase
{
    private ILog logger;
    public TeJob(ILog logger):base(logger)
    {
    }

    public override ExecuteJob(IJobExecutionContext context)
    {
    }
}

Assumes that use some factory for creating a Job

For Stopping a Job you will call method scheduler.Interrupt(new JobKey(jobName));

  • This looks like exactly what I need. But whenever I try to interrupt a job I get the exceptoin 'ThreadAbortException'. – Schoof Jun 07 '17 at 09:43
  • @Schoof That is correct. If you take a look at the documentation of `Thread.Abort()` you see that it raises a `ThreadAbortException` https://msdn.microsoft.com/en-us/library/system.threading.thread.abort(v=vs.110).aspx – Jordy van Eijk Sep 27 '17 at 14:00
4

As you told, there is no way to interrupt "brutally" a job in quartz, neither in JAVA.

You can encapsulate your job's logic in a separate Thread and run it with the ExecutorService.

Take a look to this example: https://stackoverflow.com/a/2275596/1517816

Assume your QuartzJob is the Test class and move your business logic in the Task class.

Hope it helps

Community
  • 1
  • 1
poussma
  • 7,033
  • 3
  • 43
  • 68
  • I agree that we cannot brutally kills a job in Quartz neither in JAVA. Also, agree that we can achieve the same via ExecutorService. Out of my curiosity, it raises one more question why Quartz didn't implement ExecutorService so that they can provide us a way to Kill the Job? Or is there is a future plan in the Quartz enhancements. Thanks for your clarification and please let me know your thoughts. – Kathir Oct 27 '12 at 17:09
  • Why it does not implement is probably because it has been designed to provide an alternative to this lack in the jvm. It works with old jvms and if they implement the ExecutorService, quartz will be linked with a recent jvm and force project to migrate – poussma Oct 28 '12 at 14:32
  • Probably they can give an additional or extensive support via a configuration. In that way they can achieve provide the downward compatibility as well as the new...am i missing anything?..Anyway thanks for your time and explanation... – Kathir Oct 28 '12 at 16:04
  • you can monitor the socket and need to terminate the sockets open which got opened during the thread...the sockets might be opened for third party access – Kathir Oct 20 '14 at 11:22
2

I don't know why nobody mentioned this, or maybe this was not available at the time the question was asked.

There is a method called shutdown for a Scheduler instance.

 SchedulerFactory factory = new StdSchedulerFactor();
 Scheduler scheduler = factory.getScheduler();

The above is used to start a job like

  scheduler.start();

Use a flag or something to know when to stop the job from running. Then use

 scheduler.shutdown();

How I implemented my requirement:

 if(flag==true)
{
    scheduler.start();
    scheduler.scheduleJob(jobDetail, simpleTrigger);
}
else if(flag==false)
{
    scheduler.shutdown();
}

Where jobDetail and simpleTrigger are self explanatory.

Hope it helps. :)

Nikhil Kumar
  • 89
  • 1
  • 7