Search code examples
javaprocessexecrunnablescheduledexecutorservice

Avoid scheduled executor from creating several instances of a java process


I created a scheduledTask that executes a call to an external .jar that creates some xml Files, I want this to run every 4 minutes. Every time the external .jar is run a new instance of it is created but I want it to close the existing one and create a new one instead

basically this is my code :

private static void RunInvoiceProcesses(Properties props) {
ScheduledExecutorService executorService =  
Executors.newScheduledThreadPool(executorService.scheduleAtFixedRate(new 
Runnable() {
        @Override
        public void run() {

          Runtime.getRuntime().exec("cmd /c call C:\\creinvoice\\XMLGen\\runxmlgen.bat");


        }
},
15,
240,
TimeUnit.SECONDS);

//the .bat simply calls java -jar myapp.jar

and that is the one that should only be run one instance at a time. every time this runnable is run it calls the bat and a new instance is created by the JVM.

I tried creating an instance of Process outside the executor and doing something like this

Process xmlGeneration = null;

  Runnable() {
        @Override
        public void run() {
    if (xmlGeneration.stillAlive()){xmlGeneration.Destroy();}
         xmlGeneration= Runtime.getRuntime().exec("cmd /c call C:\\creinvoice\\XMLGen\\runxmlgen.bat");


        }
}

but it seems you can only bring final variables into the runnable, so it's not possible. Of course I tried researching all I could about this, but if you can at least point me in the right direction of where to look, I'd really appreciate it!


Solution

  • From Javadoc

    If any execution of this task * takes longer than its period, then subsequent executions * may start late, but will not concurrently execute.

    So you just need to wait for process to finish in your runnable with something like this:

    Process p =  Runtime.getRuntime().exec(...);
    p.waitFor();
    

    In this case your Runnable will wait for underlying process to finish and because of how ScheduledThreadPool works there will be no overlapping executions of your process.