8

I have a ProcessBuilder:

String src = c:/hello/
String dst = c:/hello/2

ProcessBuilder builder = null;
builder = new ProcessBuilder("c:/file/file.exe", "-i", src, "-f", "-l 500", dst);
builder.redirectErrorStream(true);
process = builder.start();

The problem is that as soon as I add "-l 500" I get output:

"l 500" invalid command

Even though I've inputed "-l 500" and not "l 500". If I input "--l 500" I get:

"-l 500" invalid command

Even though -l 500 IS a valid command when running it in command prompt.

If I REMOVE "-l 500" it works again.

Am I using Processbuilder wrong?

EDIT:

Ok it seems as if it works if I do "-l" and "500" as separate entries like this:

new ProcessBuilder("c:/file/file.exe", "-i", src, "-f", "-l", "500", dst);

Why is this so? Can't I have a command with space in it as the same entry?

Omid
  • 823
  • 1
  • 11
  • 31

3 Answers3

5

When you run it at the command prompt you do not wrap the -l 500 in quotes, so they are treated as two different arguments. Enter this at the command line:

file.exe -i some_source -f "-l 500" some_dest

and I expect you will see the same error message as you see when ProcessBuilder is used incorrectly. The file.exe program must be parsing the command line, searching for strings with a leading - character. When it finds the single string "-l 500" it removes the - and does not recognise l 500 as a valid argument.

An argument to ProcessBuilder is analogous to a quoted argument on the command line.

hmjd
  • 120,187
  • 20
  • 207
  • 252
  • @Omid, as you have done as two separate arguments to `ProcessBuilder`?? – hmjd Apr 12 '13 at 19:58
  • @Omid, but `file.exe` does not. `file.exe` expects the argument `-l` to have an associated value, in this case `500`. – hmjd Apr 12 '13 at 20:01
5

I ran into the same issue with the ffmpeg command where I have many paramters with values. I ended up creating an ArrayList and the adding each item to the list one by one. Here is an example:

List<String> command = new ArrayList<>();
command.add(ffmpegCommand);
command.add("-re");
command.add("-i");
command.add(videoFile);
command.add("-vcodec");
command.add("libx264");
command.add("-vcodec");
command.add("libx264");
command.add("-vb");
command.add("500000");
command.add("-g");
command.add("60");
command.add("-vprofile");
command.add("main");
command.add("-acodec");
command.add("aac");
command.add("-ab");
command.add("128000");
command.add("-ar");
command.add("48000");
command.add("-ac");
command.add("2");
command.add("-vbsf");
command.add("h264_mp4toannexb");
command.add("-strict");
command.add("experimental");
command.add("-f");
command.add("mpegts");
command.add("udp://127.0.0.1:10000?pkt_size=1316");

ProcessBuilder pb = new ProcessBuilder(command);
pb.redirectErrorStream(true);
Process process;
try {
  process = pb.start();
  process.waitFor();
  if (process.exitValue() == 0) {
    // success
  } else {
    // failure
  }
} catch (IOException | InterruptedException e) {
  // handle exception
}

Where ffmpegCommand is the full path to the command and videoFile is the full path to the video. This is the only way that I was able to get the command to run successfully.

Ray Hunter
  • 15,137
  • 5
  • 53
  • 51
1

I think the intention of ProcessBuilder was to help but it is not intuitive and it lacks documentation about how it behaves. Anyways what others answered is true, here I am just pasting a small code snipped on how to use it without struggling too much.

String command = String.format("c:/file/file.exe -i %s -f -l 500 %s", src, dst);

ProcessBuilder ps = new ProcessBuilder(command.split(" "));

Yep, write your command as you usually do then use split in order to use the constructor that receives a list of strings.

Marco Medrano
  • 2,530
  • 1
  • 21
  • 35