courtenayt
asked on
Java InputStream hanging when executing a script for ftp
Hi,
I've got 2 scripts that I'm calling from my Java app via the Runtime process executor:
Runtime rShell = Runtime.getRuntime();
Process pExecution = rShell.exec(sCommand);
The commands call scripts that are used to log into ftp servers and either upload or download files. In both scripts I'm also doing a remote listing of the file/s I either just uploaded or just downloaded so I can compare the number of bytes on the remote side with the number of bytes locally.
The strange thing is when I try to get this info from the InputStream, it doesn't always give me all of the input and sometimes it hangs. If I try to get the input stream multiple times, this sometimes helps to get all of the input, but I still run into issues with it hanging.
The multiple input stream values appear to come into existence if my ftp script uses "ls" or "dir" commands. Below is an example of my using the InputStream 2 times and storing everything from both InputStreams into a String called str_inputStream that I can later parse.
BufferedReader br = null;
String line;
// Capture any process output
br = new BufferedReader(new InputStreamReader(pExecuti on.getInpu tStream()) );
line = "";
str_inputStream = "";
while ((line = br.readLine()) != null && br.ready()) {
System.out.println("inputS tream1: " + line);
str_inputStream += line + System.getProperty("line.s eparator") ;
}
// Capture any process output
br = new BufferedReader(new InputStreamReader(pExecuti on.getInpu tStream()) );
line = "";
str_inputStream = "";
while ((line = br.readLine()) != null && br.ready()) {
System.out.println("inputS tream2: " + line);
str_inputStream += line + System.getProperty("line.s eparator") ;
}
Integer iExitVal = pExecution.waitFor();
The funny thing is that my first ftp script uses Windows ftp and logs into an AIX server and uses DIR to list 2 files. If I use at least 3 Input Streams I can get everything into str_inputStream and the process finishes. The other script I call uses putty's psftp program and seems to only use 1 input stream, but ends up hanging on the second file I try to "ls".
Could this have something to do with InputStream buffer sizes? Is there a way to do this without limits to the size?
Thanks,
Courtenay
I've got 2 scripts that I'm calling from my Java app via the Runtime process executor:
Runtime rShell = Runtime.getRuntime();
Process pExecution = rShell.exec(sCommand);
The commands call scripts that are used to log into ftp servers and either upload or download files. In both scripts I'm also doing a remote listing of the file/s I either just uploaded or just downloaded so I can compare the number of bytes on the remote side with the number of bytes locally.
The strange thing is when I try to get this info from the InputStream, it doesn't always give me all of the input and sometimes it hangs. If I try to get the input stream multiple times, this sometimes helps to get all of the input, but I still run into issues with it hanging.
The multiple input stream values appear to come into existence if my ftp script uses "ls" or "dir" commands. Below is an example of my using the InputStream 2 times and storing everything from both InputStreams into a String called str_inputStream that I can later parse.
BufferedReader br = null;
String line;
// Capture any process output
br = new BufferedReader(new InputStreamReader(pExecuti
line = "";
str_inputStream = "";
while ((line = br.readLine()) != null && br.ready()) {
System.out.println("inputS
str_inputStream += line + System.getProperty("line.s
}
// Capture any process output
br = new BufferedReader(new InputStreamReader(pExecuti
line = "";
str_inputStream = "";
while ((line = br.readLine()) != null && br.ready()) {
System.out.println("inputS
str_inputStream += line + System.getProperty("line.s
}
Integer iExitVal = pExecution.waitFor();
The funny thing is that my first ftp script uses Windows ftp and logs into an AIX server and uses DIR to list 2 files. If I use at least 3 Input Streams I can get everything into str_inputStream and the process finishes. The other script I call uses putty's psftp program and seems to only use 1 input stream, but ends up hanging on the second file I try to "ls".
Could this have something to do with InputStream buffer sizes? Is there a way to do this without limits to the size?
Thanks,
Courtenay
ASKER
Thanks for your help! I'm not sure if I can use the separate thread approach, since I need to be able to get the str_inputStream and str_errorStream from the class that calls an instance of the class containing executeCmd(String sCommand).
Here is what I have so far, when it executes it runs through the 1st while loop 2 times and hangs on evaluating the while condition the third time.
public Integer executeCmd(String sCommand) throws IOException, InterruptedException{
Runtime rShell = Runtime.getRuntime();
Process pExecution = rShell.exec(sCommand);
String line = null;
str_inputStream = "";
str_errorStream = "";
// Capture any process output
BufferedReader br1 = new BufferedReader(new InputStreamReader(pExecuti on.getInpu tStream()) );
while ((line = br1.readLine()) != null) {
System.out.println("inputS tream1: " + line);
str_inputStream += line + System.getProperty("line.s eparator") ;
}
// Capture any process errors
line = null;
BufferedReader br2 = new BufferedReader(new InputStreamReader(pExecuti on.getErro rStream()) );
while ((line = br2.readLine()) != null) {
System.out.println("errorS tream1: " + line);
str_errorStream += line + System.getProperty("line.s eparator") ;
}
Integer iExitVal = pExecution.waitFor();
return iExitVal;
}
Here is what I have so far, when it executes it runs through the 1st while loop 2 times and hangs on evaluating the while condition the third time.
public Integer executeCmd(String sCommand) throws IOException, InterruptedException{
Runtime rShell = Runtime.getRuntime();
Process pExecution = rShell.exec(sCommand);
String line = null;
str_inputStream = "";
str_errorStream = "";
// Capture any process output
BufferedReader br1 = new BufferedReader(new InputStreamReader(pExecuti
while ((line = br1.readLine()) != null) {
System.out.println("inputS
str_inputStream += line + System.getProperty("line.s
}
// Capture any process errors
line = null;
BufferedReader br2 = new BufferedReader(new InputStreamReader(pExecuti
while ((line = br2.readLine()) != null) {
System.out.println("errorS
str_errorStream += line + System.getProperty("line.s
}
Integer iExitVal = pExecution.waitFor();
return iExitVal;
}
are you sure thats where it is hanging?
ASKER
When I use the debugger that is where it sits for ages unless i manually terminate it
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
I tried the following to call the StreamGobbler running the same script:
public static Integer execute(String sCommand) throws InterruptedIOException
{
Integer iExitVal = 0;
try
{
Runtime rShell = Runtime.getRuntime();
Process pExecution = rShell.exec(sCommand);
// Capture any process errors
StreamGobbler sgError = new StreamGobbler(pExecution.g etErrorStr eam(), "APP");
// Capture any process output
StreamGobbler sgOutput = new StreamGobbler(pExecution.g etInputStr eam(), "OUTPUT");
sgError.start();
sgOutput.start();
iExitVal = pExecution.waitFor();
System.out.println("Exit value: " + iExitVal);
}
catch (Exception ex)
{
throw new InterruptedIOException(":C ommandRunn er: " + ex.getMessage());
}
return iExitVal;
}
And now it freezes here: iExitVal = pExecution.waitFor();
I know the script works and quits out of the ftp because it works on the commandline to call it, and the weirdest thing is it sometimes works when I run it my old way & sometimes not. Makes me think it has to do with a buffer size, or something weird.
Also I do need a way to get the output in the calling class, so I'm not sure, even if this worked, if it would meet my needs to have it execute in a separate thread.
public static Integer execute(String sCommand) throws InterruptedIOException
{
Integer iExitVal = 0;
try
{
Runtime rShell = Runtime.getRuntime();
Process pExecution = rShell.exec(sCommand);
// Capture any process errors
StreamGobbler sgError = new StreamGobbler(pExecution.g
// Capture any process output
StreamGobbler sgOutput = new StreamGobbler(pExecution.g
sgError.start();
sgOutput.start();
iExitVal = pExecution.waitFor();
System.out.println("Exit value: " + iExitVal);
}
catch (Exception ex)
{
throw new InterruptedIOException(":C
}
return iExitVal;
}
And now it freezes here: iExitVal = pExecution.waitFor();
I know the script works and quits out of the ftp because it works on the commandline to call it, and the weirdest thing is it sometimes works when I run it my old way & sometimes not. Makes me think it has to do with a buffer size, or something weird.
Also I do need a way to get the output in the calling class, so I'm not sure, even if this worked, if it would meet my needs to have it execute in a separate thread.
what is the value of sCommand?
ASKER
Woops - I take that back. It is working with the StreamGobbler, forgot to change a setting.
Is there a good way I can adapt this so I can get a String with the output and a String with the errors into the class that calls the execute(String sCommand) method I posted above?
Thanks,
Courtenay
Is there a good way I can adapt this so I can get a String with the output and a String with the errors into the class that calls the execute(String sCommand) method I posted above?
Thanks,
Courtenay
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks so much this solved the problem!
and get rid of the br.ready() call from the loop condition
http://helpdesk.objects.com.au/java/runtime-exec-locks-up
worth also checking that the process isn't writing to stderr as well