Unravel โบ Java concepts โบ Language basics
Processes and shutdown hooks
ProcessBuilder starts another program from Java and lets you read its output; Runtime.addShutdownHook registers code that runs when the JVM shuts down.
Learn these first
At a glance
Calling a colleague in another office: you start them with an instruction, read what they say back, and wait for them to hang up.
- 1new ProcessBuilder("ls", "-l").redirectErrorStream(true).start() starts the program; read process.getInputStream() and finish with process.waitFor(), which returns the exit code
- 2Pass the command as separate strings, never one string with the user input glued in: that is command injection waiting to happen
- 3Runtime.getRuntime().addShutdownHook(new Thread(() -> pool.shutdown())) runs on Ctrl+C, kill (SIGTERM) and normal exit, but not on kill -9 or a crash
- A process whose output you do not read can block forever once its pipe buffer is full
- Shutdown hooks run concurrently with no ordering guarantee and must be short; do not start new threads or block
- On Unix the JDK uses posix_spawn or fork/exec through a helper process and connects pipes to the child; the JVM installs signal handlers for SIGTERM and SIGINT that run the hooks
import java.io.*;public class Shell { static int run(String... command) throws IOException, InterruptedException { Process p = new ProcessBuilder(command).redirectErrorStream(true).start(); try (BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()))) { String line; while ((line = r.readLine()) != null) System.out.println(line); } return p.waitFor(); } static void onExit(Runnable cleanup) { Runtime.getRuntime().addShutdownHook(new Thread(cleanup)); }}- line 4 uses Process, the core of Processes and shutdown hooks
- line 9 uses waitFor, the core of Processes and shutdown hooks
- line 11 uses onExit, the core of Processes and shutdown hooks
Read the full explanation (about 1 min)
ProcessBuilder starts another program from Java and lets you read its output; Runtime.addShutdownHook registers code that runs when the JVM shuts down.
A mental model
Calling a colleague in another office: you start them with an instruction, read what they say back, and wait for them to hang up. A shutdown hook is the note "before you lock the building, switch the lights off".
How it works
new ProcessBuilder("ls", "-l").redirectErrorStream(true).start() starts the program; read process.getInputStream() and finish with process.waitFor(), which returns the exit code.
Pass the command as separate strings, never one string with the user input glued in: that is command injection waiting to happen.
Runtime.getRuntime().addShutdownHook(new Thread(() -> pool.shutdown())) runs on Ctrl+C, kill (SIGTERM) and normal exit, but not on kill -9 or a crash.
Going deeper
A process whose output you do not read can block forever once its pipe buffer is full. Drain stdout and stderr (on separate threads or with redirectErrorStream), or use inheritIO() to forward them.
Shutdown hooks run concurrently with no ordering guarantee and must be short; do not start new threads or block. Frameworks (Spring, Kafka consumers) register their own, so prefer their lifecycle callbacks (@PreDestroy, close()).
Runtime.halt skips hooks and finalisers and ends the JVM immediately.
Under the hood
On Unix the JDK uses posix_spawn or fork/exec through a helper process and connects pipes to the child; the JVM installs signal handlers for SIGTERM and SIGINT that run the hooks.
Common mistakes
- Not reading the output of the child process, causing a hang.
- Building the command from user text.
- Doing heavy or blocking work in a shutdown hook.
How Unravel recognises it
When you paste code, Unravel looks for these signs of processes and shutdown hooks. Spotting them yourself is a good habit when you read unfamiliar code:
- Types:
ProcessBuilderProcess - Method calls:
addShutdownHook()Runtime.getRuntime()waitFor()exec()getRuntime()destroyForcibly()halt()onExit()inheritIO()
Part of a learning path
- The JVM and the environment ยท previous: System, Runtime and environment ยท next: ServiceLoader and plug-ins
Related concepts
Frequently asked questions
What is Processes and shutdown hooks?
ProcessBuilder starts another program from Java and lets you read its output; Runtime.addShutdownHook registers code that runs when the JVM shuts down.
What are the most common mistakes with Processes and shutdown hooks?
Not reading the output of the child process, causing a hang. Building the command from user text. Doing heavy or blocking work in a shutdown hook.
How can I see Processes and shutdown hooks in real code?
Paste your own Java into Unravel and it will point out where processes and shutdown hooks appears, explain how it works at the detail level you choose, and draw the flow of the code around it.