I am starting an external process in my Java program (on Linux) and I need the ability to send it a SIGTERM signal rather than the SIGKILL that exec.getWatchdog().destroyProcess()
is sending. Is there a way that I can more gracefully stop a unix process started with commons-exec? Or can I get the PID so that I can just run the appropriate kill command myself?

- 889
- 11
- 27
3 Answers
ExecuteWatchdog class has method for killing process.
So, you could just create a watchdog with long timeout and use it to kill process when neccessary, i.e.
executor.getWatchdog().destroyProcess();

- 251
- 1
- 3
- 7
-
2Right, but that sends SIGKILL. Question was how to send a different signal, like SIGTERM to stop it more gracefully. – jtb Sep 19 '12 at 23:38
-
4@audras Actually, you would better to use `new ExecuteWatchdog(ExecuteWatchdog.INFINITE_TIMEOUT)`, not just *long* timeout. – om-nom-nom May 27 '13 at 14:34
Well, Commons Exec relies on the Java Process class, which doesn't expose a PID. It's also what is used to kill the process, so it's not something you can change the behavior of. All nice and encapsulated. Gotta love OO, eh?
If you are simply launching processes in to the background, you can wrap them in a simple shell script that captures the PID for you, and then saves that off to a "known place" that your Java routine knows about. Still kind of messy, and, naturally, it doesn't port to other platforms well.
You can write your own exec function using JNI to capture this information for you as well, but that's likely less friendly.
You could write a platform specific exec launcher daemon in something more system oriented (C, Python, etc.). You send IT messages to launch and stop things, and it handles that process for you. One benefit of this is that you don't have to fork the JVM when you run a new process (which can be quite expensive depending on your JVM size).
You can start the daemon up at the beginning and share a socket or a pipe (both pretty portable). That's actually not a horribly INelegant solution, and it compartmentalizes a lot of system specific behavior (so you can have a completely different process on, say, Windows vs Unix and your Java stays the same, you just need to port your little daemon), without having to run JNI.

- 115,893
- 19
- 128
- 203
-
yes that is a good idea of executing java jar from shell script so you know which one to kill. +1 – ant Mar 02 '11 at 23:30
-
Alright, thanks for the info. It's really strange that they haven't exposed this kind of functionality, I'll just have to work around it in python. Bummer. – jtb Mar 03 '11 at 19:19
Well you could grep it, for ex :
for i in $(ps -ef | grep -i "[Y]ourClassName" | awk '{print $2}'); do kill -9 $i; done
This is in case that you have it running more than 1 time(although it works if you have just one project), notice the [] in grep, that is so the grep doesn't give you its own process pid and -i stands for ignore case, awk is for printing second column only that is PID number.

- 22,634
- 36
- 132
- 182
-
1That is a possibility, but I have multiple invokations of the same script running, and I'd really just rather stop the exact one the external process started, rather than trying to link them together again using the command line. I take it there's no way to get the PID from commons-exec? – jtb Mar 02 '11 at 23:00
-
@jtb Will Hartung has a better idea if ur asking me, just wrap your jar with shell script and you can still use this grep or another one to kill exactly the one you want. – ant Mar 02 '11 at 23:31