javaintermediate

Java ProcessBuilder — Execute System Commands

Run external processes from Java: capture output, handle errors, timeouts, and piped commands.

java
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;

public class ProcessExec {

    // Run command and capture output
    public static String run(String... command) throws Exception {
        ProcessBuilder pb = new ProcessBuilder(command)
            .redirectErrorStream(true);

        Process process = pb.start();

        String output;
        try (var reader = new BufferedReader(
                new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8))) {
            output = reader.lines().collect(java.util.stream.Collectors.joining("\n"));
        }

        boolean finished = process.waitFor(30, TimeUnit.SECONDS);
        if (!finished) {
            process.destroyForcibly();
            throw new RuntimeException("Process timed out");
        }

        if (process.exitValue() != 0) {
            throw new RuntimeException("Exit code " + process.exitValue() + ": " + output);
        }
        return output;
    }

    // Run with environment and working directory
    public static String runInDir(String dir, String... command) throws Exception {
        ProcessBuilder pb = new ProcessBuilder(command)
            .directory(new File(dir))
            .redirectErrorStream(true);

        pb.environment().put("JAVA_HOME", System.getProperty("java.home"));

        Process process = pb.start();
        String output;
        try (var is = process.getInputStream()) {
            output = new String(is.readAllBytes(), StandardCharsets.UTF_8);
        }
        process.waitFor(60, TimeUnit.SECONDS);
        return output;
    }

    // Stream output line by line
    public static void streamOutput(String... command) throws Exception {
        Process process = new ProcessBuilder(command)
            .redirectErrorStream(true)
            .start();

        try (var reader = new BufferedReader(
                new InputStreamReader(process.getInputStream()))) {
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println("[OUT] " + line);
            }
        }
        process.waitFor();
    }

    public static void main(String[] args) throws Exception {
        // Run simple command
        System.out.println(run("java", "--version"));

        // Git status
        System.out.println(runInDir(".", "git", "status", "--short"));

        // Pipe via shell
        System.out.println(run("sh", "-c", "ps aux | head -5"));
    }
}

Use Cases

  • Running system commands from Java applications
  • Build tool integration and automation
  • Health check scripts and system monitoring

Tags

Related Snippets

Similar patterns you can reuse in the same workflow.