ZT Process Killer
Continuous Integration
Quick Overview
The project was created in ZeroTurnaround to have a stable base functionality of stopping running processes from Java. It can stop processes started from Java (e.g. with zt-exec) as well as existing system processes based on their process ID (PID).
Installation
The project artifacts are available in Maven Central Repository.
To include it in your maven project then you have to specify the dependency.
...
<dependency>
<groupId>org.zeroturnaround</groupId>
<artifactId>zt-process-killer</artifactId>
<version>1.10</version>
</dependency>
...
Motivation
In Java Process.destroy() is ambiguous. On Windows it terminates processes forcibly. On UNIX it terminates them gracefully. As invoking kill commands from Java is errorprone it should have an advised API and good test coverage.
We had the following functional requirements:
- check whether a process is alive
- wait until a process has finished
- terminate a process gracefully (by default disabled on Windows as it's unsupported - WindowsProcess)
- terminate a process forcibly
- get the process ID (PID) of running JVM
and these non-functional requirements:
- abstraction of processes regardless they are started from Java or not (use process ID) - SystemProcess
- have process API similar to java.lang.Process
- all waiting methods should have one version with timeout and another without it
- stopping operation should be idempotent - if a process was already finished it is a success
- separate generic behavior from process implementation - ProcessUtil
- support alternative implementations for stopping same process - OrProcess
- simple factory for creating process instances - Processes
- invoke Java 8 java.lang.Process methods if possible - Java8Process
Limitations:
- As the process abstraction is also used for already running processes it can't access their streams or exit value.
- The scope of this project is stopping single processes. However WindowsProcess has method setIncludeChildren to also stop child processes in case the root process is still running.
Examples
- Get my PID
int pid = PidUtil.getMyPid();
System.out.println("My PID is " + pid);
- Check whether a PID is alive
int pid = Integer.parseInt(FileUtils.readFileToString(new File("pidfile")));
PidProcess process = Processes.newPidProcess(pid);
boolean isAlive = process.isAlive();
System.out.println("PID " + pid + " is alive: " + isAlive);
- Check whether a process is alive
Process p = new ProcessBuilder("my-application").start();
JavaProcess process = Processes.newJavaProcess(p);
boolean isAlive = process.isAlive();
System.out.println("Process " + process + " is alive: " + isAlive);
- Wait until an already started process has finished
int pid = Integer.parseInt(FileUtils.readFileToString(new File("pidfile")));
PidProcess process = Processes.newPidProcess(pid);
boolean finished = process.waitFor(10, TimeUnit.MINUTES);
System.out.println("PID " + pid + " finished on time: " + finished);
- Wait until the started process has finished
Process p = new ProcessBuilder("my-application").start();
JavaProcess process = Processes.newJavaProcess(p);
boolean finished = process.waitFor(10, TimeUnit.MINUTES);
System.out.println("Process " + process + " finished on time: " + finished);
- Stop an already started process, timeout of 30 seconds for graceful stop, timeout of 10 seconds for forceful stop
int pid = Integer.parseInt(FileUtils.readFileToString(new File("pidfile")));
PidProcess process = Processes.newPidProcess(pid);
ProcessUtil.destroyGracefullyOrForcefullyAndWait(process, 30, TimeUnit.SECONDS, 10, TimeUnit.SECONDS);
- Stop the started process, timeout of 30 seconds for graceful stop, timeout of 10 seconds for forceful stop
Process p = new ProcessBuilder("my-application").start();
SystemProcess process = Processes.newStandardProcess(p);
ProcessUtil.destroyGracefullyOrForcefullyAndWait(process, 30, TimeUnit.SECONDS, 10, TimeUnit.SECONDS);