Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 767
Samuel Avatar asked Nov 20 '12 05:11

Samuel


People also ask

What does Runtime getRuntime () exec () do?

Runtime features a static method called getRuntime() , which retrieves the current Java Runtime Environment. That is the only way to obtain a reference to the Runtime object. With that reference, you can run external programs by invoking the Runtime class's exec() method.

What is Runtime getRuntime ()?

getRuntime. public static Runtime getRuntime() Returns the runtime object associated with the current Java application. Most of the methods of class Runtime are instance methods and must be invoked with respect to the current runtime object.

How do you run a shell script in Java?

With this tutorial we'll illustrate the two ways of executing a shell command from within Java code. The first is to use the Runtime class and call its exec method. The second and more customizable way, will be to create and use a ProcessBuilder instance.


2 Answers

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()));
like image 105
hkd93 Avatar answered Sep 22 '22 21:09

hkd93


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

like image 44
Nandkumar Tekale Avatar answered Sep 23 '22 21:09

Nandkumar Tekale