Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / May 2007

Tip: Looking for answers? Try searching our database.

Runtime.exec(cmd) hangs up

Thread view: 
Vic - 24 May 2007 23:43 GMT
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
Vic - 24 May 2007 23:55 GMT
one correction -
cmd = "home/qaplay/loader/604/soaploaderclient.ps nemo 50624 55604
genevaman qa /home/vpatanka/604Current/lib/loader/data/
DuplicateTransactionTest.0.lrd -bcp"

> I am having a problem with Runtime.exec(cmd) where cmd is a string and
> is as follows -
[quoted text clipped - 35 lines]
> then I can do that. Please let me know what am I missing here in
> Runtime.exec() or its something else
Vic - 25 May 2007 00:05 GMT
type
cmd = "home/qaplay/loader/604/soaploaderclient.ps nemo 50624 55604
genevaman qa /home/vpatanka/604Current/lib/loader/data/
DuplicateTransactionTest.0.lrd -bcp"
> I am having a problem with Runtime.exec(cmd) where cmd is a string and
> is as follows -
[quoted text clipped - 35 lines]
> then I can do that. Please let me know what am I missing here in
> Runtime.exec() or its something else
Matt Humphrey - 25 May 2007 01:33 GMT
|I am having a problem with Runtime.exec(cmd) where cmd is a string and
| is as follows -
[quoted text clipped - 24 lines]
| 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 matth@ivizNOSPAM.com http://www.iviz.com/
Vic - 25 May 2007 01:44 GMT
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

> |I am having a problem with Runtime.exec(cmd) where cmd is a string and
> | is as follows -
[quoted text clipped - 38 lines]
>
> Matt Humphrey m...@ivizNOSPAM.comhttp://www.iviz.com/
Mike  Schilling - 25 May 2007 01:53 GMT
>I am having a problem with Runtime.exec(cmd) where cmd is a string and
> is as follows -
[quoted text clipped - 34 lines]
> 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();
Vic - 25 May 2007 18:54 GMT
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" <mscottschill...@hotmail.com>
wrote:

> >I am having a problem with Runtime.exec(cmd) where cmd is a string and
> > is as follows -
[quoted text clipped - 46 lines]
> anything to read and then exits.
>     4. Process.waitFor();
Daniel Pitts - 25 May 2007 19:19 GMT
> 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
[quoted text clipped - 8 lines]
>
> 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.
Vic - 25 May 2007 20:43 GMT
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" <mscottschill...@hotmail.com>
wrote:

> >I am having a problem with Runtime.exec(cmd) where cmd is a string and
> > is as follows -
[quoted text clipped - 46 lines]
> anything to read and then exits.
>     4. Process.waitFor();
Mike  Schilling - 25 May 2007 21:10 GMT
> Alright so here is my new code now, I implemented it the way you said
> (with some online help)
[quoted text clipped - 54 lines]
> (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();
Matt Humphrey - 25 May 2007 21:21 GMT
| Alright so here is my new code now, I implemented it the way you said
| (with some online help)
[quoted text clipped - 54 lines]
| (which calls the Command executer constructor). Could you please
| suggest me some changes to get this?

Your earlier example showed that you wanted to concatenate all the output
into a single string.  If that's what you want to do, add a StringBuffer
instance variable to the StreamGobbler and have the read loop append each
line as you get it--rather than print it out.  Modify the CommandExecuter to
assign its stdout / stderr instance variables with the stream gobbler
contents when the process has completed.  After the executer completes, just
retrieve the values via get methods.

If you want to actually process the strings as they arrive, that's a bit
more complicated.

Matt Humphrey matth@ivizNOSPAM.com http://www.iviz.com/
Vic - 25 May 2007 23:20 GMT
> | Alright so here is my new code now, I implemented it the way you said
> | (with some online help)
[quoted text clipped - 67 lines]
>
> Matt Humphrey m...@ivizNOSPAM.comhttp://www.iviz.com/

I talked to my manager and she allowed me to make stdout and stderr as
"pulic static" (global) so I could directly access those in
StreamGobbler as I am producing the output in those two thrads.
Thank you so much for your help. have a great long weekend
Matt Humphrey - 26 May 2007 12:59 GMT
| > | Alright so here is my new code now, I implemented it the way you said
| > | (with some online help)
[quoted text clipped - 72 lines]
| StreamGobbler as I am producing the output in those two thrads.
| Thank you so much for your help. have a great long weekend

That's the kind of problem I've seen trip up others and there's no reason to
use a static variable in this case because it's equally easy and much safer
to make it an instance variable.  Good luck with your program.

Matt Humphrey matth@ivizNOSPAM.com http://www.iviz.com/
Lew - 26 May 2007 15:43 GMT
"Vic" <vikrantp@gmail.com> wrote
> | I talked to my manager and she allowed me to make stdout and stderr as
> | "pulic static" (global) so I could directly access those in
[quoted text clipped - 4 lines]
> use a static variable in this case because it's equally easy and much safer
> to make it an instance variable.  Good luck with your program.

I have a real problem with programmers asking permission from managers about
such detailed code decisions.  If your manager is such a good coder, why is
she in management?

If the programmer needs to ask a manager for programming advice, why aren't
they in management and far, far, far away from coding?

If you are a good enough programmer to deserve the job title you should be
telling the manager what the code needs, not asking; if you aren't, your job
shouldn't involve anything fancier than asking, "Would you like fries with that?"

Signature

Lew

Vic - 29 May 2007 18:50 GMT
> | > | Alright so here is my new code now, I implemented it the way you said
> | > | (with some online help)
[quoted text clipped - 82 lines]
>
> Matt Humphrey m...@ivizNOSPAM.comhttp://www.iviz.com/

Thanks Matt and everyone here for the info and help. I actually
modified the class and removed "static" and added getResult() in the
thread processing logic to get the string and then I access that in
the CommandExecuter class. Everything is working fine now.
Lew - no offense but you don't have to bash me up without knowing
anything about me. I have some experience with programming but I am in
QA/scripting side mostly doing perl scripts n other stuff but I was
asked to work on java code (there was a guy who left the company and
was working on this part) which I have hardly done so I am not a java
coder at all. But my manager just asked me to look into this if I
could thats why I started looking into the code. have a nice day
Vic
Lew - 29 May 2007 19:52 GMT
> Lew - no offense but you don't have to bash me up without knowing
> anything about me. I have some experience with programming but I am in
[quoted text clipped - 3 lines]
> coder at all. But my manager just asked me to look into this if I
> could thats why I started looking into the code. have a nice day

I am not bashing you at all.

I was describing a general problem I have with certain types of manager and
the lack of respect they sometimes have for our profession.

I apologize for making it sound like you personally were at any kind of fault.
 I should learn to use the pronoun "one" when prescribing, instead of the
less formal and more ambiguous "you".

I am aware that managers often tell us what to do instead of letting us tell
them what should be done.  I do not blame the engineer for this.  Again, I'm
sorry that I caught you in the crossfire.

Signature

Lew

Vic - 29 May 2007 22:44 GMT
> > Lew - no offense but you don't have to bash me up without knowing
> > anything about me. I have some experience with programming but I am in
[quoted text clipped - 19 lines]
> --
> Lew

No Problem. Its cool. Thanks for the clarification. I totally agree
with what you're saying. Have a nice day


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.