Java Mailing List Archive

http://www.junlu.com/

Home » Home (12/2007) » Apache Tomcat »

Re: Runtime.getRuntime.exec() problem

hui zhang

2007-01-15

Replies:

Mike Quilleash wrote:
> Process is a fiddly class to work with at the best of times. I can't
> say I've ever come across the exec of a Process not returning, when I've
> used it it will return immediatly from the exec() and you have to use
> Process.waitFor() if you want to wait for the program to terminate.
>
> A common problem doing this is that the standard output stream from the
> process fills up and blocks the waitFor() from ever returning as the
> process will not terminate until it's standard output is consumed. To
> do this I fork a separate thread just before calling waitFor() to read
> the standard output and error streams. This fixes the problem for me.
>
> Another not-so amusing problem is that if you don't explicitly close the
> input/output/error streams that Process returns they will get left
> hanging around and eventually you'll blow the OS limit on open file
> handles, so remember to close them.
>
> My code looks something like the following (I use a ProcessBuilder),
> needs a bit of work with try/finally to close the streams in all cases.
> If you need the output the external program generates then have the
> StreamGobbler store the output in a StringBuilder or something.
>
> You should also read this article which I where I got some of my info
> from originally.
>
> http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html
>
>
> HTH
>
>      // create and start the process - redirect stderr to stdout
>      ProcessBuilder processBuilder = new ProcessBuilder( commands );
>      processBuilder.redirectErrorStream( true );
>
>      // this call does not block
>      Process process = processBuilder.start();
>
>      // create the gobbler to read the stdout/stderr from the process
>      StreamGobbler outputGobbler = new
>           StreamGobbler( process.getInputStream() );
>
>      // kick off the separate stream gobbler thread  
>      outputGobbler.start();
>
>      // wait for the process to terminate - blocks
>      int exitCode = process.waitFor();
>
>      // wait for the gobbler to terminate - blocks
>      outputGobbler.join();
>
>      // close all the process IO streams
>      try
>      {
>         process.getInputStream().close();
>      }
>      catch ( IOException e )
>      {
>         // ignore error
>      }
>
>      try
>      {
>         process.getOutputStream().close();
>      }
>      catch ( IOException e )
>      {
>         // ignore error
>      }
>
>      try
>      {
>         process.getErrorStream().close();
>      }
>      catch ( IOException e )
>      {
>         // ignore error
>      }
>
>      return exitCode;
>
>
>
>
>
> -----Original Message-----
> From: Zack Grafton [mailto:zachary.grafton@(protected)]
> Sent: 15 January 2007 05:39
> To: Tomcat Users List
> Subject: Re: Runtime.getRuntime.exec() problem
>
> hui zhang wrote:
>  
>> Zack Grafton wrote:
>>  
>>> hui zhang wrote:
>>>    
>>>> Zack Grafton wrote:
>>>>      
>>>>> hui zhang wrote:
>>>>>      
>>>>>> Hi Everybody,
>>>>>>
>>>>>> Now I am trying to launch an external application, for example,
>>>>>> "top" ,in my web application, and killing it by PID after a while.
>>>>>> But when I execute Runtime.getRuntime.exec("top") in my JSP page
>>>>>> or Servlet, Tomcat is stuck in that page and do not display
>>>>>> anything because it can not stop running until that "commnad" is
>>>>>> terminated, which means it waiting for the response from
>>>>>> Runtime.getRuntime.exec("top"). It seems that it will run forever.
>>>>>> Is there any solution to solve this problem? I mean that JSP page
>>>>>> can execute the following code no matter if it finish the process
>>>>>> is done.
>>>>>>
>>>>>> BTW, I do not use System.exit() in my program. It may cause
>>>>>> Security Manager problem.
>>>>>> Thanks and best regards,
>>>>>>
>>>>>> Hui
>>>>>>
>>>>>> ------------------------------------------------------------------
>>>>>> --- To start a new topic, e-mail: users@(protected)
>>>>>> unsubscribe, e-mail: users-unsubscribe@(protected)
>>>>>> For additional commands, e-mail: users-help@(protected)
>>>>>>
>>>>>>
>>>>>>        
>>>>> Hey,
>>>>>
>>>>> I'm new to the list and all, but you might want to try executing
>>>>> "top" in batch mode. The command line option is -b on my gentoo
>>>>> linux box. Also, be careful of executing commands from applets and
>>>>>      
>
>  
>>>>> such. Another thing might be user permissions as well. You could
>>>>> try executing the command and redirecting the output to a file and
>>>>> parsing the file instead.
>>>>>
>>>>> Zack Grafton
>>>>>
>>>>> -------------------------------------------------------------------
>>>>> -- To start a new topic, e-mail: users@(protected)
>>>>> unsubscribe, e-mail: users-unsubscribe@(protected)
>>>>> For additional commands, e-mail: users-help@(protected)
>>>>>      
>>>> Hi,
>>>>
>>>> "TOP" is only an example in this case. Actually I am running some
>>>> program which can not stop running until terminating it by "Control
>>>> + C". In this case, Tomcat can not run the following code if the
>>>> external application does not stop. I need a solution to make my
>>>> webapp running in this case. Thank you.
>>>>
>>>> Regards,
>>>>
>>>> Hui
>>>>
>>>>
>>>>
>>>>
>>>> --------------------------------------------------------------------
>>>> - To start a new topic, e-mail: users@(protected)
>>>> unsubscribe, e-mail: users-unsubscribe@(protected)
>>>> For additional commands, e-mail: users-help@(protected)
>>>>
>>>>      
>>> Hui,
>>>
>>> You could check out the javadoc for the java.lang.Process class. You
>>>    
>
>  
>>> would need to do something like:
>>>
>>> Process process = Runtime.getRuntime().exec("command");
>>>
>>> process.getInputStream();
>>> process.getOutputStream();
>>>
>>> Just remember to wrap the streams appropriately and you should be
>>> able to read the stdin and stdout of the program. That should allow
>>> you to send the <control>+C signal to the program.
>>>
>>>
>>> Zack Grafton
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To start a new topic, e-mail: users@(protected),
>>>    
>
>  
>>> e-mail: users-unsubscribe@(protected)
>>> For additional commands, e-mail: users-help@(protected)
>>>    
>> Hi,
>>
>> I can get the InputStream from process object. How can I send
>> Control+C to the console next? I can not send another command to
>> console until this command is terminated.
>>
>> BTW, what is the string format of "Control + C"?
>>
>> Thanks!
>>
>> Regards,
>>
>> Hui
>>
>> ---------------------------------------------------------------------
>> To start a new topic, e-mail: users@(protected),
>> e-mail: users-unsubscribe@(protected)
>> For additional commands, e-mail: users-help@(protected)
>>
>>
>>  
> Hui,
>
> You might also want to look at the destroy method of the Process class.
>
> Zack
>
> ---------------------------------------------------------------------
> To start a new topic, e-mail: users@(protected),
> e-mail: users-unsubscribe@(protected)
> For additional commands, e-mail: users-help@(protected)
>
>
>
> This e-mail is bound by the terms and conditions described at http://www.subexazure.com/mail-disclaimer.html
>
>
> ---------------------------------------------------------------------
> To start a new topic, e-mail: users@(protected)
> To unsubscribe, e-mail: users-unsubscribe@(protected)
> For additional commands, e-mail: users-help@(protected)
>
>  
Hi,

The problem is solved. I made a really stupid mistake. The program is
stuck because of Process.getInputStream() is hold.

Thank you all.

Regards,

Hui

---------------------------------------------------------------------
To start a new topic, e-mail: users@(protected)
To unsubscribe, e-mail: users-unsubscribe@(protected)
For additional commands, e-mail: users-help@(protected)

©2008 junlu.com - Jax Systems, LLC, U.S.A.