Search code examples
javaquartz-scheduleropenbravo

Scheduled processes running twice simultaneously in Openbravo (using Quartz)


I'm not quite sure whether this is more of an Openbravo issue or more of a Quartz issue, but we have some manual processes that run on schedules via Openbravo ProcessRequest objects (OB v2.50MP24), but it seems that the processes are running twice, at the exact same time. Openbravo extends the Quartz platform for their scheduling. I've tried to resolve this issue on my own by ensuring that my process classes extend this class:

import java.util.List;

import org.openbravo.dal.service.OBDal;
import org.openbravo.model.ad.ui.ProcessRequest;
import org.openbravo.scheduling.ProcessBundle;
import org.openbravo.service.db.DalBaseProcess;

public abstract class RBDDalProcess extends DalBaseProcess {

    @Override
    protected void doExecute(ProcessBundle bundle) throws Exception {
        org.quartz.Scheduler sched = org.openbravo.scheduling.OBScheduler
                .getInstance().getScheduler();
        int runCount = 0;
        synchronized (sched) {
            List<org.quartz.JobExecutionContext> currentlyExecutingJobs = (List<org.quartz.JobExecutionContext>) sched
                    .getCurrentlyExecutingJobs();
            for (org.quartz.JobExecutionContext jec : currentlyExecutingJobs) {
                ProcessRequest processRequest = OBDal.getInstance().get(
                        ProcessRequest.class, jec.getJobDetail().getName());
                if (processRequest == null)
                    continue;
                String processClass = processRequest.getProcess()
                        .getJavaClassName();
                if (bundle.getProcessClass().getCanonicalName()
                        .equals(processClass)) {
                    runCount++;
                }
            }
        }

        if (runCount > 1) {
            System.out.println("Process "
                    + bundle.getProcessClass().getSimpleName()
                    + " is already running. Cancelling.");
            return;
        }

        doRun(bundle);
    }

    protected abstract void doRun(ProcessBundle bundle);

}

This worked fine when I tested by requesting the process to run immediately twice at the same time. One of them cancelled. However, it's not working on the scheduled processes. I have S.o.p's set up to log when the processes start, and looking at the logs shows each line of the output twice, each line one right after the other.

I have a sneaking suspicion that it's because the processes are either running in two completely different threads that don't know about each others' processes, however, I'm not sure how to verify my suspicions or, if I am correct, what to do about it. I've already verified that there is only one instance of each of the ProcessRequest objects stored in the database.

Has anyone else experienced this, know why they might be running twice, or know what I can do to prevent them from simultaneously running?


Solution

  • The most common reasons for a double Job execution are the following:

    EDITED:

    • Your application is deployed in a clustered environment and you have not configured Quartz to run in a cluster environment.
    • Your application is deployed more than once. There are many cases where the application is deployed twice especially in Tomcat server. As a consequence the QuartzInitializerListener is invoked twice and the Jobs are executed twice. In case you use Tomcat server and you are defining contexts explicitly in server.xml, you should turn off automatic application deployment or specify deployIgnore. Both the autoDeploy set to true and the context element existence in server.xml, have as a consequence the twice deployment of the application. Set autoDeploy to false or remove the context element from the server.xml.
    • Your application has been redeployed without unscheduling the current processes.

    I hope this helps you.