Q:

Recovering stuck quartz jobs

I am facing some quartz jobs which get stuck, for example trying to connect forever. I am using a scheme where the idea is that I can detect these stuck jobs because their triggers have a nextFiretime far in the past. Then, i try to stop these threads by interrupting them. However, the interrupting doesn't seem to work, threads still run without that the nextFiretime gets updated.
How do I interrupt them correctly?
Job code:
protected AtomicReference<Thread> runningThread = null;

/*
 * (non-Javadoc)
 * 
 * @see org.quartz.Job#execute(org.quartz.JobExecutionContext)
 */
@Override
public void execute(JobExecutionContext context)
        throws JobExecutionException
{
    runningThread = new AtomicReference<Thread>();
    try {
        this.runningThread.set(Thread.currentThread());
    } finally { 
        runningThread.set(null); 
    }
}

/*
 * (non-Javadoc)
 * 
 * @see org.quartz.InterruptableJob#interrupt()
 */
@Override
public void interrupt() throws UnableToInterruptJobException
{
    Thread thread = runningThread.getAndSet(null);
    if (thread != null)
        thread.interrupt();
}

The actual jobscheduler code for interrupting:
public int interruptLongRunningJobs(int ms) {
    int jobsInterrupted = 0;
    String jobsInterruptedList = "";

    Date limitInThePast = new Date(System.currentTimeMillis() - ms);

    Scheduler scheduler = this.getJobScheduler();
    // All scheduled jobs
    try {
        for (String groupName : scheduler.getJobGroupNames()) {
            for (JobKey jobKey : scheduler.getJobKeys(GroupMatcher.jobGroupEquals(groupName))) {
                JobDetail jobDetail = scheduler.getJobDetail(jobKey);
                final List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);

                Date nextFireTime = null;
                if (triggers.size() > 0)
                {
                    nextFireTime = triggers.get(0).getNextFireTime();

                    if(nextFireTime != null) {
                        if(nextFireTime.before(limitInThePast)) {
                            String jobString = jobDetail.getKey() + "@" + jobDetail.getJobClass().getSimpleName();
                            logger.debug("JobScheduler::interruptLongRunningJobs interrupting: " + jobString);

                            scheduler.interrupt(jobDetail.getKey());

                            if(!jobsInterruptedList.isEmpty()) {
                                jobsInterruptedList += ", ";
                            }
                            jobsInterruptedList += jobString;
                            ++jobsInterrupted;
                        }
                    }
                }
            }
        }
    } catch (SchedulerException e) {
        logger.debug("JobScheduler::interruptLongRunningJobs failed: " + e.getMessage());
    }

    if(jobsInterrupted>0) {
        logger.debug("JobScheduler::interruptLongRunningJobs interrupted jobs#= " + jobsInterrupted);

        emailSomething("JobScheduler::interruptLongRunningJobs interrupted jobs#= " + jobsInterrupted, 
                "These jobs have been interrupted and canceled because they exceeded the maximum running time as detected by triggers with nextFireTime in the past:\r\n" +  
                jobsInterruptedList
        );
    }
    return jobsInterrupted;
}

A:

The problem was I implemented (copy-pasted) the logic found in public void execute only in some of the subclasses, which were in the focus at that time. I changed the code for public void execute so that it is now easy for all subclasses to use the logic.
@Override
public void execute(JobExecutionContext context)
        throws JobExecutionException
{
    runningThread = new AtomicReference<Thread>();
    try {
        this.runningThread.set(Thread.currentThread());
        reallyExecute(context);
    } finally { 
        runningThread.set(null); 
    }
}

