Search code examples
javaperforceprocessbuilderruntime.exec

Why is Java Runtime.exec command working but ProcessBuilder not able to execute the Perforce client command?


Ok, so to delete a Perfoce Label , the CommandLine command is: p4 label -d mylabel123. Now I want to execute this command using Java. I tried Runtime.exec() and it works like charm. However when I run the same command using ProcessBuilder it doesn't work. Any help appreciated.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException, InterruptedException {
        exec1("p4 label -d mylabel123");
        exec2("p4","label -d mylabel123");
    }
    public static void exec1(String cmd)
            throws java.io.IOException, InterruptedException {
        System.out.println("Executing Runtime.exec()");
        Runtime rt = Runtime.getRuntime();
        Process proc = rt.exec(cmd);

        BufferedReader stdInput = new BufferedReader(new InputStreamReader(
                proc.getInputStream()));
        BufferedReader stdError = new BufferedReader(new InputStreamReader(
                proc.getErrorStream()));

        String s = null;
        while ((s = stdInput.readLine()) != null) {
             System.out.println(s);
        }
        while ((s = stdError.readLine()) != null) {
             System.out.println(s);
        }
        proc.waitFor();
    }
    public static void exec2(String... cmd) throws IOException, InterruptedException{
        System.out.println("\n\nExecuting ProcessBuilder.start()");
        ProcessBuilder pb = new ProcessBuilder();
        pb.inheritIO();
        pb.command(cmd);
        Process process = pb.start();
        process.waitFor();
    }
}

Method exec1() output: Label mylabel123 deleted.

Method exec2() output: Unknown command. Try 'p4 help' for info.


Solution

  • ProcessBuilder wants you to provide the command name and each argument as separate strings. When you (indirectly) perform

    pb.command("p4", "label -d mylabel123");
    

    you are building a process that runs command p4 with a single argument, label -d mylabel123. You want instead to run that command with three separate arguments:

    pb.command("p4", "label", "-d", "mylabel123");
    

    Your clue would have been that the error message in the second case is emitted by the p4 command (it says "Try 'p4 help' for info"). Clearly, then, the problem is with the arguments. I grant you, though, that p4 does create some confusion by calling one of its arguments a "command".