Using Process object

T

Tim Slattery

I'm writing a Java object that runs a Perl script. I use the Process
object to do this. I set everything up, then call the waitFor() method
- and the Java program hangs. I've put debug logging into both the
Perl script and the java program, so I see that the Perl script runs
all the way through, but the last thing the Java program does is
execute waitFor().
 
T

Tom Anderson

I'm writing a Java object that runs a Perl script. I use the Process
object to do this. I set everything up, then call the waitFor() method -
and the Java program hangs. I've put debug logging into both the Perl
script and the java program, so I see that the Perl script runs all the
way through, but the last thing the Java program does is execute
waitFor().

The most common bug around this sort of thing is that the parent process
doesn't read all the child's output from its standard output stream. The
buffer for the pipe between the two fills up, and the child then gets
blocked waiting for it to empty so that it can finish writing, which of
course never happens because the parent is waiting for the child to
terminate. Deadlock ensues.

However, from what you say, it sounds like the Perl script is terminating.
Is that definitely the case? Could it be that the script finishes running,
but the buffer is never drained, so the Perl interpreter doesn't exit? Can
you see the interpreter in a process listing after the script seems to
have finished? If you drain all the output from the child, does that help?

If not, i'm not sure what to suggest. I note that the javadoc for Process
does mention that:

The methods that create processes may not work well for special processes
on certain native platforms, such as native windowing processes, daemon
processes, Win16/DOS processes on Microsoft Windows, or shell scripts.

So if a Perl script is like a shell script (and it is - albeit a hideously
deformed shell script with mutant superpowers), there could be trouble.
That sounds more like arse-covering than a genuine warning, though.

tom
 
R

Roedy Green

I'm writing a Java object that runs a Perl script. I use the Process
object to do this. I set everything up, then call the waitFor() method
- and the Java program hangs. I've put debug logging into both the
Perl script and the java program, so I see that the Perl script runs
all the way through, but the last thing the Java program does is
execute waitFor().

see http://mindprod.com/jgloss/exec.html
for the usual pitfalls. If your script is eating or producing chars
you need threads to deal with them.
--
Roedy Green Canadian Mind Products
http://mindprod.com
A short order cook is a master of multitasking. Every movement is
optimised from years of practice. Yet when a computer executes a
multitasking program, it approaches the task as if for the first time.
 
T

Tim Slattery

Tom Anderson said:
The most common bug around this sort of thing is that the parent process
doesn't read all the child's output from its standard output stream. The
buffer for the pipe between the two fills up, and the child then gets
blocked waiting for it to empty so that it can finish writing, which of
course never happens because the parent is waiting for the child to
terminate. Deadlock ensues.

However, from what you say, it sounds like the Perl script is terminating.
Is that definitely the case? Could it be that the script finishes running,
but the buffer is never drained, so the Perl interpreter doesn't exit?

I guess it was something like that. Putting the processes to read
STDOUT and STDERR in separate threads did the trick. But the Perl
script definitely finished, so ?????
 
M

markspace

I guess it was something like that. Putting the processes to read
STDOUT and STDERR in separate threads did the trick. But the Perl
script definitely finished, so ?????


I don't know if this is documented somewhere but it's well known. For
whatever reason, Process doesn't consider the process to be "done" until
all of it's output is read. Possibly to avoid issues where one thread
is still reading/processing output and another thread thinks otherwise.
 
J

Jim Janney

Tim Slattery said:
I guess it was something like that. Putting the processes to read
STDOUT and STDERR in separate threads did the trick. But the Perl
script definitely finished, so ?????

The Perl interpreter is written in C, so it probably ends by calling
exit(). One of the things exit() does is to flush all open buffered
output streams. If any of those is a pipe, it could block at that
point.
 
E

Esmond Pitt

For whatever reason, Process doesn't consider the process to be "done" until
all of it's output is read.

This is not so. The issue is that the child process can't exit if it is
blocked doing output because the reading end hasn't read it. Process
itself couldn't care less.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,682
Members
48,796
Latest member
Greg L.

Latest Threads

Top