title: ProcessBuilder vs Runtime.exec()
body: <p>I'm trying to create a frontend app in Java to handle batch SVG conversions using Inkscape's command line feature. I'm taking and updating the code from <a href="https://sourceforge.net/projects/conversionsvg/" rel="noreferrer">https://sourceforge.net/projects/conversionsvg/</a>. The way the original developer handled calling Inkscape by <em>Runtime.getRuntime().exec(String)</em>. The issue I'm running into is some inconsistencies between using methodA and methodB. I created a simple java test project to demonstrate the different actions being performed.</p>
  <p><strong>CallerTest.java</strong></p>
  <pre><code>package conversion;
  
  import java.io.IOException;
  
  public class CallerTest {
    
      static String pathToInkscape = &quot;\&quot;C:\\Program Files\\Inkscape\\inkscape.exe\&quot;&quot;;  
      
      public static void main(String[] args) {
        
        ProcessBuilderCaller processBuilder = new ProcessBuilderCaller();
        RuntimeExecCaller runtimeExec = new RuntimeExecCaller();
        
        // methodA() uses one long command line string
        try {
          
          String oneLongString_ProcessBuilder = pathToInkscape + &quot; -f \&quot;C:\\test.svg\&quot; -D -w 100 -h 100 -e \&quot;C:\\ProcessBuilder-methodB.png\&quot;&quot;;
          String oneLongString_RuntimeExec =    pathToInkscape + &quot; -f \&quot;C:\\test.svg\&quot; -D -w 100 -h 100 -e \&quot;C:\\RuntimeExec-methodA.png\&quot;&quot;;
          
  //        processBuilder.methodA(oneLongString_ProcessBuilder);
          runtimeExec.methodA(oneLongString_RuntimeExec);
          
        } catch (IOException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
        
        // methodB() uses an array containing the command and the options to pass to the command
        try {
  
          String[] commandAndOptions_ProcessBuilder = {pathToInkscape, &quot; -f \&quot;C:/test.svg\&quot; -D -w 100 -h 100 -e \&quot;C:\\ProcessBuilder-methodB.png\&quot;&quot;};
          String[] commandAndOptions_RuntimeExec =    {pathToInkscape, &quot; -f \&quot;C:/test.svg\&quot; -D -w 100 -h 100 -e \&quot;C:\\RuntimeExec-methodB.png\&quot;&quot;};
          
          processBuilder.methodB(commandAndOptions_ProcessBuilder);
  //        runtimeExec.methodB(commandAndOptions_RuntimeExec);
          
        } catch (IOException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
      }
  }
  </code></pre>
  <p><strong>RuntimeExecCaller.java</strong></p>
  <pre><code>package conversion;
  
  import java.io.IOException;
  
  public class RuntimeExecCaller {
      Process process;
      
      // use one string
      public void methodA(String oneLongString) throws IOException {
        process = Runtime.getRuntime().exec(oneLongString);
      }
      
      // use the array
      public void methodB(String[] commandAndOptions) throws IOException {
        process = Runtime.getRuntime().exec(commandAndOptions);
      }
  }
  </code></pre>
  <p><strong>ProcessBuilderCaller.java</strong></p>
  <pre><code>package conversion;
  
  import java.io.IOException;
  
  public class ProcessBuilderCaller {
      Process process;
      
      // use one string
      public void methodA(String oneLongString) throws IOException {
        process = new ProcessBuilder(oneLongString).start();
      }
      
      // use the array
      public void methodB(String[] commandAndOptions) throws IOException {
        process = new ProcessBuilder(commandAndOptions).start();
      }
  }
  </code></pre>
  <p><strong>Result</strong></p>
  <p>Both <em>methodA(String)</em> calls work, but when <em>methodB(String[])</em> is called Inkscape is being started and the arguments are being passed incorrectly. After <em>methodB(String[])</em> executes I get an Inkscape error dialog for each saying</p>
  <blockquote>
  <p>Failed to load the requested file  -f C:/test.svg -D -w 100 -h 100 -e C:\RuntimeExec-methodB.png</p>
  <p>Failed to load the requested file  -f C:/test.svg -D -w 100 -h 100 -e C:\ProcessBuilder-methodB.png</p>
  </blockquote>
  <p>and when I click Close on the dialog, Inkscape pops up with a new blank document. So, I guess I have a few questions:</p>
  <p>What is the difference between Runtime.getRuntime().exec(String) and Runtime.getRuntime().exec(String[])?</p>
  <p>JavaDoc says that <em><strong>Runtime.exec(String)</strong></em> calls <em>Runtime.exec(command, null)</em> (which is <em><strong>Runtime.exec(String cmd, String[] envp)</strong></em>) which in turn calls <em>Runtime.exec(cmdarray, envp)</em> (which is <em><strong>Runtime.exec(String[] cmdarray, String[] envp)</strong></em>). So, if <em>Runtime.getRuntime().exec(String)</em> is calling <em>Runtime.exec(String[])</em> anyways, why am I getting different results when using different methods?</p>
  <p>Is something happening behind the scenes where Java sets up the environment differently depending on which method is called?</p>