I'm facing an annoying issue with Java and I couldn't find a solution.
In my code, I create a subprocess to validate a git commit like this:
void processCommit(String commitId) throws InterruptedException, IOException {
int result = new ProcessBuilder("git", "cat-file", "-e", commitId + "^{commit}").start().waitFor();
if (result != 0) {
throw new IllegalArgumentException("Invalid commit '" + commitId + "'!");
}
// further processing
}
Git will have a 0 exit status if commitId
denotes a valid commit. Otherwise, I know the commit doesn't exist and I throw an appropriate exception.
However, when processing multiple commits and the process is long-running, when I type Ctrl-C into the terminal, the JVM exits by throwing an Invalid commit ...!
exception.
This happens because the SIGINT signal is sent to all child processes of the JVM, not only to the JVM itself. There is probably a race condition:
- the git child process is killed and exits with non-zero status
- before the JVM is killed, the exception is thrown and shuts down the JVM
This happens under Linux, I didn't try on Windows, but my guess is that the behavior would be similar.
Trying to register a shutdown hook didn't help.
While this is a rather cosmetic issue, it really bugs me. How can I gracefully handle this and not report that a commit doesn't exist upon a Ctrl-C, but rather terminate the JVM either with no error message, or at least with an InterruptedException
?
Thanks!