Spawning process from Java gives deadlock for standard output

P

peter.koch.larsen

Hi all

We have a weird problem here. When we spawn a program from a 1.4.2 java
program (using Runtime().exec(String command, String[] envp, File
dir)), the spawned program appears to be deadlocked in some standard
output routine. At least if we do not write to std::cout (the spawned
process is written in C++), the program behaves as expected. The
spawned program also works fine if we start the program manually from
the commandline.
Do anyone have an idea what might be going on here?

Kind regards
Peter Koch Larsen
 
T

Thomas Weidenfeller

We have a weird problem here. When we spawn a program from a 1.4.2 java
program (using Runtime().exec(String command, String[] envp, File
dir)), the spawned program appears to be deadlocked in some standard
output routine. At least if we do not write to std::cout (the spawned
process is written in C++), the program behaves as expected. The
spawned program also works fine if we start the program manually from
the commandline.
Do anyone have an idea what might be going on here?

You forgot to read the standard output and standard error streams from
the started program. See the Process class for a start.

/Thomas
 
P

peter.koch.larsen

Thomas said:
We have a weird problem here. When we spawn a program from a 1.4.2 java
program (using Runtime().exec(String command, String[] envp, File
dir)), the spawned program appears to be deadlocked in some standard
output routine. At least if we do not write to std::cout (the spawned
process is written in C++), the program behaves as expected. The
spawned program also works fine if we start the program manually from
the commandline.
Do anyone have an idea what might be going on here?

You forgot to read the standard output and standard error streams from
the started program. See the Process class for a start.
Hello Thomas

Thanks - this gives us something to work on. I have tried to study the
exec calls to see if it is possible to redirect standard io, but so far
with no succes. Do you have a suggestion as to how we can either
redirect the output or just ignore the output in some way? While we
could create a thread to read output, that solution is... er... not
printable ;-)

Kind regards
Peter
 
G

Gordon Beaton

I have tried to study the exec calls to see if it is possible to
redirect standard io, but so far with no succes. Do you have a
suggestion as to how we can either redirect the output or just
ignore the output in some way? While we could create a thread to
read output, that solution is... er... not printable ;-)

Here are a few alternatives:

You can use shell style redirection (e.g. '>') if you run the command
in a shell or wrap it in a shell script.

You can try closing the streams at your end. This might cause problems
for the child when it attempts to write to stdout or stderr, but it
might not.

If you can modify the child process, you can make it not produce
output you aren't interested in.

/gordon
 
P

peter.koch.larsen

Hi George

Gordon said:
Here are a few alternatives:

You can use shell style redirection (e.g. '>') if you run the command
in a shell or wrap it in a shell script.
Unfortunately, it seems that I can not. In my first post I stated the
wrong exec-method. In reality I use the one with a String[] as the
first parameter as we could not make the first method work when the
path contains spaces.
You can try closing the streams at your end. This might cause problems
for the child when it attempts to write to stdout or stderr, but it
might not.
This is the path chosen for now - if this gives errors in the other
application we will have to modify it.
If you can modify the child process, you can make it not produce
output you aren't interested in.

Even though the output is not really needed on std::cout we use the
console for debugging and convenience. It would be a shame to have to
give it up, but of corse we could have a switch to turn it off when
spawned from Java.
 
G

Gordon Beaton

Hi George

Hello Patrick.
Gordon said:
You can use shell style redirection (e.g. '>') if you run the command
in a shell or wrap it in a shell script.

Unfortunately, it seems that I can not. In my first post I stated the
wrong exec-method. In reality I use the one with a String[] as the
first parameter as we could not make the first method work when the
path contains spaces.

Yes, you must use exec(String[]) when your command cannot be tokenized
using whitespace.

However I fail to see how that prevents you from using a shell to
redirect the output. On Unix, this works just fine (and I'm certain
there is a similar mechanism for windows):

String[] cmd = {
"/bin/sh",
"-c",
"/path/to/mycommand -o options > /dev/null 2>&1"
};

Process p = Runtime.getRuntime().exec(cmd);

It's even easier with a script:

Process p = Runtime.getRuntime().exec("myscript");

....where the redirection is done within the script.

/gordon
 
P

peter.koch.larsen

Gordon Beaton skrev:
Hi George

Hello Patrick.
[snip]
Yes, you must use exec(String[]) when your command cannot be tokenized
using whitespace.

However I fail to see how that prevents you from using a shell to
redirect the output. On Unix, this works just fine (and I'm certain
there is a similar mechanism for windows):

String[] cmd = {
"/bin/sh",
"-c",
"/path/to/mycommand -o options > /dev/null 2>&1"
};

Hi Gordon

This is interesting. I presume that the Java exec interface must work
differently from the (C based) interfaces I'm familiar with. I would
have expected the above string to contain two parameters (one of them
containing whitespace and redirection tokens). I'll try that approach
tomorrow.

Thanks again!
Peter
[snip]
 
B

bugbear

Hi all

We have a weird problem here. When we spawn a program from a 1.4.2 java
program (using Runtime().exec(String command, String[] envp, File
dir)), the spawned program appears to be deadlocked in some standard
output routine. At least if we do not write to std::cout (the spawned
process is written in C++), the program behaves as expected. The
spawned program also works fine if we start the program manually from
the commandline.
Do anyone have an idea what might be going on here?

Yes.

http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html

BugBear
 
O

Oliver Wong

Thomas said:
We have a weird problem here. When we spawn a program from a 1.4.2 java
program (using Runtime().exec(String command, String[] envp, File
dir)), the spawned program appears to be deadlocked in some standard
output routine. At least if we do not write to std::cout (the spawned
process is written in C++), the program behaves as expected. The
spawned program also works fine if we start the program manually from
the commandline.
Do anyone have an idea what might be going on here?

You forgot to read the standard output and standard error streams from
the started program. See the Process class for a start.
Hello Thomas

Thanks - this gives us something to work on. I have tried to study the
exec calls to see if it is possible to redirect standard io, but so far
with no succes. Do you have a suggestion as to how we can either
redirect the output or just ignore the output in some way? While we
could create a thread to read output, that solution is... er... not
printable ;-)

I don't know what you mean by "not printable". I think creating a thread
which just swallows and ignores all input is the standard solution to this
problem.

- Oliver
 

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

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top