Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

Java InputStream hanging when executing a script for ftp

Posted on 2009-12-22
10
Medium Priority
?
749 Views
Last Modified: 2013-12-29
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(pExecution.getInputStream()));
            line = "";
            str_inputStream = "";
            while ((line = br.readLine()) != null && br.ready()) {
                  System.out.println("inputStream1: " + line);
                  str_inputStream += line + System.getProperty("line.separator");
            }

            // Capture any process output
            br = new BufferedReader(new InputStreamReader(pExecution.getInputStream()));
            line = "";
            str_inputStream = "";
            while ((line = br.readLine()) != null && br.ready()) {
                  System.out.println("inputStream2: " + line);
                  str_inputStream += line + System.getProperty("line.separator");
            }

                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

0
Comment
Question by:courtenayt
  • 5
  • 5
10 Comments
 
LVL 92

Expert Comment

by:objects
ID: 26108550
you should only have one loop to read the output
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
0
 
LVL 1

Author Comment

by:courtenayt
ID: 26108761
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(pExecution.getInputStream()));
            while ((line = br1.readLine()) != null) {
                  System.out.println("inputStream1: " + line);
                  str_inputStream += line + System.getProperty("line.separator");
            }
            
            // Capture any process errors
            line = null;
            BufferedReader br2 = new BufferedReader(new InputStreamReader(pExecution.getErrorStream()));
            while ((line = br2.readLine()) != null) {
                  System.out.println("errorStream1: " + line);
                  str_errorStream += line + System.getProperty("line.separator");
            }
                        
            Integer iExitVal = pExecution.waitFor();
            return iExitVal;
      }
0
 
LVL 92

Expert Comment

by:objects
ID: 26108790
are you sure thats where it is hanging?
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 1

Author Comment

by:courtenayt
ID: 26108797
When I use the debugger that is where it sits for ages unless i manually terminate it
0
 
LVL 92

Accepted Solution

by:
objects earned 2000 total points
ID: 26108821
try using the class in the link I posted above to handle the stream reading from a different thread
0
 
LVL 1

Author Comment

by:courtenayt
ID: 26108913
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.getErrorStream(), "APP");
                  // Capture any process output
                  StreamGobbler sgOutput = new StreamGobbler(pExecution.getInputStream(), "OUTPUT");
                  sgError.start();
                  sgOutput.start();
                  
                  iExitVal = pExecution.waitFor();
                  
                  System.out.println("Exit value: " + iExitVal);
            }
            catch (Exception ex)
            {
                  throw new InterruptedIOException(":CommandRunner: " + 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.
0
 
LVL 92

Expert Comment

by:objects
ID: 26108925
what is the value of sCommand?
0
 
LVL 1

Author Comment

by:courtenayt
ID: 26108961
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
0
 
LVL 92

Assisted Solution

by:objects
objects earned 2000 total points
ID: 26108974
store the returned string as a member var of the StreamGobbler class, and add a method that returns it. You can then call it to get the string when waitFor() is done

0
 
LVL 1

Author Closing Comment

by:courtenayt
ID: 31669564
Thanks so much this solved the problem!
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Understanding FTPS File transfer is a common requirement in most Enterprises. While there are numerous ways to get a file from Point A to Point B over a network, perhaps the most common method still in use is FTP – File Transfer Protocol. FTP is …
In this post we will learn how to make Android Gesture Tutorial and give different functionality whenever a user Touch or Scroll android screen.
Viewers learn how to read error messages and identify possible mistakes that could cause hours of frustration. Coding is as much about debugging your code as it is about writing it. Define Error Message: Line Numbers: Type of Error: Break Down…
In this brief tutorial Pawel from AdRem Software explains how you can quickly find out which services are running on your network, or what are the IP addresses of servers responsible for each service. Software used is freeware NetCrunch Tools (https…
Suggested Courses

569 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question