You are reading from the Process's InputStream. You should be looking at Process.getErrorStream() or Process.getOutputStream().

https://docs.oracle.com/javase/7/docs/api/java/lang/Process.html

You could also inspect the exitValue to see if the process successfully completed.

Answer from Aravindan R on Stack Overflow
🌐
Coderanch
coderanch.com › t › 725153 › java › Java-process-builder-returning-correct
Java process builder not returning correct (or any) output (Java in General forum at Coderanch)
January 11, 2020 - Bod McLeon wrote:And the output ... none - nothing is written to the console). Most likely an exception is being thrown, and you are simply ignoring it. You should at least print the stack. I would also printout the exit value: Edit: updated code ... I merged your stuff with the following thread. I hope that is okay by you. ... I am trying to call a python script from Java. I am using ProcessBuilder to call the ...
🌐
Leo3418
leo3418.github.io › 2021 › 06 › 20 › java-processbuilder-stdout.html
Properly Handling Process Output When Using Java’s ProcessBuilder - Leo3418's Personal Site
This would only require changing the command used to create the Maven process, which does not alter the expected behavior of java-ebuilder, is OS-independent (unless the -q option of Maven is not supported on some systems), and does not need to be implemented with messy code. This is the approach I used in the patch I submitted to the upstream that fixed this issue. final ProcessBuilder processBuilder = new ProcessBuilder("mvn", "-f", pomFile.toString(), "help:effective-pom", + "-q", "-Doutput=" + outputPath);
🌐
Oracle
docs.oracle.com › javase › 8 › docs › api › java › lang › ProcessBuilder.html
ProcessBuilder (Java Platform SE 8 )
April 21, 2026 - Two ProcessBuilder instances always contain independent process environments, so changes to the returned map will never be reflected in any other ProcessBuilder instance or the values returned by System.getenv. If the system does not support environment variables, an empty map is returned.
Top answer
1 of 1
1

When does ProcessBuilder.start() returns null ...

According to the javadoc, start() does not return null. The javadoc says that it returns a Process and doesn't mention returning null. If there was any circumstance in which start() could return null, then that should be mentioned explicitly in the javadoc in the "Returns:" for the method.

That is the convention that they follow.

I took a look at the source code for ProcessBuilder.start() in Java 11, and by my reading it is actually impossible for the result to be null.

The actual code is in a static Process start() method that is declared in the package private ProcessImpl class. If that method returns at all, it returns an newly created instance of ProcessImpl ... which extends Process.

(There are different versions of ProcessImpl for Unix and Windows platforms. I check both versions.)


So the question is: how come you are getting that NPE?

My guess is that you are misreading the stacktrace (which you haven't shown us!), and the exception is not being thrown in that call to getOutputStream(). Or maybe the compiled code that you are running doesn't match the source code you are looking at.

Either way, we will need you to provide a proper minimal reproducible example if we are to take this any further. A "minrepex" that we can actually compile and run, and that actually throws an NPE for us to diagnose.

(And for what it is worth, I am disinclined to believe that either the javadocs or the Java SE implementation are incorrect.)


Any other way I can call the start() method?

Not that I am aware of. But that is probably a blind alley. The real solution will involve figuring out where that NPE is really coming from.

🌐
OpenJDK
bugs.openjdk.org › browse › JDK-8268939
ProcessBuilder.waitFor() immediately returns with exit code = 1
REGRESSION : Last worked in version 11 STEPS TO FOLLOW TO REPRODUCE THE PROBLEM : Code sample that's failing // command is a List<string> ProcessBuilder pb = new ProcessBuilder(command); pb.redirectErrorStream(true); Process process = null; try { process = pb.start(); BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream())); String line = null; StringBuilder s = new StringBuilder(); while((line = input.readLine()) != null) { s.append(line).append(Constants.NEW_LINE); } int exitCode = process.waitFor(); try { input.close(); } catch (IOException e) { // I ignore
Find elsewhere
🌐
Stack Overflow
stackoverflow.com › questions › 53269305 › processbuilder-not-outputting-the-correct-output
java - ProcessBuilder not outputting the correct output - Stack Overflow
1) Perhaps output is printed to stderr, not stdout. Add builder.redirectErrorStream(true) before calling start(). --- 2) Don't call p.waitFor() until after you've read the output, otherwise your code may deadlock.
🌐
Oracle
docs.oracle.com › en › java › javase › 11 › docs › api › java.base › java › lang › ProcessBuilder.html
ProcessBuilder (Java SE 11 & JDK 11 )
January 20, 2026 - Two ProcessBuilder instances always contain independent process environments, so changes to the returned map will never be reflected in any other ProcessBuilder instance or the values returned by System.getenv. If the system does not support environment variables, an empty map is returned.
Top answer
1 of 2
2

This problem may be related to sub-process's input stream buffers.

You should clear the sub-process's input stream buffers.

These stream buffers got increased within the parent process's memory with time and at some moment your sub-process will stop responding.

There are few options to make sub-process work normally

  1. Read continuously from sub-process's input streams
  2. Redirect sub-process's input streams
  3. Close sub-process's input streams

Closing sub-process's input streams

ProcessBuilder processBuilder = new ProcessBuilder(command);
Process process = processBuilder.start();
InputStream inStream = process.getInputStream();
InputStream errStream = process.getErrorStream();
try {
    inStream.close();
    errStream.close();
} catch (IOException e1) {
}
process.waitFor();

Reading sub-process's input streams

    ProcessBuilder processBuilder = new ProcessBuilder(command);
    Process process = processBuilder.start();
    InputStreamReader tempReader = new InputStreamReader(new BufferedInputStream(p.getInputStream()));
    final BufferedReader reader = new BufferedReader(tempReader);
    InputStreamReader tempErrReader = new InputStreamReader(new BufferedInputStream(p.getErrorStream()));
    final BufferedReader errReader = new BufferedReader(tempErrReader);

    try {
        while ((line = reader.readLine()) != null) {
        }
    } catch (IOException e) {
    }

    try {
        while ((line = errReader.readLine()) != null) {
        }
    } catch (IOException e) {
    }
    process.waitFor();

Redirecting sub-process's input streams

ProcessBuilder processBuilder = new ProcessBuilder(command);
processBuilder.redirectInput();
processBuilder.redirectError();
Process process = processBuilder.start();
process.waitFor();
2 of 2
0

(from comments)

Looks like process hang is due to out/error streams becoming full. You need to consume these streams; possibly via a thread.

Java7 provides another way to redirect output.

Related : http://alvinalexander.com/java/java-exec-processbuilder-process-3

🌐
Oracle
docs.oracle.com › javase › 7 › docs › api › java › lang › ProcessBuilder.html
ProcessBuilder (Java Platform SE 7 )
Two ProcessBuilder instances always contain independent process environments, so changes to the returned map will never be reflected in any other ProcessBuilder instance or the values returned by System.getenv. If the system does not support environment variables, an empty map is returned.
🌐
Baeldung
baeldung.com › home › java › core java › guide to java.lang.processbuilder api
Guide to java.lang.ProcessBuilder API | Baeldung
November 26, 2025 - In the next section, we’re going to take a look at what additions were made to the ProcessBuilder API in Java 9. When working with the ProcessBuilder API, we may need to pass arguments that contain spaces, such as strings with multiple words or file paths under directories. If not handled correctly, these arguments can cause the command to fail or be misinterpreted by the operating system.
Top answer
1 of 1
1

The error message says that Java does not find an executable called zip in the current directory or on the path, which can be seen with:

String systemPath = System.getenv("PATH");
System.out.println("PATH="+systemPath);

Fix your launcher to include the full path to "zip" or fix the PATH used for your Java VM to include a directory that contains zip.

myListOfString.add("/the/path/to/zip");

or something like this (depending on your shell / terminal)

export PATH=/the/path/to:$PATH

As @Abra suggests, there are better ways to ZIP inside Java without relying on ProcessBuilder such as:

public static void zip(Path dir, Path zip) throws IOException
{
    Map<String, String> env = Map.of("create", "true");
    try (FileSystem fs = FileSystems.newFileSystem(zip, env))
    {
        // This predicate processed the action because it makes use of BasicFileAttributes
        // Rather than process a forEach stream which has to call Files.isDirectory(path)
        BiPredicate<Path, BasicFileAttributes> foreach = (p,a) -> {
            copy(p,a, fs.getPath("/"+dir.relativize(p)));
            return false;
        };

        Files.find(dir, Integer.MAX_VALUE, foreach).count();
    }
    System.out.println("ZIPPED "+dir +" to "+zip);
}
private static void copy(Path from, BasicFileAttributes a, Path target)
{
    System.out.println("Copy "+(a.isDirectory() ? "DIR " : "FILE")+" => "+target);
    try
    {
        if (a.isDirectory())
            Files.createDirectories(target);
        else if (a.isRegularFile())
            Files.copy(from, target, StandardCopyOption.REPLACE_EXISTING);
    }
    catch (IOException e)
    {
        throw new UncheckedIOException(e);
    }
}