7

I call a class which is located somewhere in a jar file (using java -classpath path/file.jar classname) within my java code.

This work well but only if the command is well formed. If I make a mistake the getRuntime().exect(command) just doesn't say anything. Bellow I have the working command invocation. I would like to get the error message when the command doesn't work. If I make a mistake in a cmd (windows) I get a proper error and I can fix it. But not within my java application.

I left a 'if(input.ready())' since if I don't the program freezes when the command line is incorrect. This happens when executing 'input.readLine()'.

        // Execute a command with an argument that contains a space
        String[] genKOSCommand = new String[] {
                "java",
                "-classpath",
                Config.XDSI_TEST_KIT_HOME + "/xdsitest/lib/xdsitest.jar;"
                        + Config.XDSI_TEST_KIT_HOME + "/xdsitest/classes",
                "ca.etsmtl.ihe.xdsitest.docsource.SimplePublisher", "-k",
                "C:/Softmedical/Viewer_Test/xdsi-testkit-2.0.4/xdsihome/usr/data/image14.dcm" };

        Process child = Runtime.getRuntime().exec(genKOSCommand);

        BufferedReader input = new BufferedReader(new InputStreamReader(
                child.getInputStream()), 13107200);

        String line = null;

        if (input.ready()) {
            while ((line = input.readLine()) != null) {
                System.out.println(line);
            }

            try {
                child.waitFor();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

Have any advice on how to get an error from the executed command?

Thank you

code-gijoe
  • 6,949
  • 14
  • 67
  • 103

3 Answers3

7

Here's a bit more complete piece of code to print out errors received upon running some command via Process/Runtime:

final String command = "/bin/bash -c cat foo.txt | some.app";
Process p;
    try {
        p = Runtime.getRuntime().exec(command);
    } catch (final IOException e) {
        e.printStackTrace();
    }

    //Wait to get exit value
    try {
        p.waitFor();
        final int exitValue = p.waitFor();
        if (exitValue == 0)
            System.out.println("Successfully executed the command: " + command);
        else {
            System.out.println("Failed to execute the following command: " + command + " due to the following error(s):");
            try (final BufferedReader b = new BufferedReader(new InputStreamReader(p.getErrorStream()))) {
                String line;
                if ((line = b.readLine()) != null)
                    System.out.println(line);
            } catch (final IOException e) {
                e.printStackTrace();
            }                
        }
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
laylaylom
  • 1,754
  • 16
  • 15
7

By using getErrorStream:

BufferedReader errinput = new BufferedReader(new InputStreamReader(
                child.getErrorStream()));

When processing the input from the different streams, it is better to do it in a different thread (since those calls (readLine etc.) are blocking calls.

MByD
  • 135,866
  • 28
  • 264
  • 277
  • It looks like he wants to wait for the process to terminate anyway. – Daniel Lubarov Apr 21 '11 at 19:00
  • I agree, but you can't read from two streams in parallel in the same thread. – MByD Apr 21 '11 at 19:01
  • @glowcoder - because you don't know in which stream you will get the next line. – MByD Apr 21 '11 at 19:11
  • @MByD so if I start threads to read the streams this will only avoid blocking my main process. But readLine will still block the thread, doesn't it? – code-gijoe Apr 21 '11 at 19:29
  • yes, but it will be a separate thread. I saw a good example for that and I'm still looking for it. let you know when I find it. – MByD Apr 21 '11 at 19:31
  • @code-gijoe - see this: http://www.velocityreviews.com/forums/t538651-java-process-hang-when-expectts-error-stream-from-c-application.html and this: http://stackoverflow.com/questions/3343066/reading-streams-from-java-runtime-exec – MByD Apr 21 '11 at 19:38
  • @MByD is there any reason you can't use non-blocking IO to read from both the streams? – corsiKa Apr 21 '11 at 20:46
  • @glowcoder - OP used blocking IO, but I would really like to see such implementation. If you have such an example, please share with me. Thanks. – MByD Apr 21 '11 at 21:05
2

Isn't Process.getErrorStream what you want?

Daniel Lubarov
  • 7,796
  • 1
  • 37
  • 56