0

I have an external program Otter that gets as parameter some filename and creates an output file, also specified as parameter. So for example if my input is "proof.in" and I want my output to be placed in the "proof.out" file, I run the following command in the terminal:

otter <proof.in >proof.out

The "proof.in" file must be in the same file as the otter executable.

The problem is that I need this functionality from Java so in my Java code I do the following:

java.lang.Runtime.getRuntime().exec("otter <proof.in >proof.out")

but after this line the whole UI is frozen and nothing happens and no output file is generated.

Could anyone show me where I got it wrong??

Thanks in advance, Tamash

Tamas Ionut
  • 4,240
  • 5
  • 36
  • 59
  • Does your program expect some user input? If so, it will be waiting for the input.. – Rogel Garcia Jan 05 '12 at 23:23
  • possible duplicate of [Executing another java program from our java program](http://stackoverflow.com/questions/7770094/executing-another-java-program-from-our-java-program) –  Jan 05 '12 at 23:29

4 Answers4

5

This is normal: you are attempting to launch a command normally issued by a shell.

Here, <proof.in and >proof.out are taken as literal arguments to the otter executable, and not shell redirections. But seeing the home page for this tool, it will not work: it expects data on stdin, which the redirect normally provides.

You need to launch this command via a shell, and preferably using a process builder:

final ProcessBuilder pb = new ProcessBuilder("/bin/sh", "-c", "otter <proof.in >proof.out");
final Process p = pb.start();

etc etc.

You should also ensure, of course, that the program runs from the correct directory -- fortunately, ProcessBuilder also allows you to do that.

fge
  • 119,121
  • 33
  • 254
  • 329
0

Here is a link to another question with a very detailed answer on how to do this correctly in an async way with threads. This is the only way to not block your main thread and hang your GUI.

private class ProcessResultReader extends Thread
{
    final InputStream is;
    final String type;
    final StringBuilder sb;

    ProcessResultReader(@Nonnull final InputStream is, @Nonnull String type)
    {
        this.is = is;
        this.type = type;
        this.sb = new StringBuilder();
    }

    public void run()
    {
        try
        {
            final InputStreamReader isr = new InputStreamReader(is);
            final BufferedReader br = new BufferedReader(isr);
            String line = null;
            while ((line = br.readLine()) != null)
            {
                this.sb.append(line).append("\n");
            }
        }
        catch (final IOException ioe)
        {
            System.err.println(ioe.getMessage());
            throw new RuntimeException(ioe);
        }
    }

    @Override
    public String toString()
    {
        return this.sb.toString();
    }
}

then you use the above class like so

try
{
    final Process p = Runtime.getRuntime().exec(String.format("cmd /c %s", query));
    final ProcessResultReader stderr = new ProcessResultReader(p.getErrorStream(), "STDERR");
    final ProcessResultReader stdout = new ProcessResultReader(p.getInputStream(), "STDOUT");
    stderr.start();
    stdout.start();
    final int exitValue = p.waitFor();
    if (exitValue == 0)
    {
        System.out.print(stdout.toString());
    }
    else
    {
        System.err.print(stderr.toString());
    }
}
catch (final IOException e)
{
    throw new RuntimeException(e);
}
catch (final InterruptedException e)
{
    throw new RuntimeException(e);
}
Community
  • 1
  • 1
0

If you only want to run the program, do always remember this: Process p=Runtime.getRuntime().exec ("cmd /c dir"); p.waitFor();

Lucifer
  • 29,392
  • 25
  • 90
  • 143
-1

You could see what is happening when you execute your command:

   try {
        Process p=Runtime.getRuntime().exec ("cmd /c dir");

        InputStream is = p.getInputStream();

        BufferedReader br = new BufferedReader (new InputStreamReader (is));

        String aux = br.readLine();

        while (aux!=null) {
            System.out.println (aux);

            aux = br.readLine();
        }
    } 
    catch (Exception e) {
        e.printStackTrace();
    } 

with this code.

jenaiz
  • 547
  • 2
  • 15