Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java application to start a process and get a callback when events occurred in process

My requirement is to start a process from java and register for events callback for the process for eg: like started or killed.

Typical scenario:

In my GUI application, I have a "start process" button with "start/running" status text. I want the status to dynamically change when the process is running or not running. I don't want to continuously check for the list of process and query for my process but a way the callback is triggered when the process is completed.

like image 790
Yeshvant Kumar Bhavnasi Avatar asked Dec 28 '25 18:12

Yeshvant Kumar Bhavnasi


1 Answers

Quick and unrefined solution - Java8 - (just in case, for the unaware: see java.lang.Process and java.lang.ProcessBuilder on how to start one)

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

public class ProcessObserver
implements Runnable {
  protected Consumer<Process> callback;
  protected Process           toExecute;


  public ProcessObserver(
    Consumer<Process> callback, 
    Process toExecute
  ) {
    super();
    this.callback = callback;
    this.toExecute = toExecute;
  }

  @Override
  public void run() {
    while(this.toExecute.isAlive()) {
      try {
        this.toExecute.waitFor(250, TimeUnit.MILLISECONDS);
      } catch (InterruptedException e) {
        this.toExecute.destroyForcibly();
        return; // Honouring the interrupt request,
                // bail out here and don call the callback
      }
    }
    this.callback.accept(this.toExecute);
  }

  static public void main(String[] args) {
    ThreadPoolExecutor pool=new ThreadPoolExecutor(
        4, 1024, // the threads will mostly sleep in waitFors
        3600, TimeUnit.SECONDS, 
        new LinkedBlockingQueue<Runnable>()
    );

    Process longRunningProcess=null; // initialize it properly
    ProcessObserver observer=new ProcessObserver(
      (Process p)->System.out.println("Exit code of: "+p.exitValue()),
      longRunningProcess
    );
    pool.execute(observer);
  }
}

A more refined solution will involve a single thread monitoring multiple processes polling them periodically and invoking the associated callback for those that exited (after all, a 0.2s-1s delay in reporting the exit code for long running processes won't make too much of a difference).

like image 80
Adrian Colomitchi Avatar answered Dec 30 '25 06:12

Adrian Colomitchi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!