Skip navigation

byah.

you’d think it’d tell you.

Launching an executable from a Java program on win32 using lines like:

public class TestExecutable {
public static void main( String args[] )
{ 
System.out.println("about to launch javac.exe...");
Runtime rt = Runtime.getRuntime();
Process proc = null;
String cmd;
try
{
  cmd = "C:\\program files\\java\\jdk1.5.0_15\\bin\\javac.exe";
  proc = rt.exec( cmd );

  // now, I want to wait until the compilation of the java program is
  // complete!

  proc.waitFor();  // block until execution is complete
}
catch(Exception e)
{
  System.out.println("whoops...");
  e.printStackTrace();
}

System.out.println("Finish");
}//main
}//class

but it hangs!!

How stupid. Nobody told you that you have to pull anything out of the error stream or else proc.waitFor() will hang forever.

Anyway:

class TestExecutable {
public static void main(String[] args)
{
  System.out.println("about to launch javac.exe...");
  Runtime rt = Runtime.getRuntime();
  Process proc = null;
  String cmd;
  try
  {
    cmd = "C:\\program files\\java\\jdk1.5.0_15\\bin\\javac.exe";
    proc = rt.exec( cmd );

    // now, I want to wait until the compilation 
    // of the java program is complete!
    
    // WAIT!!! waitFor() will HANG IF THERE IS ANYTHING
    // AT ALL IN THE STDERR OUTPUT BUFFER!!
    
    // So, we have to grab the standard error output
    // and check to see if there's anything in it,
    // before we said waitFor().
	    
    InputStream stderr = proc.getErrorStream();
    InputStreamReader isrErr = new InputStreamReader(stderr);
    BufferedReader br = new BufferedReader(isrErr);
    String line = null;
        
    while ( (line = br.readLine()) != null)
    {
      System.out.println("Err stream says: " + line);
    }
    proc.waitFor();  // block until execution is complete
  }
  catch(Exception e)
  {
    System.out.println("whoops...");
    e.printStackTrace();
  }

System.out.println("Finish");
}//main
}//class

IT WORKS!!

But wait. I have another program that STILL HANGS WHEN I LAUNCH IT USING Runtime.getRuntime().exec(). WHY???

Because it will hang as long as STDOUT had something to say.

public class TestExecutable{
public static void main(String[] args)
{
  System.out.println("about to launch someprogram.exe...");
  Runtime rt = Runtime.getRuntime();
  Process proc = null;
	  
  try
  {
    cmd = "C:\\program.exe";
    proc = rt.exec( cmd );

    // now, I want to wait until the compilation 
    // of the java program is complete!
	    
    // WAIT!!! waitFor() will HANG IF THERE IS ANYTHING
    // AT ALL IN THE STDERR ___OR___ STDOUT OUTPUT BUFFERS!!!!
	    
    // So, we have to grab the standard error output
    // OR JUST THE PLAIN OLD STANDARD OUT OUTPUT,
    // and check to see if there's anything in it,
    // before we said waitFor().
	    
    // stuff to connect to and read from stderr
    InputStream stderr = proc.getErrorStream();
    InputStreamReader isrErr = new InputStreamReader(stderr);
    BufferedReader brErr = new BufferedReader(isrErr);
	
    // stuff to connect to and read from stdout
    InputStream stdout = proc.getInputStream();
    InputStreamReader isrStd = new InputStreamReader(stdout);
    BufferedReader brStd = new BufferedReader(isrStd);
		
    String line = null;
    if( brErr.ready() )
    {
      // The error stream has something to say!!
      // You had better listen, or proc.waitFor()
      // will hang forever!!!
      while ( (line = brErr.readLine()) != null)
      {
        System.out.println("Err stream says: " + line);
      }
    }
        
    if( brStd.ready() )
    {
      while ( (line = brStd.readLine()) != null)
      {
         System.out.println("stdout says: " + line);
      }
    }
      
     int exitVal = proc.waitFor();    // block until execution is complete
     System.out.println("Process exitValue: " + exitVal);
  }
  catch(Exception e)
  {
    System.out.println("whoops...");
    e.printStackTrace();
  }

  System.out.println("Finish");
}
}

this is still a bad solution

This program will STILL hang if you try to read from stderr or stdout, and NEITHER has anything to say (will hang at readLine())

I think what you want to do is, create a separate thread that polls brStd.ready() and brErr.ready() and pull data from each of those streams if / when there is data available.

Byah. I’ll post something like that later.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: