[Webinar] Streamline your web hosting managementRegister Today

x
?
Solved

java ftp program is hangs ...

Posted on 2005-03-30
15
Medium Priority
?
554 Views
Last Modified: 2012-06-27
Hi All,

I am trying to use java to ftp a file from my local pc to an ftp server. Once the connection is established, my program
hangs. Any idea or help will be nice.  Thanks - Inayat.

Here is where it is ... h(b)anging on me ...

C:\Inayat\JavaPractice>java ftp_utility
UserName: bbb\ijilani
LOGIN Successful
RD: \ftptest1
... ... ... ... ... ... ... ....
...(nothing happens)...
... ... ... ... ... ... ... ....

Here is my code....

==============================================

import java.io.*;
import sun.net.ftp.*;

import java.util.*;
import java.net.*;

import java.lang.*;                        

public class ftp_utility2 {

public static void main (String args[]) throws Exception {

String       host = "ftpun01";
int       port = 21;
String       username = "bbb\\ijilani";
String       password = "union28";

String       sourceFile = "HelloCom.java";

String       remoteDirectory = "\\ftptest1";

   put1(host, port, username, password, sourceFile, remoteDirectory);

}

public static void put1(
    String host,                  
    int port,                              
    String username,
    String password,
    String sourceFile,
    String remoteDirectory ) throws Exception
    {

     System.out.println("UserName: " + username);

     // Modify system properties - 03/16/2005
     Properties sysProperties = System.getProperties();
     // Specify proxy settings
     sysProperties.put("proxyHost", "app-proxy");
     sysProperties.put("proxySet",  "true");
     sysProperties.put("proxyPort", "8080");
     System.setProperties(sysProperties);

        FtpClient ftpClient = null;

        try
        {

          ftpClient = new FtpClient(host, port);                  

          ftpClient.login(username, password);
          System.out.println("LOGIN Successful");
          ftpClient.cd(remoteDirectory);
          System.out.println("RD: " + remoteDirectory);

          ftpClient.put(sourceFile);
         }
         finally
         {
          if (ftpClient != null)
          {
            ftpClient.closeServer();
          }
        }
    }
}

==============================================
0
Comment
Question by:Inayat081501
  • 8
  • 6
15 Comments
 
LVL 2

Expert Comment

by:ThummalaRaghuveer
ID: 13663155
Comment out the line ftpClient.closeServer()  in finally block it works
0
 
LVL 15

Expert Comment

by:aozarov
ID: 13664375
commenting out ftpClient.closeServer is fine if your application terminates after that (as in your example) but if you keep running after that
then not closing the connection might lead to resource leak.
I would recommend you to use different FTP java library instead of using the undocumented/unsafe sun libraries.
You can look at: http://www.javaworld.com/javaworld/jw-04-2003/jw-0404-ftp_p.html  for a list of libraries.
I personally recommend http://akarta.apache.org/commons/net/  (I use it myself)
0
 

Author Comment

by:Inayat081501
ID: 13665186
ThummalaRaghuveer/azarov,

I commented out the line  ftpClient.closeServer()  in the finally block, recompiled and tried. But the file transfer did not take place. Any ideas?

azarov, thanks for your input. But once I have this code working, my objective is to compile it into the oracle database
using its internal Sun JVM and call it using a stored procedure. So I don't know how the other libraries will work.

- Inayat

0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
LVL 15

Expert Comment

by:aozarov
ID: 13665664
Because you are running in environment that keeps the JVM alive for a long time then I would not recommend you to not close the connection.
I don't understand why this method hangs (bug?), and I still advice you to use some other library. I think all you need is to add that library to Oracle JVM classpath though I am not sure about it.
0
 
LVL 15

Accepted Solution

by:
aozarov earned 400 total points
ID: 13681289
Change this lines and it will work for you:

From:
          ftpClient.put(sourceFile);
         }
         finally
         {
          if (ftpClient != null)
          {
            ftpClient.closeServer();
          }

to
          OutputStream output = ftpClient.put(sourceFile);
              File file = new File(sourceFile);
              byte bytes[] = new byte[(int) file.length()];
              FileInputStream input = new FileInputStream(file);
              input.read(bytes);
              input.close();
              output.write(bytes);
              output.close();
         }
         finally
         {
          if (ftpClient != null)
          {
            ftpClient.closeServer();
          }
0
 

Author Comment

by:Inayat081501
ID: 13698371
hi aozarov:

Thank you for your help. I will give you all the points. I am not sure if this site will allow to add another comments once I accept your answer.

Would you mind helping me with fixing the code below? It is doing the opposite - i.e., it does a get function - connects to the ftp server and gets the file and puts it into a folder on the database server. Please excuse my Java knowledge. By the way, I am compiling this code using Oracle's JVM that is integrated into the database.

I get this error when I compile:

JAVA SOURCE SA.my_ftp_get
On line:  0
my_ftp_get:26: Incompatible type for constructor. Can't convert java.lang.String to java.io.OutputStream.

And this is the code,

=========================
CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED "my_ftp_get" AS
import java.io.*;
import sun.net.ftp.*;
import oracle.sql.*;
public class my_ftp_get {
  public static void get(
    String host,
    NUMBER port,
    String username,
    String password,
    String sourceFile) throws Exception {
    FtpClient ftpClient = null;
    try {
      int lastSlash = sourceFile.lastIndexOf('/');
      String file = sourceFile.substring(lastSlash + 1);
      String directory = sourceFile.substring(0, lastSlash);
    /*// Turn on proxy support when requested.
      if (proxyHost != null && proxyHost.trim().length() > 0 && proxyPort !=null) {
        System.getProperties().put("proxySet", "true");
        System.getProperties().put("proxyHost", proxyHost.trim());
        System.getProperties().put("proxyPort", proxyPort.stringValue());
      }*/
      ftpClient = new FtpClient(host, port.intValue());
      ftpClient.login(username, password);
      ftpClient.cd(directory);
      InputStream is = ftpClient.get(file);
      BufferedOutputStream os = new BufferedOutputStream("F:/clfy/infile/getTest.txt");
      int length;
      while((length = is.read()) != -1) {
        os.write(length);
      }
      is.close();
      os.close();
    } finally {
      if (ftpClient != null) {
        ftpClient.closeServer();
      }
    }
  }
}
/
==================================
0
 
LVL 15

Expert Comment

by:aozarov
ID: 13699064
You can continue a thread even after giving the points.
Change the code:

BufferedOutputStream os = new BufferedOutputStream("F:/clfy/infile/getTest.txt");
to
BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream("F:/clfy/infile/getTest.txt"))

Also do you really mean:
 NUMBER port, ...
or you meant
 int port, ...
If so then also change:
ftpClient = new FtpClient(host, port.intValue());
to
ftpClient = new FtpClient(host, port);
0
 

Author Comment

by:Inayat081501
ID: 13700171
Thank you aozarov,

NUMBER port; is OK coz I am compiling with the JVM inside the oracle database, and I have import oracle.sql.*; at the top of my code. But you are right, if I compile it using JDK, then I have to change it to int port;

I made the first change to the code as you suggested, but I now get this one when I compile:

==============================================
 my_ftp_get:25: Incompatible type for declaration. Can't convert
 sun.net.TelnetInputStream to java.io.BufferedInputStream.

 my_ftp_get:31: Undefined variable or class name: is
 my_ftp_get:34: Undefined variable or class name: is
 Info: 3 errors
==============================================

Here is my code as it stands now,

==============================================
CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED "my_ftp_get" AS
import java.io.*;
import sun.net.ftp.*;
import oracle.sql.*;
public class my_ftp_get {
  public static void get(
    String host,
    NUMBER port,
    String username,
    String password,
    String sourceFile) throws Exception {
    FtpClient ftpClient = null;
    try {
      int lastSlash = sourceFile.lastIndexOf('/');
      String file = sourceFile.substring(lastSlash + 1);
      String directory = sourceFile.substring(0, lastSlash);
    /*// Turn on proxy support when requested.
      if (proxyHost != null && proxyHost.trim().length() > 0 && proxyPort !=null) {
        System.getProperties().put("proxySet", "true");
        System.getProperties().put("proxyHost", proxyHost.trim());
        System.getProperties().put("proxyPort", proxyPort.stringValue());
      }*/
      ftpClient = new FtpClient(host, port.intValue());
      ftpClient.login(username, password);
      ftpClient.cd(directory);
      BufferedInputStream in = ftpClient.get(file);
      /*BufferedOutputStream os = new BufferedOutputStream("F:/clfy/infile/getTest.txt");*/

 BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream("F:/clfy/infile/getTest.txt"));

      int length;
      while((length = is.read()) != -1) {
        os.write(length);
      }
      is.close();
      os.close();
    } finally {
      if (ftpClient != null) {
        ftpClient.closeServer();
      }
    }
  }
}
/
==============================================
0
 
LVL 15

Expert Comment

by:aozarov
ID: 13700312
change:
BufferedInputStream in = ftpClient.get(file);

to:
InputStream in

Any reason you want to wrap it in bufferdInputStream?
I don't think there is a reason, but if I am wrong then you can do (instead of the above suggestion):
BufferedInputStream in = new BufferedInputStream(ftpClient.get(file));
0
 

Author Comment

by:Inayat081501
ID: 13700596
Hi aozarov:

I got it. It worked. I don't have any real reason for wrapping it in Buffered class. I first wanted to fix the error and then go back and do some reading.

One last question, when do I use BufferedInputStream and when do I use InputStream? I know I will have to tutor myself on the basics of Java programming. But I just want a brief answer for now.

Thanks for your help - Inayat

0
 
LVL 15

Expert Comment

by:aozarov
ID: 13700705
BufferedInputStream will do more efficient reading from the source by applying buffering.
What that means is that when you call in.read() which basically "reads" only one byte the BufferedInputStream will actually read more (in one chunk) and will cache
the rest for your subsequent read calls.
That is the preferred way in most of the cases as long as you understand the underlining source (File, Socket, ...).
In this case you get TelnetInputStream (which you don't know much about -> undocumented class) that class might already buffer input (so you do double work), but
also the implication of wrapping it with BufferedInputStream is unknown. This is why I prefer not to wrap it, though it is probably going to be ok.
0
 

Author Comment

by:Inayat081501
ID: 13700784
aozarov:

But in my program I have this:

 InputStream is = ftpClient.get(file);
 BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream("F:/clfy/infile/getTest2.txt"));

As you see, the input is not buffered, but the output is. Will this be a real inconsistency or will it cause any problem under certain conditions?

Thanks - Inayat
0
 
LVL 15

Expert Comment

by:aozarov
ID: 13700963
>> BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream("F:/clfy/infile/getTest2.txt"));
This goes to a local file (different destination)

>> InputStream is = ftpClient.get(file);
This gets it as TelnetInputStream

Those are two different type of sinks.
I don't think it is inconsistent, but as I said you can always try:
BufferedInputStream is = new BufferedInputStream(ftpClient.get(file)); // which is a bit different from what you did back there.
Personaly, I would not do it.
0
 

Author Comment

by:Inayat081501
ID: 13701475
Thank you, aozarov. :)
0
 
LVL 15

Expert Comment

by:aozarov
ID: 13701596
:-)
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say 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

INTRODUCTION Working with files is a moderately common task in Java.  For most projects hard coding the file names, using parameters in configuration files, or using command-line arguments is sufficient.   However, when your application has vi…
In this post we will learn different types of Android Layout and some basics of an Android App.
Viewers will learn about arithmetic and Boolean expressions in Java and the logical operators used to create Boolean expressions. We will cover the symbols used for arithmetic expressions and define each logical operator and how to use them in Boole…
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …
Suggested Courses
Course of the Month8 days, 21 hours left to enroll

590 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