2

I have looked up on how to run an executable in java via Runtime process builder but it does not work. My code is as follows ...

        String command = "potrace --svg mb-finer-19.pbm -o mb-finer-19.svg";
        try {
            File f = new File("C:\\webstudio\\potrace113win32");
            Process process = Runtime.getRuntime().exec(command, null, f);
            System.out.println("the output stream is " + process.getOutputStream());
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String s;
            while ((s = reader.readLine()) != null) {
                System.out.println("The inout stream is " + s);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

but I get back

java.io.IOException: Cannot run program "potrace" (in directory "C:\webstudio\potrace113win32"): CreateProcess error=2, The system cannot find the file specified
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
    at java.lang.Runtime.exec(Runtime.java:620)
    at java.lang.Runtime.exec(Runtime.java:450)
    at shellcommands.RunPotrace.main(RunPotrace.java:22)
Caused by: java.io.IOException: CreateProcess error=2, The system cannot find the file specified
    at java.lang.ProcessImpl.create(Native Method)
    at java.lang.ProcessImpl.<init>(ProcessImpl.java:386)
    at java.lang.ProcessImpl.start(ProcessImpl.java:137)
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)```

Where am I going wrong with this as it is according to the javadocs ? The executable portace.exe is in the directory along with the image mb-finer-19.pbm Help will be much appreciated.

user3310658
  • 61
  • 1
  • 5

2 Answers2

1

I ran the following and it worked ...

String command = "C:\\webstudio\\potrace113win32\\potrace.exe --svg mb-finer-19.pbm -o mb-finer-19.svg";

Apparently the whole path must be specified if it is not in the system path. Apologies for not first trying this before asking the question.

Amessihel
  • 5,891
  • 3
  • 16
  • 40
user3310658
  • 61
  • 1
  • 5
  • Yes, actually the directory you specified in your `exec()` command was the _working_ directory, not the directory where is the executable. – Amessihel Sep 24 '19 at 16:14
  • I suspect the actual problem was that you were trying to run `potrace` instead of `potrace.exe`. – VGR Sep 24 '19 at 16:41
0

Here is the proper way to run such a process:

    Path imagesDir = Paths.get(
        System.getProperty("user.home"), "Documents");

    Path inputFile = imagesDir.resolve("mb-finer-19.pbm");
    Path outputFile = imagesDir.resolve("mb-finer-19.svg");

    ProcessBuilder builder = new ProcessBuilder(
        "C:\\webstudio\\potrace113win32\\potrace.exe",
        "--svg",
        inputFile.toString(),
        "-o",
        outputFile.toString());

    builder.inheritIO();

    Process process = builder.start();
    int exitCode = process.waitFor();
    if (exitCode != 0) {
        throw new IOException("Got error code " + exitCode
            + " from command " + builder.command());
    }

inheritIO() will cause all of the child process’s output to appear in the output of the Java program which calls it, eliminating the need to consume the process’s InputStream and ErrorStream yourself.

One important benefit of using individual command line arguments instead of a single command string is that file names with spaces in them will be handled correctly. This makes your code more portable, as it will work with any valid file and any valid directory.

VGR
  • 40,506
  • 4
  • 48
  • 63