Runtime.Exec and windows batch file

Discussion in 'Java' started by MMilkin@gmail.com, Oct 17, 2006.

  1. Guest

    Hi Im trying to run an Exec(Blah.bat) however it seems to be freezing
    for some reason if the exec returns errors then the Exec does not freez
    however if run the file and all i get is output it just freezes.

    How would i handle output from the Batch file diferently ?

    proc = rt.exec(cmd);


    stderr = proc.getErrorStream();
    isr = new InputStreamReader(stderr);
    br = new BufferedReader(isr);
    iostr = proc.getInputStream();
    ist = new InputStreamReader(iostr);
    bri = new BufferedReader(ist);

    stdoutt = proc.getOutputStream();
    ost = new OutputStreamWriter(stdoutt);
    bwr = new BufferedWriter(ost);

    String line2;

    while ( (line = br.readLine()) != null && (line2 = bri.readLine()) !=
    null)
    {
    line2 = null;
    while ( (line2 = bri.readLine()) != null)
    {
    System.out.println("Error:" + line2 + ":Error");
    }

    System.out.println("VVVVVVV");
    myString = line;
    System.out.println("Error:" + line + ":Error");
    }

    //Im asuming that it freezes somewere before this wait for proc
    command
    System.out.println("waiting for proc");
    exitVal = proc.waitFor();

    if(exitVal > 0)
    {
    System.out.println("exitVal: " + exitVal);
    }
    , Oct 17, 2006
    #1
    1. Advertising

  2. On 17 Oct 2006 11:56:42 -0700, wrote:
    > Hi Im trying to run an Exec(Blah.bat) however it seems to be
    > freezing for some reason if the exec returns errors then the Exec
    > does not freez however if run the file and all i get is output it
    > just freezes.


    The following line will attempt to read one line from each of the
    streams alternately:

    > while ( (line = br.readLine()) != null && (line2 = bri.readLine()) !=
    > null)


    As long as both streams have something to read, the loop progresses.
    As soon as one stream has nothing, readLine() blocks waiting for it.

    There are essentially two ways to do this correctly:

    - create a second Thread to read from one of the streams, and read
    from the other one in the original Thread
    - use ProcessBuilder to combine the two streams, so you really can
    read from both at the same time.

    /gordon

    --
    [ don't email me support questions or followups ]
    g o r d o n + n e w s @ b a l d e r 1 3 . s e
    Gordon Beaton, Oct 17, 2006
    #2
    1. Advertising

  3. Guest

    Gordon Beaton wrote:
    > On 17 Oct 2006 11:56:42 -0700, wrote:
    > > Hi Im trying to run an Exec(Blah.bat) however it seems to be
    > > freezing for some reason if the exec returns errors then the Exec
    > > does not freez however if run the file and all i get is output it
    > > just freezes.

    >
    > The following line will attempt to read one line from each of the
    > streams alternately:
    >
    > > while ( (line = br.readLine()) != null && (line2 = bri.readLine()) !=
    > > null)

    >
    > As long as both streams have something to read, the loop progresses.
    > As soon as one stream has nothing, readLine() blocks waiting for it.
    >
    > There are essentially two ways to do this correctly:
    >
    > - create a second Thread to read from one of the streams, and read
    > from the other one in the original Thread
    > - use ProcessBuilder to combine the two streams, so you really can
    > read from both at the same time.
    >
    > /gordon
    >
    > --
    > [ don't email me support questions or followups ]
    > g o r d o n + n e w s @ b a l d e r 1 3 . s e


    Hmmm .....

    So do something of this nature:

    have a class

    public class ReadThread implements Runnable {
    BufferedReader reader;

    public ReadThread(BufferedReader br) {
    reader = br;
    }

    public BufferedReader getReader() {
    return reader;
    }

    public void setNumber(BufferedReader br) {
    reader = br;
    }

    public void run()
    {
    String line2 = null;

    try {

    while ( (line2 = reader.readLine()) != null)
    {
    System.out.println("Error:" + line2 + ":Error");
    }
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    }

    and from my code instead of having that ugly if statment do

    MyThread Error = new MyThread(br);
    MyThread Outp = new MyThread(bri);

    Error.run();
    Outp.run();
    , Oct 17, 2006
    #3
  4. Guest

    wrote:
    > Gordon Beaton wrote:
    > > On 17 Oct 2006 11:56:42 -0700, wrote:
    > > > Hi Im trying to run an Exec(Blah.bat) however it seems to be
    > > > freezing for some reason if the exec returns errors then the Exec
    > > > does not freez however if run the file and all i get is output it
    > > > just freezes.

    > >
    > > The following line will attempt to read one line from each of the
    > > streams alternately:
    > >
    > > > while ( (line = br.readLine()) != null && (line2 = bri.readLine()) !=
    > > > null)

    > >
    > > As long as both streams have something to read, the loop progresses.
    > > As soon as one stream has nothing, readLine() blocks waiting for it.
    > >
    > > There are essentially two ways to do this correctly:
    > >
    > > - create a second Thread to read from one of the streams, and read
    > > from the other one in the original Thread
    > > - use ProcessBuilder to combine the two streams, so you really can
    > > read from both at the same time.
    > >
    > > /gordon
    > >
    > > --
    > > [ don't email me support questions or followups ]
    > > g o r d o n + n e w s @ b a l d e r 1 3 . s e

    >
    > Hmmm .....
    >
    > So do something of this nature:
    >
    > have a class
    >
    > public class ReadThread implements Runnable {
    > BufferedReader reader;
    >
    > public ReadThread(BufferedReader br) {
    > reader = br;
    > }
    >
    > public BufferedReader getReader() {
    > return reader;
    > }
    >
    > public void setNumber(BufferedReader br) {
    > reader = br;
    > }
    >
    > public void run()
    > {
    > String line2 = null;
    >
    > try {
    >
    > while ( (line2 = reader.readLine()) != null)
    > {
    > System.out.println("Error:" + line2 + ":Error");
    > }
    > } catch (IOException e) {
    > // TODO Auto-generated catch block
    > e.printStackTrace();
    > }
    > }
    > }
    >
    > and from my code instead of having that ugly if statment do
    >
    > MyThread Error = new MyThread(br);
    > MyThread Outp = new MyThread(bri);
    >
    > Error.run();
    > Outp.run();


    This seems to Block when I run it
    , Oct 17, 2006
    #4
  5. <> wrote in message
    news:...
    >
    > wrote:
    >> Gordon Beaton wrote:
    >> > On 17 Oct 2006 11:56:42 -0700, wrote:
    >> > > Hi Im trying to run an Exec(Blah.bat) however it seems to be
    >> > > freezing for some reason if the exec returns errors then the Exec
    >> > > does not freez however if run the file and all i get is output it
    >> > > just freezes.
    >> >
    >> > The following line will attempt to read one line from each of the
    >> > streams alternately:
    >> >
    >> > > while ( (line = br.readLine()) != null && (line2 = bri.readLine()) !=
    >> > > null)
    >> >
    >> > As long as both streams have something to read, the loop progresses.
    >> > As soon as one stream has nothing, readLine() blocks waiting for it.
    >> >
    >> > There are essentially two ways to do this correctly:
    >> >
    >> > - create a second Thread to read from one of the streams, and read
    >> > from the other one in the original Thread
    >> > - use ProcessBuilder to combine the two streams, so you really can
    >> > read from both at the same time.
    >> >
    >> > /gordon
    >> >
    >> > --
    >> > [ don't email me support questions or followups ]
    >> > g o r d o n + n e w s @ b a l d e r 1 3 . s e

    >>
    >> Hmmm .....
    >>
    >> So do something of this nature:
    >>
    >> have a class
    >>
    >> public class ReadThread implements Runnable {
    >> BufferedReader reader;
    >>
    >> public ReadThread(BufferedReader br) {
    >> reader = br;
    >> }
    >>
    >> public BufferedReader getReader() {
    >> return reader;
    >> }
    >>
    >> public void setNumber(BufferedReader br) {
    >> reader = br;
    >> }
    >>
    >> public void run()
    >> {
    >> String line2 = null;
    >>
    >> try {
    >>
    >> while ( (line2 = reader.readLine()) != null)
    >> {
    >> System.out.println("Error:" + line2 + ":Error");
    >> }
    >> } catch (IOException e) {
    >> // TODO Auto-generated catch block
    >> e.printStackTrace();
    >> }
    >> }
    >> }
    >>
    >> and from my code instead of having that ugly if statment do
    >>
    >> MyThread Error = new MyThread(br);
    >> MyThread Outp = new MyThread(bri);
    >>
    >> Error.run();
    >> Outp.run();


    Please keep reading the API. You don't start a thread by calling run--you
    call start. Calling run will execute the thread body in the current
    thread--not what you want. This stream reading problem is well known and
    solutions have been posted here in the past--search for StreamGobbler.

    Matt Humphrey http://www.iviz.com/

    >
    > This seems to Block when I run it
    >
    Matt Humphrey, Oct 18, 2006
    #5
  6. wrote:
    > wrote:
    >> Gordon Beaton wrote:
    >>> On 17 Oct 2006 11:56:42 -0700, wrote:
    >>>> Hi Im trying to run an Exec(Blah.bat) however it seems to be
    >>>> freezing for some reason if the exec returns errors then the Exec
    >>>> does not freez however if run the file and all i get is output it
    >>>> just freezes.
    >>> The following line will attempt to read one line from each of the
    >>> streams alternately:
    >>>
    >>>> while ( (line = br.readLine()) != null && (line2 = bri.readLine()) !=
    >>>> null)
    >>> As long as both streams have something to read, the loop progresses.
    >>> As soon as one stream has nothing, readLine() blocks waiting for it.
    >>>
    >>> There are essentially two ways to do this correctly:
    >>>
    >>> - create a second Thread to read from one of the streams, and read
    >>> from the other one in the original Thread
    >>> - use ProcessBuilder to combine the two streams, so you really can
    >>> read from both at the same time.
    >>>
    >>> /gordon
    >>>
    >>> --
    >>> [ don't email me support questions or followups ]
    >>> g o r d o n + n e w s @ b a l d e r 1 3 . s e

    >> Hmmm .....
    >>
    >> So do something of this nature:
    >>
    >> have a class
    >>
    >> public class ReadThread implements Runnable {
    >> BufferedReader reader;
    >>
    >> public ReadThread(BufferedReader br) {
    >> reader = br;
    >> }
    >>
    >> public BufferedReader getReader() {
    >> return reader;
    >> }
    >>
    >> public void setNumber(BufferedReader br) {
    >> reader = br;
    >> }
    >>
    >> public void run()
    >> {
    >> String line2 = null;
    >>
    >> try {
    >>
    >> while ( (line2 = reader.readLine()) != null)
    >> {
    >> System.out.println("Error:" + line2 + ":Error");
    >> }
    >> } catch (IOException e) {
    >> // TODO Auto-generated catch block
    >> e.printStackTrace();
    >> }
    >> }
    >> }
    >>
    >> and from my code instead of having that ugly if statment do
    >>
    >> MyThread Error = new MyThread(br);
    >> MyThread Outp = new MyThread(bri);
    >>
    >> Error.run();
    >> Outp.run();

    >
    > This seems to Block when I run it
    >


    It won't either as you are not creating new threads you are just calling
    the run method so the first one blocks your execution.

    Take a look at the following code. I wrote this because I was doing a
    lot of execing for a while and wanted to simplify the coding. I'm not
    sure that it exactly did what I wanted but it should give you some idea
    how to code these things.

    //
    //
    // ProcessControl
    //
    //

    import java.io.*;

    public class ProcessControl {
    private Process process;

    public ProcessControl(String... args) throws IOException {
    ProcessBuilder builder = new ProcessBuilder(args);
    process = builder.start();
    }

    public void handleInput(final InputStream is) {
    Runnable r = new Runnable() {
    public void run() {
    BufferedReader br = null;
    try {
    InputStreamReader isr = new InputStreamReader(is);
    br = new BufferedReader(isr);
    String string = null;
    while ((string = br.readLine()) != null)
    System.out.println(string);
    } catch (IOException ioe) {
    System.out.println("ProcessControl.handleInput(): "
    + ioe);
    } finally {
    if (br != null)
    try {
    br.close();
    } catch (IOException ioe) {
    ioe.printStackTrace();
    }
    }
    }
    };
    new Thread(r).start();
    }

    public void handleInput() {
    handleInput(getInputStream());
    }

    public void handleError() {
    handleInput(getErrorStream());
    }

    public Process getProcess() {
    return process;
    }

    public OutputStream getOutputStream() {
    return process.getOutputStream();
    }

    public InputStream getInputStream() {
    return process.getInputStream();
    }

    public InputStream getErrorStream() {
    return process.getErrorStream();
    }

    public int waitFor() throws InterruptedException {
    return process.waitFor();
    }

    public static void main(String[] args) {
    try {
    ProcessControl pc = new ProcessControl(args);
    pc.handleInput();
    pc.handleError();
    pc.waitFor();
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    }

    And here is a program you can use to test the stdin and stderr.

    public class test {
    public static void main(String[] args) {
    System.out.println("STDOUT");
    System.err.println("STDERR");
    }
    }

    --

    Knute Johnson
    email s/nospam/knute/
    Knute Johnson, Oct 18, 2006
    #6
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. jds
    Replies:
    4
    Views:
    76,516
    Nitin Yadav
    Oct 3, 2011
  2. paul brown
    Replies:
    3
    Views:
    5,555
    deepa gr
    Feb 17, 2009
  3. Kid
    Replies:
    3
    Views:
    3,504
    P.Hill
    Feb 5, 2004
  4. S!mb@
    Replies:
    3
    Views:
    7,660
    Roedy Green
    Jul 19, 2004
  5. Hal Vaughan
    Replies:
    11
    Views:
    1,107
    Gordon Beaton
    May 22, 2006
Loading...

Share This Page