?
Solved

java ftp program is hangs ...

Posted on 2005-03-30
15
Medium Priority
?
543 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Get real performance insights from real users

Key features:
- Total Pages Views and Load times
- Top Pages Viewed and Load Times
- Real Time Site Page Build Performance
- Users’ Browser and Platform Performance
- Geographic User Breakdown
- And more

 
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

Industry Leaders: 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!

Question has a verified solution.

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

Introduction This article is the second of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers the basic installation and configuration of the test automation tools used by…
Java functions are among the best things for programmers to work with as Java sites can be very easy to read and prepare. Java especially simplifies many processes in the coding industry as it helps integrate many forms of technology and different d…
Viewers will learn about the different types of variables in Java and how to declare them. Decide the type of variable desired: Put the keyword corresponding to the type of variable in front of the variable name: Use the equal sign to assign a v…
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.
Suggested Courses
Course of the Month15 days, 8 hours left to enroll

741 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