1

I am getting an exe-File, which I have to execute using Java (Version 6) on Windows Server 2008 R2. Now there is s problem I do not really understand. When executing the file with the commandline

"C:\test.exe param1 param2" 

it works correctly, but when I execute the file with

Process proc = Runtime.getRuntime().exec("C:\\test.exe param1 param2");
proc.waitFor();

I can see the test.exe in the windows task manager and it starts running (it creates a log which states that), but then it simply doesn't do anything anymore. The test.exe endlessly runs with 0% and I have to kill the process manually. After doing so the java-program continues and

proc.exitValue()

is "1", therefore java recognizes that I have killed the process. I also tried writing the commandline in a batchfile and executing it with .exec() but it didn't change anything.

What really confuses me, is that it runs perfectly via windows command-line, but does not via .exec(). Does anyone have an idea what might cause such a problem? Or is it more likely that the test.exe is causing the problem?

In best regards

Edit: Wrote down the wrong path in .exec

  • Perhaps http://stackoverflow.com/questions/8595748/java-runtime-exec can help you, seems like a similar question. – Nicky Tellekamp Feb 20 '14 at 09:24
  • Does this program produce output in the console, when you run it there? Or does it read from standard input? – Ingo Feb 20 '14 at 09:27
  • Before going further, use a `ProcessBuilder`! – fge Feb 20 '14 at 09:29
  • Does `test.exe` output a lot of text? It may be that it is blocked trying to write its output, and you don't seem to read from it – fge Feb 20 '14 at 09:30
  • Yes, it does produce a lot of output in the console and in a log.txt. Might it be helpful to reduce the output in the console (I have to contact the programmer of the test.exe-programm to do so, though)? – John Johnson Feb 20 '14 at 09:35
  • I also tried ProcessBuilder, but it didn't really change anything. – John Johnson Feb 20 '14 at 09:36
  • Well then I think your problem is there: the program is stuck trying to output to the console. Read from the process' output, even to "nothing". It should cure your problem/ – fge Feb 20 '14 at 09:38
  • Thanks, that was the problem. I drained the output and now it's working! Thank you all for the help! – John Johnson Feb 20 '14 at 09:47

3 Answers3

2

Since your program procudes a lot of output, my hypothesis is that it is stuck trying to write to the standard output (which is a pipe under Linux, don't know for Windows).

Try this:

final byte[] devnull = new byte[1024];

final ProcessBuilder builder = new ProcessBuilder("C:\\test.exe", "param1", "param2")
    .redirectErrorStream(true);
final Process p = builder.start();

final InputStream stdout = process.getInputStream();

// Purge stdout
while (stdout.read[devnull] != -1);

// Grab the process' exit code here
fge
  • 119,121
  • 33
  • 254
  • 329
2

As fge pointed out in https://stackoverflow.com/a/21903969 , it is important to consume all the output that is produced by the process - not only on Linux, but also on Windows, and not only the standard output, but also the possible errors.

The general pattern for this could look like this:

private static void runCommand(String command) throws IOException
{
    Process process = Runtime.getRuntime().exec(command);
    String errorMessage = 
        new String(toByteArray(process.getErrorStream()));
    String outputMessage = 
        new String(toByteArray(process.getInputStream()));
    int exitValue = 0;
    try
    {
        exitValue = process.waitFor();
    }
    catch (InterruptedException e)
    {
        Thread.currentThread().interrupt();
    }
    System.out.println("Output message: "+outputMessage);
    System.out.println("Error message: "+errorMessage);
    System.out.println("Exit value: "+exitValue);
}

private static byte[] toByteArray(
    InputStream inputStream) throws IOException
{
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    byte buffer[] = new byte[8192];
    while (true)
    {
        int read = inputStream.read(buffer);
        if (read == -1)
        {
            break;
        }
        baos.write(buffer, 0, read);
    }
    return baos.toByteArray();
}
Community
  • 1
  • 1
Marco13
  • 53,703
  • 9
  • 80
  • 159
  • Do we always need to consume the output even if we are not interested? Will the called program freeze otherwise? – JohnyTex Nov 01 '21 at 14:27
  • 1
    @JohnyTex It has been a while since I worked with this, but as far as I remember: Yes, one has to consume the output, because otherwise, the program may appear to "freeze". – Marco13 Nov 05 '21 at 17:54
0
"C:\test.exe param1 param2"

You have a tab in there. Try this:

"C:\\test.exe param1 param2"

If the process produces any output on either stdout or stderr you need to consume it. Otherwise it can block.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • Sorry, I tried breaking the problem down to minimal code and copied the wrong exec()-string for the question. In the java-programm the path is like you wrote it – John Johnson Feb 20 '14 at 09:29