Normally I use this code to run a bash script and get it's output
ProcessBuilder pb = new ProcessBuilder("/home/myscript");Process p = pb.start();BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));String inputRead;p.waitFor();while((inputRead=stdInput.readLine()) != null){ Helper.log(inputRead);}This works fine but this time the bash script I am using didn't terminate. It's always active and when it detect something it print it. I want to start the script, wait for some time and than check if it detected something. I tried to usep.wait(periode);I tried this code
p.wait(10000);while((inputRead=stdInput.readLine()) != null){ Helper.log(inputRead);}I am not sure if it's the right solution for my problem but anyway I get an error with this code
java.lang.IllegalMonitorStateExceptionMy question is not really about waiting, but how to stop the process after waiting and still be able to get the output.
- Usually, IllegalMonitorStateException means that a thread is trying to wait/notify an object monitor without owning it. Make sure no threads are trying to do that.jordaniac89– jordaniac892016-10-17 14:23:37 +00:00CommentedOct 17, 2016 at 14:23
- I see what you're doing. p.wait() needs to be inside a synchronized statement:docs.oracle.com/javase/tutorial/essential/concurrency/…. If you want the thread to wait, use Thread.sleep().jordaniac89– jordaniac892016-10-17 14:25:58 +00:00CommentedOct 17, 2016 at 14:25
- The script "/home/myscript" write to a file?Lucas Oliveira– Lucas Oliveira2016-10-17 14:27:51 +00:00CommentedOct 17, 2016 at 14:27
- What makes you think that calling
Object.wait()on theProcessobject is a good idea? It's not - that method has a totally different purpose, and has the precondition that you need to hold the monitor on the object (synchronize on it). But that's not the fix for your problem.Erwin Bolwidt– Erwin Bolwidt2016-10-17 14:30:01 +00:00CommentedOct 17, 2016 at 14:30
2 Answers2
In your case using .wait(1000), is totally wrong. That's what the exception also tells you.
Exactly for your usecase there'swaitFor(long timeout, TimeUnit unit):
p.waitFor(10, TimeUnit.SECONDS);3 Comments
Below is the complete example of the solution. A separate thread switches a flag for the main thread to terminate and then output the collected lines:
private static boolean triggerToClose = false; public static void main(String[] args) throws IOException, InterruptedException { ProcessBuilder pb = new ProcessBuilder("/home/myscript"); Process p = pb.start(); java.io.InputStream is = p.getInputStream(); BufferedReader stdInput = new BufferedReader(new InputStreamReader(is)); String inputRead; new Thread(new Runnable() { public void run() { try { Thread.sleep(10000); } catch (InterruptedException e) { } triggerToClose = true; } }).start(); StringBuilder sb = new StringBuilder(); while ((inputRead = stdInput.readLine()) != null) { if (triggerToClose) { p.destroy(); break; } sb.append(inputRead).append('\n'); } System.out.println(sb); }5 Comments
Explore related questions
See similar questions with these tags.

