Search code examples
javaprocessbuilder

How to know if my ProcessBuilder start() executed the commands successfully


I'm executing a command in java code using ProcessBuilder class. Once the start() is called I'm done with execution. Every time I run this code, I go to output and verify whether the java code has run the command successfully or not. Question is, will I be able to verify this in the code itself?, instead of verifying my output every time. In future I may not be able to view the output, so I want to make sure my commands run successfully or even if it runs into some exception, I should be able to know it from my code.

start() is returning me the Process class object and I hardly find any useful methods available under Process class.

Code:

File file = new File(getClass().getClassLoader().getResource(fileName).getFile());

List<String> list = new ArrayList<String>();
list.add(my_command);

String absPath = file.getAbsolutePath();
list.add(absPath);
ProcessBuilder pb = new ProcessBuilder(list);
Process process = pb.start();
List<String> commandList = pb.command();

Your help is very much appreciated!

Edit:
Tried process.exitValue(); but returning me the below error every time I execute my code. Point to note, my output is generated with out any issue even though I see this exception in my console.

Exception in thread "main" java.lang.IllegalThreadStateException: process has not exited
    at java.lang.ProcessImpl.exitValue(ProcessImpl.java:246)
    at com.rwithjava.caller.RWithJavaCaller.processRWithJavaScript(RWithJavaCaller.java:39)
    at com.rwithjava.caller.RWithJavaCaller.main(RWithJavaCaller.java:51)

Solution

  • If you call pb.waitFor, your program will wait for the process to terminate and returns its result code (that should be zero if everything goes well).

    If that's not enough, you should capture the standard output and standard error streams and check that you get what you're expecting.

    UPDATE

    Example code:

            Process process = pb.start();
            OutputHandler out
                    = new OutputHandler(process.getInputStream(), "UTF-8");
            OutputHandler err
                    = new OutputHandler(process.getErrorStream(), "UTF-8");
            int status = process.waitFor();
            System.out.println("Status: " + status);
            out.join();
            System.out.println("Output:");
            System.out.println(out.getText());
            System.out.println();
            err.join();
            System.out.println("Error:");
            System.out.println(err.getText());
    

    Class OutputHandler:

    class OutputHandler extends Thread {
        private final StringBuilder buf = new StringBuilder();
        private final BufferedReader in;
    
        OutputHandler(InputStream in, String encoding)
                throws UnsupportedEncodingException {
            this.in = new BufferedReader(new InputStreamReader(
                    in, encoding == null ? "UTF-8" : encoding));
            setDaemon(true);
            start();
        }
    
        String getText() {
            synchronized(buf) {
                return buf.toString();
            }
        }
    
        @Override
        public void run() {
            // Reading process output
            try {
                String s = in.readLine();
                while (s != null) {
                    synchronized(buf) {
                        buf.append(s);
                        buf.append('\n');
                    }
                    s = in.readLine();
                }
            } catch (IOException ex) {
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
            } finally {
                try {
                    in.close();
                } catch (IOException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }