How to get java getRuntime().exec() to run a command-line program with arguments?

81,152

Solution 1

You are not capturing STDERR, so when errors occur you do not receive them from STDOUT (which you are capturing). Try:

BufferedReader input = new BufferedReader(new InputStreamReader(
               pr.getErrorStream()));

Solution 2

well tesseract is external command so you do not need to use it with cmd. Add tesseract to environment variables. Use direct command as :

String[] commands = {"tesseract", imageFilePath, outputFilePath };

Exist status 1 means Incorrect function. See process exit status

Solution 3

another workaround is give complete installation path of file like /usr/local/Cellar/tesseract/3.02.02/bin/tesseract"

Solution 4

Another workaround without having to recompile and deploy is using the old DOS style paths for e.g C:\Program Files would be C:\Progra~1. Of course this will be helpful only if you are reading the paths from a config file or DB and registry etc.

Share:
81,152
Samuel
Author by

Samuel

I started programming with Parallax Basic working with BoeBots. From there I wrote an efficiency calculator with my friend in Qbasic for a game called O-Game. Recently I have taken courses in C programming and C++ programing. I have a good interest in these because my Dad is an instructor for the company Learning Tree. He flies around the United States teaching companies how to program. I have gotten my associates degree at my local community college. However that degree is only an AA in transfer studies, so its not much. But it has helped me get into the Unversity that I was accepted to. I will be attending to earn a B.S. in Mechanical Engineering. I can't wait to start my courses! Recently I have decided to leave my major of Mechanical Engineering and have switched to Computer Science, so I have really come full circle.

Updated on October 08, 2020

Comments

  • Samuel
    Samuel over 3 years

    I've been trying to write a java program that uses the Runtime.getRuntime().exec() method to use the command-line to run an instance of the program "tesseract".

    Some background, Tesseract is a free open source program that is used to perform OCR (Optical Character Recognition) on pictures. It takes in a picture file and outputs a text document. It is a command-line program that uses this command to run

    (from within the command prompt shell)

    tesseract imageFilePath outFilePath [optional arguments] 
    

    example:

    tesseract "C:\Program Files (x86)\Tesseract-OCR\doc\eurotext.tif" "C:\Users\Dreadnought\Documents\TestingFolder\out"
    

    the first argument calls the tesseract program, the second is the absolute path to the image file and the last argument is the path and name of what the output file should be. Tesseract only requires the name of the output file it does not require the extension.

    Working from the command prompt this works perfect. However, I was wanting to run this from a java program and was running into some errors.

    I found this this code to be very helpful as a starting off point

    public class Main
    {
       public static void main(String args[])
       {
          try
          {
             Runtime rt = Runtime.getRuntime();
             String cmdString = "cmd /c dir";
    
             System.out.println(cmdString);
             Process pr = rt.exec(cmdString);
    
             BufferedReader input = new BufferedReader(new InputStreamReader(
                                                       pr.getInputStream()));
    
             String line = null;
    
             while ((line = input.readLine()) != null)
             {
                System.out.println(line);
             }
    
             int exitVal = pr.waitFor();
             System.out.println("Exited with error code " + exitVal);
    
          }
          catch (Exception e)
          {
             System.out.println(e.toString());
             e.printStackTrace();
          }
       }
    }
    

    It prints out the result of the dir command. However when I modified it like so

    public class Main
    {
       public static void main(String args[])
       {
          try
          {
             Runtime rt = Runtime.getRuntime();
             String imageFilePath = "\"C:\\Program Files (x86)\\Tesseract-OCR\\doc\\eurotext.tif\"";
             String outputFilePath = "\"C:\\Users\\Dreadnought\\Documents\\TestingFolder\\eurotext-example\"";
             String[] commands = {"cmd", "/c", "tesseract", imageFilePath, outputFilePath };
    
             Process pr = rt.exec(commands);
    
             BufferedReader input = new BufferedReader(new InputStreamReader(
                   pr.getInputStream()));
    
             String line = null;
    
             while ((line = input.readLine()) != null)
             {
                System.out.println(line);
             }
    
             int exitVal = pr.waitFor();
             System.out.println("Exited with error code " + exitVal);
          }
          catch (Exception e)
          {
             System.out.println(e.toString());
             e.printStackTrace();
          }
       }
    }
    

    The only thing it outputs is Exited with error code 1. This is the expected output if the Process ended with an error.

    I have even tried passing "cmd /c tesseract \"C:\\Program Files (x86)\\Tesseract-OCR\\doc\\eurotext.tif\" \"C:\\Users\\Dreadnought\\Documents\\TestingFolder\\eurotext-example\"" and I ended up having the same error.

    According to Using Quotes within getRuntime().exec I thought problem was that I was that i had tried to escape the quotes, so that is why I passed in a String array. But I am still getting the Exited with error code 1.

    Is it possible to execute a command-line program with the java Runtime.getRuntime().exec() command?


    EDIT: The problem is still occuring

    I have tried not using "cmd /c" thinking along the same line of reasoning as Evgeniy Dorofeev and Nandkumar Tekale suggested below. However, I get a different sort of error:

    java.io.IOException: Cannot run program "tesseract": CreateProcess error=2, The system cannot find the file specified
    java.io.IOException: Cannot run program "tesseract": CreateProcess error=2, The system  cannot find the file specified
        at java.lang.ProcessBuilder.start(Unknown Source)
        at java.lang.Runtime.exec(Unknown Source)
        at java.lang.Runtime.exec(Unknown Source)
        at Main.main(Main.java:15)
    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>(Unknown Source)
        at java.lang.ProcessImpl.start(Unknown Source)
    ... 4 more
    

    Maybe this gives more information? I am really curious about what is causing this problem. Also the problem is the same whether or not I add the escaped quotations to my arguments.


    EDIT 2: On a whim I provided an absolute path to the tesseract executable and not using the cmd /c worked like a charm. I guess the question is can Runtime.getRuntime().exec() not call environment variables?

    • Nandkumar Tekale
      Nandkumar Tekale over 11 years
      I am not sure but problem might exist with C:\\Program Files (x86) which contain space in path.
    • Samuel
      Samuel over 11 years
      I figured this was the root of the problem which is why I tried to use the quotes, but if those don't work with exec, do you have a suggestion on how I might make this work?
    • Niklas R
      Niklas R over 11 years
      You're passing an array to rt.exec(). Don't put quotes at the beginning and end of your arguments. It is an information for the shell on how to split the arguments apart, but you've already done that.
    • Samuel
      Samuel over 11 years
      If I don't use quotes then how can I get the C:\\Program Files (x86) to stay together? However, I have tried it without the quotes and still doesn't work.
    • Samuel
      Samuel over 11 years
      yes I used it without the cmd /c
    • that other guy
      that other guy almost 10 years
      @Samuel Consider marking this question as answered, and ask your follow-up question about Runtime.exec and environment variables separately.
  • Nandkumar Tekale
    Nandkumar Tekale over 11 years
    did you check running it directly on cmd prompt?