H
Hal Vaughan
I've included the method I'm having trouble with at the end of the post.
I was using Runtime.getRuntime().exec(String) to execute programs and had no
problem with it at all, but since I had to include an argument, I was
worried about problems with spaces in program names, so I switched
to .exec(String[]) instead of .exec(String). I figure this way when it
turns out I have to run a program with a space in the filename, there
should be no problem.
When I was specifying the program with only a String, every program I would
attempt would run. Now that I'm using String[], I have times where I run
one program and it works, then run the same program, with the same
arguments, a few seconds later, and waitFor() returns immediately and I get
no data from the ErrorStream or InputStream.
I tried, as an experiment, to put quotation marks around the filename in a
string so it would look like this:
"/usr/bin/myprogram" -myargument
And that would not work -- the programs would not run at all.
Also as an experiment, in the spot I marked with a comment, I tried a
sleep() call, just in case waiting had any effect. When I had it wait 100
milliseconds, every time I ran a program, I got data from the appropriate
InputStream or ErrorStream, but not all the data I should have (it was
lopped off at the beginning). I tried shorter times for sleep() and with
10 milliseconds, no programs ran.
So why is it that sometimes the program runs and I get input and sometimes
it doesn't? My best guess is that the program always runs, but that there
might be a timing issue that keeps me from reading the streams quickly
enough, but that doesn't sound likely.
Any help is appreciated.
Thanks!
Hal
------Code method-----
public boolean runFile()
{
stopFlag = false;
System.out.println("DEBUG: Starting to run file, Command: " + runLine);
try
{
Process procRun = Runtime.getRuntime().exec(cmdInfo);
iRead = new BufferedReader (new
InputStreamReader(procRun.getInputStream()));
eRead = new BufferedReader (new
InputStreamReader(procRun.getErrorStream()));
System.out.println("\tDEBUG: Buffers made");
//Tried to use Thread.sleep() here with different timings
//Thread to read Standard output
//Only exception thrown by BufferedReader.readLine() is EOF, which
//means we're at the end, so there's no need to do anything with it.
new Thread(
new Runnable() {
public void run() {
String sRead;
try {
while ((sRead = iRead.readLine()) != null) {
System.out.println("DEBUG: Standard:" + sRead);
outData = outData + sRead;
if (stopFlag)
break;
}
} catch (Exception eofE) {}
}
}
).start();
//Thread to read Error output
new Thread(
new Runnable() {
public void run() {
String sRead;
try {
while ((sRead = eRead.readLine()) != null) {
System.out.println("DEBUG: Error:" + sRead);
outError = outError + sRead;
if (stopFlag)
break;
}
} catch (Exception eofE) {}
}
}
).start();
procRun.waitFor();
stopFlag = true;
System.out.println("\tDEBUG: Run is complete");
iStream.close();
eStream.close();
}
catch (Exception e)
{
System.err.println("Could not execute IDFile: " + runLine);
return false;
}
System.out.println("\tDEBUG: Done running file");
return true;
}
I was using Runtime.getRuntime().exec(String) to execute programs and had no
problem with it at all, but since I had to include an argument, I was
worried about problems with spaces in program names, so I switched
to .exec(String[]) instead of .exec(String). I figure this way when it
turns out I have to run a program with a space in the filename, there
should be no problem.
When I was specifying the program with only a String, every program I would
attempt would run. Now that I'm using String[], I have times where I run
one program and it works, then run the same program, with the same
arguments, a few seconds later, and waitFor() returns immediately and I get
no data from the ErrorStream or InputStream.
I tried, as an experiment, to put quotation marks around the filename in a
string so it would look like this:
"/usr/bin/myprogram" -myargument
And that would not work -- the programs would not run at all.
Also as an experiment, in the spot I marked with a comment, I tried a
sleep() call, just in case waiting had any effect. When I had it wait 100
milliseconds, every time I ran a program, I got data from the appropriate
InputStream or ErrorStream, but not all the data I should have (it was
lopped off at the beginning). I tried shorter times for sleep() and with
10 milliseconds, no programs ran.
So why is it that sometimes the program runs and I get input and sometimes
it doesn't? My best guess is that the program always runs, but that there
might be a timing issue that keeps me from reading the streams quickly
enough, but that doesn't sound likely.
Any help is appreciated.
Thanks!
Hal
------Code method-----
public boolean runFile()
{
stopFlag = false;
System.out.println("DEBUG: Starting to run file, Command: " + runLine);
try
{
Process procRun = Runtime.getRuntime().exec(cmdInfo);
iRead = new BufferedReader (new
InputStreamReader(procRun.getInputStream()));
eRead = new BufferedReader (new
InputStreamReader(procRun.getErrorStream()));
System.out.println("\tDEBUG: Buffers made");
//Tried to use Thread.sleep() here with different timings
//Thread to read Standard output
//Only exception thrown by BufferedReader.readLine() is EOF, which
//means we're at the end, so there's no need to do anything with it.
new Thread(
new Runnable() {
public void run() {
String sRead;
try {
while ((sRead = iRead.readLine()) != null) {
System.out.println("DEBUG: Standard:" + sRead);
outData = outData + sRead;
if (stopFlag)
break;
}
} catch (Exception eofE) {}
}
}
).start();
//Thread to read Error output
new Thread(
new Runnable() {
public void run() {
String sRead;
try {
while ((sRead = eRead.readLine()) != null) {
System.out.println("DEBUG: Error:" + sRead);
outError = outError + sRead;
if (stopFlag)
break;
}
} catch (Exception eofE) {}
}
}
).start();
procRun.waitFor();
stopFlag = true;
System.out.println("\tDEBUG: Run is complete");
iStream.close();
eStream.close();
}
catch (Exception e)
{
System.err.println("Could not execute IDFile: " + runLine);
return false;
}
System.out.println("\tDEBUG: Done running file");
return true;
}