File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Java in General and the fly likes spawning a process Big Moose Saloon
  Search | Java FAQ | Recent Topics
Register / Login


Win a copy of The Mikado Method this week in the Agile and other Processes forum!
JavaRanch » Java Forums » Java » Java in General
Reply Bookmark "spawning a process" Watch "spawning a process" New topic
Author

spawning a process

B Mayes
Ranch Hand

Joined: Apr 28, 2010
Posts: 47

Hi all,

This is really my first attempt to use the Process class in Java. I'm running into some issues and just want to be sure I know why. So to start, here is a very simple BASH script to determine whether or not the input number is even or odd:




Now here is a very simply Java program to invoke that code:




The problem I'm running into is that the program often outputs nothing, but when I run it through my debugger it outputs something every time. I eventually got it to output sometimes when running normally so I think that the issue is really timing. I have the following questions:

1. Is the program outputting nothing because the call to exec() simply spawns the new process but does not wait for it to finish before moving on?
2. In order to always force the program to output something I guess I want to call p.waitFor() ?
3. I see that p.getInputStream() and p.getErrorStream() can block if the size of the output exceeds the buffer size. Thus, it is best to place these calls in separate threads...ok fine. But will calling p.waitFor() ever block (assuming the process being called always terminates)?


I believe the answers to the above questions are yes, yes, and no. I'm just trying to understand things a bit better here. It seems like you cannot rely on the process to be terminated without waitFor() so the best thing to do is:

- Call the process to be run with exec()
- Spawn thread(s) to read stdout/stderr
- call waitFor()

At this point you can be certain that the process completed and that you read all of the output without blocking.

4. The only problem is that I cannot see how to get the output of the command inside of the calling thread. Instead, the output is only available inside of the spawned thread (which we created to prevent blocking). I suppose I could add a public method to append whatever the thread reads to an object in the calling class, but that's a bit cumbersome. Anyone have any other ideas? In the grand scheme of things it may not matter anyway...I'm just going to have my thread throw an exception if it encounters certain strings but I'm just curious. Thanks!
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 32694
    
    4
Don't go anywhere near Runtime.exec() or Process until you have read the classic article by Michael Daconta, When Runtime.exec() won't. It might be over ten years old, but it is still relevant. It is a little easier if you use a ProcessBuilder.

I don't think this is a "beginning" question, so shall move it.
B Mayes
Ranch Hand

Joined: Apr 28, 2010
Posts: 47

Thanks, but I have actually already read that article. When I first ran some google searches I stumbled upon that pretty quickly, but I didn't think that it directly answered any of my questions so I'm simply extrapolating answers from my own experience as well as what that article suggests. Furthermore, using ProcessBuilder doesn't seem to do any better. In fact, I cannot get it to produce any output at all, even if I throw in a call to Thread.sleep() for several seconds.

The new code is as follows:

Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 32694
    
    4
Aren't you supposed to empty the error stream, too? You can do that by merging the two streams in the ProcessBulider class.
B Mayes
Ranch Hand

Joined: Apr 28, 2010
Posts: 47

I didn't know that flushing stderr was required -- I thought it was more of an optional thing. However, after flushing stderr I do see some error output so that might explain why it's not printing anything. I'll play around with things a bit more and report back.
B Mayes
Ranch Hand

Joined: Apr 28, 2010
Posts: 47

D'oh. Silly me I shouldn't have been using the -c option to bash. As soon as I removed that it works perfectly (assuming waitFor() is used). Here is the final code:




So that's cool, but I still haven't ever received confirmation on my first three questions:

1. Is the program outputting nothing because the call to exec() simply spawns the new process but does not wait for it to finish before moving on?
2. In order to always force the program to output something I guess I want to call p.waitFor() ?
3. I see that p.getInputStream() and p.getErrorStream() can block if the size of the output exceeds the buffer size. Thus, it is best to place these calls in separate threads...ok fine. But will calling p.waitFor() ever block (assuming the process being called always terminates)?


Again, I believe the answers are yes, yes, and no but it would be great if someone with more expertise in this area could confirm.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: spawning a process
 
Similar Threads
Runtime.getRuntime().exec(s) spaces in s are trimed
java.io.IOException: Too many open files
Calling a java object fromn a store procedure no idea how to get it to work
Program freezes while executing an external command
wait runtime object finish execution