Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > Runtime.exec(cmd) hangs up

Reply
Thread Tools

Runtime.exec(cmd) hangs up

 
 
Vic
Guest
Posts: n/a
 
      05-24-2007
I am having a problem with Runtime.exec(cmd) where cmd is a string and
is as follows -

cmd = "home/qaplay/loader/604/soaploaderclient.ps nemo 50624 55604
genevaman qa /home/vpatanka/604Current/lib/loader/data/
DuplicateTransactionTest.0.lrd -bcp > & $GVHOME/tempOut.txt"


The actual code is like this ->
public CommandExecuter (String cmd) throws java.io.IOException{
System.out.println("CommandExecuter: EXECUTING COMMAND: "+cmd);
Process proc = Runtime.getRuntime().exec(cmd);

BufferedReader in = new BufferedReader(new
InputStreamReader(proc.getInputStream()));
BufferedReader err = new BufferedReader(new
InputStreamReader(proc.getErrorStream()));

stdout = "";
while ((line = in.readLine()) != null)
stdout += line +"\n";
if (stdout == "")
stdout = null;

stderr = "";
while ((line = err.readLine()) != null)
stderr += line +"\n";
if (stderr == "")
stderr = null;

//System.out.println ("CommandExecuter stdout="+stdout);
//System.out.println ("CommandExecuter stderr="+stderr);
}
}

I can run the same cmd on the shell and I get a an output which is
pretty big so I am not copying it over here but if you guyz need it
then I can do that. Please let me know what am I missing here in
Runtime.exec() or its something else

 
Reply With Quote
 
 
 
 
Vic
Guest
Posts: n/a
 
      05-24-2007
one correction -
cmd = "home/qaplay/loader/604/soaploaderclient.ps nemo 50624 55604
genevaman qa /home/vpatanka/604Current/lib/loader/data/
DuplicateTransactionTest.0.lrd -bcp"

On May 24, 3:43 pm, Vic <(E-Mail Removed)> wrote:
> I am having a problem with Runtime.exec(cmd) where cmd is a string and
> is as follows -
>
> cmd = "home/qaplay/loader/604/soaploaderclient.ps nemo 50624 55604
> genevaman qa /home/vpatanka/604Current/lib/loader/data/
> DuplicateTransactionTest.0.lrd -bcp > & $GVHOME/tempOut.txt"
>
> The actual code is like this ->
> public CommandExecuter (String cmd) throws java.io.IOException{
> System.out.println("CommandExecuter: EXECUTING COMMAND: "+cmd);
> Process proc = Runtime.getRuntime().exec(cmd);
>
> BufferedReader in = new BufferedReader(new
> InputStreamReader(proc.getInputStream()));
> BufferedReader err = new BufferedReader(new
> InputStreamReader(proc.getErrorStream()));
>
> stdout = "";
> while ((line = in.readLine()) != null)
> stdout += line +"\n";
> if (stdout == "")
> stdout = null;
>
> stderr = "";
> while ((line = err.readLine()) != null)
> stderr += line +"\n";
> if (stderr == "")
> stderr = null;
>
> //System.out.println ("CommandExecuter stdout="+stdout);
> //System.out.println ("CommandExecuter stderr="+stderr);
> }
>
> }
>
> I can run the same cmd on the shell and I get a an output which is
> pretty big so I am not copying it over here but if you guyz need it
> then I can do that. Please let me know what am I missing here in
> Runtime.exec() or its something else



 
Reply With Quote
 
 
 
 
Vic
Guest
Posts: n/a
 
      05-24-2007
type
cmd = "home/qaplay/loader/604/soaploaderclient.ps nemo 50624 55604
genevaman qa /home/vpatanka/604Current/lib/loader/data/
DuplicateTransactionTest.0.lrd -bcp"
On May 24, 3:43 pm, Vic <(E-Mail Removed)> wrote:
> I am having a problem with Runtime.exec(cmd) where cmd is a string and
> is as follows -
>
> cmd = "home/qaplay/loader/604/soaploaderclient.ps nemo 50624 55604
> genevaman qa /home/vpatanka/604Current/lib/loader/data/
> DuplicateTransactionTest.0.lrd -bcp > & $GVHOME/tempOut.txt"
>
> The actual code is like this ->
> public CommandExecuter (String cmd) throws java.io.IOException{
> System.out.println("CommandExecuter: EXECUTING COMMAND: "+cmd);
> Process proc = Runtime.getRuntime().exec(cmd);
>
> BufferedReader in = new BufferedReader(new
> InputStreamReader(proc.getInputStream()));
> BufferedReader err = new BufferedReader(new
> InputStreamReader(proc.getErrorStream()));
>
> stdout = "";
> while ((line = in.readLine()) != null)
> stdout += line +"\n";
> if (stdout == "")
> stdout = null;
>
> stderr = "";
> while ((line = err.readLine()) != null)
> stderr += line +"\n";
> if (stderr == "")
> stderr = null;
>
> //System.out.println ("CommandExecuter stdout="+stdout);
> //System.out.println ("CommandExecuter stderr="+stderr);
> }
>
> }
>
> I can run the same cmd on the shell and I get a an output which is
> pretty big so I am not copying it over here but if you guyz need it
> then I can do that. Please let me know what am I missing here in
> Runtime.exec() or its something else



 
Reply With Quote
 
Matt Humphrey
Guest
Posts: n/a
 
      05-25-2007

"Vic" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) oups.com...
|I am having a problem with Runtime.exec(cmd) where cmd is a string and
| is as follows -
|
| cmd = "home/qaplay/loader/604/soaploaderclient.ps nemo 50624 55604
| genevaman qa /home/vpatanka/604Current/lib/loader/data/
| DuplicateTransactionTest.0.lrd -bcp > & $GVHOME/tempOut.txt"
|
|
| The actual code is like this ->
| public CommandExecuter (String cmd) throws java.io.IOException{
| System.out.println("CommandExecuter: EXECUTING COMMAND: "+cmd);
| Process proc = Runtime.getRuntime().exec(cmd);
|
| BufferedReader in = new BufferedReader(new
| InputStreamReader(proc.getInputStream()));
| BufferedReader err = new BufferedReader(new
| InputStreamReader(proc.getErrorStream()));
|
| stdout = "";
| while ((line = in.readLine()) != null)
| stdout += line +"\n";
| if (stdout == "")
| stdout = null;
|
| stderr = "";
| while ((line = err.readLine()) != null)
| stderr += line +"\n";
| if (stderr == "")
| stderr = null;

The first thing that I see is that your command contains io redirection.
You have to invoke a shell in order to use those operators--you don't get
one automatically. Also, you can find the details elsewhere on the web or
the cljp past messages, but reading stdout and then reading stderr will not
solve the blocking problem. Both must be read simultaneously because if
either fills up its OS pipe buffer, your exec cmd will be automatically
suspended to give your Java reader a chance to empty the buffer. However,
your Java program will be waiting for output which will never arrive. In
this case, the stderr buffer could fill up and suspend the process while
your Java program waits for more output. There are a variety of tools and
techniques to help with this nowadays.

Matt Humphrey http://www.velocityreviews.com/forums/(E-Mail Removed) http://www.iviz.com/


 
Reply With Quote
 
Vic
Guest
Posts: n/a
 
      05-25-2007
Matt,
Thanks for a reply. I actually typed cmd incorrectly which I fixed in
the same post later on. sorry about that

cmd = ""home/qaplay/loader/604/soaploaderclient.ps nemo 50624 55604
genevaman qa /home/vpatanka/604Current/lib/loader/data/
DuplicateTransactionTest.0.lrd -bcp"

I think I know what you are talking about. Are you talking about
StreamGobbler or something of that sort? I did google it for my
problem and saw a few posts talking about it so just wondering.
I'll try it out n will get back to you soon. Thanks

On May 24, 5:33 pm, "Matt Humphrey" <(E-Mail Removed)> wrote:
> "Vic" <(E-Mail Removed)> wrote in message
>
> news:(E-Mail Removed) oups.com...
> |I am having a problem with Runtime.exec(cmd) where cmd is a string and
> | is as follows -
> |
> | cmd = "home/qaplay/loader/604/soaploaderclient.ps nemo 50624 55604
> | genevaman qa /home/vpatanka/604Current/lib/loader/data/
> | DuplicateTransactionTest.0.lrd -bcp > & $GVHOME/tempOut.txt"
> |
> |
> | The actual code is like this ->
> | public CommandExecuter (String cmd) throws java.io.IOException{
> | System.out.println("CommandExecuter: EXECUTING COMMAND: "+cmd);
> | Process proc = Runtime.getRuntime().exec(cmd);
> |
> | BufferedReader in = new BufferedReader(new
> | InputStreamReader(proc.getInputStream()));
> | BufferedReader err = new BufferedReader(new
> | InputStreamReader(proc.getErrorStream()));
> |
> | stdout = "";
> | while ((line = in.readLine()) != null)
> | stdout += line +"\n";
> | if (stdout == "")
> | stdout = null;
> |
> | stderr = "";
> | while ((line = err.readLine()) != null)
> | stderr += line +"\n";
> | if (stderr == "")
> | stderr = null;
>
> The first thing that I see is that your command contains io redirection.
> You have to invoke a shell in order to use those operators--you don't get
> one automatically. Also, you can find the details elsewhere on the web or
> the cljp past messages, but reading stdout and then reading stderr will not
> solve the blocking problem. Both must be read simultaneously because if
> either fills up its OS pipe buffer, your exec cmd will be automatically
> suspended to give your Java reader a chance to empty the buffer. However,
> your Java program will be waiting for output which will never arrive. In
> this case, the stderr buffer could fill up and suspend the process while
> your Java program waits for more output. There are a variety of tools and
> techniques to help with this nowadays.
>
> Matt Humphrey (E-Mail Removed)://www.iviz.com/



 
Reply With Quote
 
Mike Schilling
Guest
Posts: n/a
 
      05-25-2007

"Vic" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) oups.com...
>I am having a problem with Runtime.exec(cmd) where cmd is a string and
> is as follows -
>
> cmd = "home/qaplay/loader/604/soaploaderclient.ps nemo 50624 55604
> genevaman qa /home/vpatanka/604Current/lib/loader/data/
> DuplicateTransactionTest.0.lrd -bcp > & $GVHOME/tempOut.txt"
>
>
> The actual code is like this ->
> public CommandExecuter (String cmd) throws java.io.IOException{
> System.out.println("CommandExecuter: EXECUTING COMMAND: "+cmd);
> Process proc = Runtime.getRuntime().exec(cmd);
>
> BufferedReader in = new BufferedReader(new
> InputStreamReader(proc.getInputStream()));
> BufferedReader err = new BufferedReader(new
> InputStreamReader(proc.getErrorStream()));
>
> stdout = "";
> while ((line = in.readLine()) != null)
> stdout += line +"\n";
> if (stdout == "")
> stdout = null;
>
> stderr = "";
> while ((line = err.readLine()) != null)
> stderr += line +"\n";
> if (stderr == "")
> stderr = null;
>
> //System.out.println ("CommandExecuter stdout="+stdout);
> //System.out.println ("CommandExecuter stderr="+stderr);
> }
> }
>
> I can run the same cmd on the shell and I get a an output which is
> pretty big so I am not copying it over here but if you guyz need it
> then I can do that. Please let me know what am I missing here in
> Runtime.exec() or its something else



The obvious issue is that this code won't start to read stderr until the
exec'd process closes stdout, so the process may be hung trying to wite to
stderr. Try reading from stdout and stderr at the same time (in different
threads.) A nice, symmetrical way to do this is

1. Runtime.exec()
2. Start a thread that reads from stdout as long as there's anything to
read and then exits.
3. Start another thread that reads from stderr as long as there's
anything to read and then exits.
4. Process.waitFor();


 
Reply With Quote
 
Vic
Guest
Posts: n/a
 
      05-25-2007
I was wondering if its possible to read only stdout as a temporary fix
if its gonna work, would this hang up problem be still there if I just
do

Process proc = Runtime.getRuntime().exec(cmd);
BufferedReader in = new BufferedReader(new
InputStreamReader(proc.getInputStream()));
proc.waitfor (in the try catch block)
.........
.........

I actually tried the above version but didn't work


On May 24, 5:53 pm, "Mike Schilling" <(E-Mail Removed)>
wrote:
> "Vic" <(E-Mail Removed)> wrote in message
>
> news:(E-Mail Removed) oups.com...
>
>
>
> >I am having a problem with Runtime.exec(cmd) where cmd is a string and
> > is as follows -

>
> > cmd = "home/qaplay/loader/604/soaploaderclient.ps nemo 50624 55604
> > genevaman qa /home/vpatanka/604Current/lib/loader/data/
> > DuplicateTransactionTest.0.lrd -bcp > & $GVHOME/tempOut.txt"

>
> > The actual code is like this ->
> > public CommandExecuter (String cmd) throws java.io.IOException{
> > System.out.println("CommandExecuter: EXECUTING COMMAND: "+cmd);
> > Process proc = Runtime.getRuntime().exec(cmd);

>
> > BufferedReader in = new BufferedReader(new
> > InputStreamReader(proc.getInputStream()));
> > BufferedReader err = new BufferedReader(new
> > InputStreamReader(proc.getErrorStream()));

>
> > stdout = "";
> > while ((line = in.readLine()) != null)
> > stdout += line +"\n";
> > if (stdout == "")
> > stdout = null;

>
> > stderr = "";
> > while ((line = err.readLine()) != null)
> > stderr += line +"\n";
> > if (stderr == "")
> > stderr = null;

>
> > //System.out.println ("CommandExecuter stdout="+stdout);
> > //System.out.println ("CommandExecuter stderr="+stderr);
> > }
> > }

>
> > I can run the same cmd on the shell and I get a an output which is
> > pretty big so I am not copying it over here but if you guyz need it
> > then I can do that. Please let me know what am I missing here in
> > Runtime.exec() or its something else

>
> The obvious issue is that this code won't start to read stderr until the
> exec'd process closes stdout, so the process may be hung trying to wite to
> stderr. Try reading from stdout and stderr at the same time (in different
> threads.) A nice, symmetrical way to do this is
>
> 1. Runtime.exec()
> 2. Start a thread that reads from stdout as long as there's anything to
> read and then exits.
> 3. Start another thread that reads from stderr as long as there's
> anything to read and then exits.
> 4. Process.waitFor();



 
Reply With Quote
 
Daniel Pitts
Guest
Posts: n/a
 
      05-25-2007
On May 25, 10:54 am, Vic <(E-Mail Removed)> wrote:
> I was wondering if its possible to read only stdout as a temporary fix
> if its gonna work, would this hang up problem be still there if I just
> do
>
> Process proc = Runtime.getRuntime().exec(cmd);
> BufferedReader in = new BufferedReader(new
> InputStreamReader(proc.getInputStream()));
> proc.waitfor (in the try catch block)
> ........
> ........
>
> I actually tried the above version but didn't work

[snip];

You cant just waitFor, you actually have to actively read both stdout
and stderr. Although, if you don't care about distinguishing one from
the other, there IS an option (using ProcessBuilder I think) to
combine both into a single stream. You can then just read from that
stream and be happy with your results.

 
Reply With Quote
 
Vic
Guest
Posts: n/a
 
      05-25-2007
Alright so here is my new code now, I implemented it the way you said
(with some online help)
class StreamGobbler extends Thread {
InputStream is;
String type;

StreamGobbler(InputStream is, String type){
this.is = is;
this.type = type;
}

public void run(){
try{
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line = null;
while((line = br.readLine()) != null){
System.out.println(type+">"+line);
}
}
catch(IOException ioe){
ioe.printStackTrace();
}
}
}

class CommandExecuter {
public static String stdout = null;
public static String stderr = null;
private String line;

public CommandExecuter (String cmd) throws java.io.IOException{
System.out.println("CommandExecuter: EXECUTING COMMAND: "+cmd);
Process proc = Runtime.getRuntime().exec(cmd);

StreamGobbler errorGobbler = new
StreamGobbler(proc.getErrorStream(),"ERROR");
StreamGobbler outputGobbler = new
StreamGobbler(proc.getInputStream(),"OUTPUT");

errorGobbler.start();
outputGobbler.start();

try{
//VicP - temporary code to check the process status
int val = proc.waitFor();
//proc.wait(120000);
}
catch (Throwable t){
t.printStackTrace();
}
}
}
But now the question is how do I set the value of stdout and stderr in
CommandExecuter(As we are doing the stuff in thwo different threads
now)? I need these values as they are checked in the calling function
(which calls the Command executer constructor). Could you please
suggest me some changes to get this?
On May 24, 5:53 pm, "Mike Schilling" <(E-Mail Removed)>
wrote:
> "Vic" <(E-Mail Removed)> wrote in message
>
> news:(E-Mail Removed) oups.com...
>
>
>
> >I am having a problem with Runtime.exec(cmd) where cmd is a string and
> > is as follows -

>
> > cmd = "home/qaplay/loader/604/soaploaderclient.ps nemo 50624 55604
> > genevaman qa /home/vpatanka/604Current/lib/loader/data/
> > DuplicateTransactionTest.0.lrd -bcp > & $GVHOME/tempOut.txt"

>
> > The actual code is like this ->
> > public CommandExecuter (String cmd) throws java.io.IOException{
> > System.out.println("CommandExecuter: EXECUTING COMMAND: "+cmd);
> > Process proc = Runtime.getRuntime().exec(cmd);

>
> > BufferedReader in = new BufferedReader(new
> > InputStreamReader(proc.getInputStream()));
> > BufferedReader err = new BufferedReader(new
> > InputStreamReader(proc.getErrorStream()));

>
> > stdout = "";
> > while ((line = in.readLine()) != null)
> > stdout += line +"\n";
> > if (stdout == "")
> > stdout = null;

>
> > stderr = "";
> > while ((line = err.readLine()) != null)
> > stderr += line +"\n";
> > if (stderr == "")
> > stderr = null;

>
> > //System.out.println ("CommandExecuter stdout="+stdout);
> > //System.out.println ("CommandExecuter stderr="+stderr);
> > }
> > }

>
> > I can run the same cmd on the shell and I get a an output which is
> > pretty big so I am not copying it over here but if you guyz need it
> > then I can do that. Please let me know what am I missing here in
> > Runtime.exec() or its something else

>
> The obvious issue is that this code won't start to read stderr until the
> exec'd process closes stdout, so the process may be hung trying to wite to
> stderr. Try reading from stdout and stderr at the same time (in different
> threads.) A nice, symmetrical way to do this is
>
> 1. Runtime.exec()
> 2. Start a thread that reads from stdout as long as there's anything to
> read and then exits.
> 3. Start another thread that reads from stderr as long as there's
> anything to read and then exits.
> 4. Process.waitFor();



 
Reply With Quote
 
Mike Schilling
Guest
Posts: n/a
 
      05-25-2007

"Vic" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) oups.com...
> Alright so here is my new code now, I implemented it the way you said
> (with some online help)
> class StreamGobbler extends Thread {
> InputStream is;
> String type;
>
> StreamGobbler(InputStream is, String type){
> this.is = is;
> this.type = type;
> }
>
> public void run(){
> try{
> InputStreamReader isr = new InputStreamReader(is);
> BufferedReader br = new BufferedReader(isr);
> String line = null;
> while((line = br.readLine()) != null){
> System.out.println(type+">"+line);
> }
> }
> catch(IOException ioe){
> ioe.printStackTrace();
> }
> }
> }
>
> class CommandExecuter {
> public static String stdout = null;
> public static String stderr = null;
> private String line;
>
> public CommandExecuter (String cmd) throws java.io.IOException{
> System.out.println("CommandExecuter: EXECUTING COMMAND: "+cmd);
> Process proc = Runtime.getRuntime().exec(cmd);
>
> StreamGobbler errorGobbler = new
> StreamGobbler(proc.getErrorStream(),"ERROR");
> StreamGobbler outputGobbler = new
> StreamGobbler(proc.getInputStream(),"OUTPUT");
>
> errorGobbler.start();
> outputGobbler.start();
>
> try{
> //VicP - temporary code to check the process status
> int val = proc.waitFor();
> //proc.wait(120000);
> }
> catch (Throwable t){
> t.printStackTrace();
> }
> }
> }
> But now the question is how do I set the value of stdout and stderr in
> CommandExecuter(As we are doing the stuff in thwo different threads
> now)? I need these values as they are checked in the calling function
> (which calls the Command executer constructor). Could you please
> suggest me some changes to get this?


Have your StreamGobbler class keep track of the characters it's read, much
as your original code did, and add a method to return the result, something
like (not tested or even compiled)

class StreamGobbler extends Thread {
InputStream is;
String type;
String read;

StreamGobbler(InputStream is, String type){
this.is = is;
this.type = type;
}

public String getResult() {
return result;
}

public void run(){
StringBuffer buffer = new StringBuffer();
try{
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line = null;
while((line = br.readLine()) != null){
buffer.append(line);
buffer.append("\n");
}
}
catch(IOException ioe){
ioe.printStackTrace();
}
finally {
result = buffer.toString();
}
}
}

In the main program, do the following:

// wait for process to stop
int val = proc.waitFor();
// wait for threads to finish reading output
outputGobbler.join();
errorGobbler.join();
// get output
stdout = outputGobbler.getResult();
stderr = errorGobbler.getResult();


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Gem hangs => TCPSocket.write hangs Tim Shadel Ruby 1 07-24-2005 06:11 AM
Firefox hangs using pull-down menus Jim Lahue Firefox 1 06-07-2005 03:47 PM
Firefox hangs/slow load - especially on web ads - help! iDAHOPRiME Firefox 2 01-06-2005 12:58 PM
Thunderbird hangs when I ask it to search for new extensions Marc Rios Firefox 1 08-26-2004 06:51 AM
Clear hangs up - & hangs up - & hangs up Sue Bilstein NZ Computing 26 03-07-2004 01:33 AM



Advertisments