Programming for fun and profit

Programming tutorials, problems, solutions. Always with code.

Java external process


How to run external process in Java? In this post we’re going to show how to use ProcessBuilder to work with external processes using new API from Java 7.

The java.lang.ProcessBuilder class allows to start external processes and is available since… forever, but in Java 7 it has been extended with the new ProcessBuilder.Redirect class that specializes in redirection of input, output, and error streams.


In the following example we’re going to start two processes. Both will have error stream redirected to /tmp/process.log. Note that we are using Redirect.appendTo(File), because we want to append to the log instead of rewriting it each time a process starts.

The first process will use cat command to get information about RAM from /proc/meminfo file that is available on Linux machines. We will show how to read its output and display it. The process will end up cleanly.

The second process will run ls to display content of /root directory, to which we don’t have access, so the process will output error message to the log file.


import java.lang.ProcessBuilder.Redirect;

import static;

public class ProcessBuilderExample {

    private File workingDirectory = new File("/tmp");
    private File logFile = new File("/tmp/process.log");

    public static void main(String[] args) throws IOException {
        ProcessBuilderExample example = new ProcessBuilderExample();

    private void start() throws IOException {
        Process memInfo = runCommand("cat", "/proc/meminfo");

        Process ls = runCommand("ls", "/root");
        try {
            // End the process to get "exit value":
        } catch (InterruptedException e) {
        System.out.println("Exit code: " + ls.exitValue());

    private void displayMemoryInfo(Process memInfo)
            throws IOException {
        try (BufferedReader reader = createReader(memInfo)) {
            String line;
            while ((line = reader.readLine()) != null) {

    private BufferedReader createReader(Process process) {
        return new BufferedReader(
                new InputStreamReader(

    private Process runCommand(String... command)
            throws IOException {
        ProcessBuilder builder = new ProcessBuilder(command);

        // Optionally specify working directory:;
        // Append all errors from process to log file:

        String cmdLine = builder.command()
                .collect(joining(" "));

        System.out.println("\nStarting: " + cmdLine);
        Process process = builder.start();
        System.out.printf("'%s' running: %b%n",
                cmdLine, process.isAlive());

        return process;

The code is straightforward. We are using method destroyForcibly() (added in Java 8) to kill the process, to be able to obtain exit code from the process. Else it could throw an exception that the process hasn’t finished yet.

Here’s the output of running the above program:

Starting: cat /proc/meminfo
'cat /proc/meminfo' running: true
MemTotal:        8064024 kB
MemFree:          680004 kB
MemAvailable:    3846556 kB
[...] cut for brevity
DirectMap2M:     8116224 kB

Starting: ls /root
'ls /root' running: true
Exit code: 137

And the contents of our error log:

$> cat /tmp/process.log
ls: cannot open directory /root: Permission denied

Pretty nice. Also remember that you can customize the ProcessBuilder after each call to start() thus execute commands with different arguments – customize the list returned from builder.command().

Share with the World!