Apache Commons Net FTP does not throw any exception on wrong credentials - java

I just managed to upload some files to an FTP server using Apache Commons Net FTP. When I use everything as it should be it works fine, I mean, the file uploading is working, but when I use, for example, a wrong password for the FTP account, obviously the files don't get uploaded to the server, but I don't get an error message either. In other words: I don't know how to show the error. I tried to show with a toast the e.getMessage() from the Exception but nothing is shown. Is there any documentation that would help me? Or am I missing something you could help me with? thank you!
This is my code:
#Override
protected Void doInBackground(Void... voids) {
FTPClient ftpClient=new FTPClient();
try {
ftpClient.connect(fserver);
ftpClient.login(fusername,fpassword);
ftpClient.enterLocalPassiveMode();
dirArch = new ArrayList<>();
for (int k=0;k<adapter.getSelected().size();k++){
dirArch.add(adapter.getSelected().get(k).getArch());
}
for (String archTXT : dirArch){
File fileX =new File(stringFolder,archTXT);
InputStream inputStream=new FileInputStream(fileX);
ftpClient.storeFile(archTXT,inputStream);
inputStream.close();
pbPorc=pbPorc+pbSum;
pb1.setProgress(pbPorc);
pb2.setProgress(pbPorc);
}
ftpClient.logout();
ftpClient.disconnect();
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(ExportTracks.this,e.getMessage(),Toast.LENGTH_LONG).show();
}
return null;
}

Your error handling is wrong.
The FTPClient.login does not throw an exception, when the credentials are wrong. It returns a false. You do not test for that. Your code carries on, trying to work with not authorized session instead, all of which will obviously fail too.
But as the same is true for FTPClient.storeFile, which also just returns false, your code basically does not notice any errors.

Related

Can't fetch expanded URL from a given shortened URL

I am given a shortened url and I want to get the expanded form. The below java function is used to achieve this.
public String expand(String shortenedUrl){
URL url = null;
try {
url = new URL(shortenedUrl);
} catch (MalformedURLException e) {
e.printStackTrace();
}
// open connection
HttpURLConnection httpURLConnection = null;
try {
httpURLConnection = (HttpURLConnection) url.openConnection(Proxy.NO_PROXY);
} catch (IOException e) {
e.printStackTrace();
}
// stop following browser redirect
httpURLConnection.setInstanceFollowRedirects(false);
// extract location header containing the actual destination URL
String expandedURL = httpURLConnection.getHeaderField("Location");
httpURLConnection.disconnect();
return expandedURL;
}
The code works fine in Eclipse but the same doesn't work in android.
String expandedURL = httpURLConnection.getHeaderField("Location");
The above line throws java.lang.RuntimeException: Unable to start activity ComponentInfo. And the error is pointed to the above line. If I remove the above line no error is encountered. Even I am not able to use getResponseCode() function.
int status = 0;
try {
status = httpURLConnection.getResponseCode();
} catch (IOException e) {
e.printStackTrace();
}
This piece of code also has the same problem. works in eclipse but not in android.
Any kind of help will be greatly appreciated.
Edit: The code using above function is,
ExpandUrl expandUrl = new ExpandUrl();
String expandedUrl = expandUrl.expand(shortenedUrl);
Note: The function expand is defined inside the class ExpandUrl.
Well, the code works in Eclipse but not in android. The reason is that you are doing it in Main thread and blocking it. Android wouldn't allow you to do so and throw runtime error.
I have tried to implement your code using AsyncTask in android. It works fine.
Give it a try.
To know more about AsyncTask follow: Android Documentation on AsyncTask
Good Luck!

Google Drive SDk Connection reset by peer

I am using following code to load public shared images from google drive to android app, but sometimes I got:
javax.net.ssl.SSLException: Read error: ssl=0x1d9ed0: I/O error during system call, Connection reset by peer
Why google drive is closing connection before I download image? This is happening randomly, but quite often. Does someone collide with such problem?
public static InputStream getStream(String url)
{
InputStream is = null;
try
{
is = new URL(url).openConnection().getInputStream();
} catch (MalformedURLException e)
{
L.e(e.toString());
} catch (IOException e)
{
L.e(e.toString());
}
return is;
}
For bitmap loading I use simple code:
BitmapFactory.decodeStream(stream, null, null);
It could be that you are affected by the following: The URL that you get from the file's metadata is short lived. If you are saving that URL to use later it won't work because it could be that the URL gets invalidated.
To do this you have to fetch the image metadata every time to get the new downloadURL.
We are working on providing non expirable URLs in the future.

FtpClient storeFile always return False

Please figure this out. The code runs properly without any exception.
try
{
FTPClient ftp = new FTPClient();
ftp.connect(server);
if(!ftp.login(username, password))
{
ftp.logout();
return false;
}
int reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply))
{
ftp.disconnect();
return false;
}
InputStream in = new FileInputStream(localfile);
ftp.setFileType(ftp.BINARY_FILE_TYPE, ftp.BINARY_FILE_TYPE);
ftp.setFileTransferMode(ftp.BINARY_FILE_TYPE);
Store = ftp.storeFile(destinationfile, in);
in.close();
ftp.logout();
ftp.disconnect();
}
catch (Exception ex)
{
ex.printStackTrace();
return false;
}
return Store;
Butm the return statement always returns false and the file is not uploaded on the server. Someone please help on this.
For your information, I am in an office network. ---> do we need to add any proxies?
File file = new File("C:\\Users\\sg0214273\\Desktop\\seagate\\seagate.txt");
FileInputStream input = new FileInputStream(file);
client.setFileType(FTP.BINARY_FILE_TYPE);
if (!client.storeFile(file.getName(), input)) {
System.out.println("upload failed!");
}
reply = client.getReplyCode();
if(!FTPReply.isPositiveCompletion(reply)) {
System.out.println("upload failed!");
}
Login success...
230 User ******** logged in.
upload failed!-----> is form boolean return value of storefile
upload failed!---------> is from replycode...
Logout from FTP server...
Please help out.
The exact failure message can be found by calling FtpClient#getReplyCode(). From that page (my emphasis):
Immediately after connecting is the only real time you need to check
the reply code (because connect is of type void). The convention for
all the FTP command methods in FTPClient is such that they either
return a boolean value or some other value. The boolean methods return
true on a successful completion reply from the FTP server and false on
a reply resulting in an error condition or failure. The methods
returning a value other than boolean return a value containing the
higher level data produced by the FTP command, or null if a reply
resulted in an error condition or failure. If you want to access the
exact FTP reply code causing a success or failure, you must call
getReplyCode after a success or failure.
To see what a return code means, you can see Wikipedia: List of FTP server return codes.
Topic is quite old but maybe I will help to any other. I compared what FileZilla sends to FTP server and my program did. I needed to use ftp.enterLocalPassiveMode() to make it work, ftp.pasv() no good :)
And for debugging is better to use getReplyString() than only getReplyCode().
Modify you code to switch to passive mode before you transfer the file with storeFile() as follows:
...
ftp.setFileTransferMode(ftp.BINARY_FILE_TYPE);
ftp.enterLocalPassiveMode();//Switch to passive mode
Store = ftp.storeFile(destinationfile, in);
in.close();
...
Hope that helps.
please add the apache library for this code
this are the impoted class
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
rest import class is from java.io or java.net
public boolean upload(String server,String username,String password,File localfile ){
boolean Store=false;
try{
FTPClient ftp = new FTPClient();
// ftp.connect(server);
/* you can use either code which is written above above or below code as ftp port 20 is used for the data transfer and port 21 is used for command and controlls */
ftp.connect(InetAddress.getByName(server),21);
//here 'server' is your domain name of ftp server or url
if(!ftp.login(username, password))
{
ftp.logout();
return false;
}
ftp.sendNoOp();//used so server timeout exception will not rise
int reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply))
{
ftp.disconnect();
return false;
}
ftp.enterLocalPassiveMode(); /* just include this line here and your code will work fine */
InputStream in = new FileInputStream(localfile);
// ftp.setFileType(ftp.BINARY_FILE_TYPE, ftp.BINARY_FILE_TYPE);
ftp.setFileType(FTP.BINARY_FILE_TYPE);
// ftp.setFileTransferMode(ftp.BINARY_FILE_TYPE);
Store = ftp.storeFile(destinationfile, in);
in.close();
//ftp.disconnect();
//here logout will close the connection for you
ftp.logout();
}
catch (Exception ex)
{
ex.printStackTrace();
return false;
}
return Store;
}
Try to use ftp.enterLocalPassiveMode(); before ftp.storeFile(destinationfile, in);

Android TCP - program crashes

I cant seem to get a simple TCP connection going between a java server application and Android (I have tried both the emulator and the Android Dev Phone 2). I am getting this error on the Emulator "The application Data Receive (process com.mdog.datareceive) has stopped unexpectedly. Please try again."
Forgive me but I am very new to android. So I don't know how to debug it... but I am not trying anything too complex. Eventually I want to try and "consume" the bytes I am receiving in the application. and have the TCP run in the background... but for now simply getting the phone and computer to communicate would be great.
If you can help me that would be awesome.
Code for Android side:
public class Receive extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView tv = new TextView(this);
Socket connectionSocket = null;
byte[] inputHolderByteArray = new byte[5*1024];
/* Connect to Server */
try {
connectionSocket = new Socket("192.168.0.104", 11313);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
/* Send an s to server to start transmission */
try {
PrintWriter out = new PrintWriter(connectionSocket.getOutputStream(), true);
out.print('s');
out.flush();
} catch (IOException e1) {
e1.printStackTrace();
}
/* read server transmission */
try {
connectionSocket.getInputStream().read(inputHolderByteArray);
} catch (IOException e) {
e.printStackTrace();
}
tv.setText("done");
setContentView(tv);
}
}
Each instance of the emulator runs behind a virtual router/firewall service that isolates it from your development machine's network interfaces and settings and from the internet.
The virtual router for each instance manages the 10.0.2/24 network address space — all addresses managed by the router are in the form of 10.0.2., where is a number. Addresses within this space are pre-allocated by the emulator/router.
You have to refer to the development machine with address as: 10.0.2.2 instead of 192.168.0.104 in your case. If you want to refer to another machine in your LAN, then you can Use Network Redirections
http://developer.android.com/guide/developing/tools/emulator.html#emulatornetworking
While superfell is correct that the full stack trace would help diagnose this, based on your code the/a likely problem is that you are breaking up every statement into it separate try/catch blocks. This probably isn't your core issue(my guess is you have a networking issue), but it is what is causing the system to crash.
Typically in Java, statements that are reliant on each other which can throw Exceptions are put in the same try/catch statement. What is most likely happening for you is that the code enters your first try catch block where you try to define a new socket. This fails throwing an exception like 'UnknownHostException'. connectionSocket remains null but the code enters the catch for UnknownHostException. You print the stack trace, but the program doesn't exit. Your code continues on to the following try/catch block where you call
PrintWriter out = new PrintWriter(connectionSocket.getOutputStream(), true);
This causes a NullPointerException. This is a RuntimeException which is not checked and, because it is unchecked, you are not forced to catch it in a catch statement. The exception now causes your VM to crash and causes the error screen you have reported.
So, even though getting the logcat stacktrace will tell us more about your issue, the code you have constructed should be condensed into a single try/catch statement since all code is dependent on the first try/catch completing without error.
Edit:
Try constructing your application like this
public class Receive extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView tv = new TextView(this);
Socket connectionSocket = null;
byte[] inputHolderByteArray = new byte[5*1024];
/* Connect to Server */
try {
connectionSocket = new Socket("192.168.0.104", 11313);
PrintWriter out = new PrintWriter(connectionSocket.getOutputStream(), true);
out.print('s');
out.flush();
connectionSocket.getInputStream().read(inputHolderByteArray);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
tv.setText("done");
setContentView(tv);
}
}
When we say 'get the stacktrace', this means you need to connect to the emulator or device using the android debug bridge (adb) and a program called logcat. If you only have the emulator and no phone connected to your pc, try running the following:
adb logcat *:D
This will output the log information to the terminal. Leave this window open and run your application. You should see a stack trace get printed. Please take the time to get to know logcat and adb.

File Upload with RequestBuilder

I need to upload a file in GWT in the background, ie. not from a visual widget.
For this I've found the RequestBuilder class, but little documentation on how to use it for upload purposes.
The file content I need to upload is 100% plaintext.
My code so far looks like this:
final String filename = UUID.randomUUID().toString() + ".txt";
RequestBuilder rb = new RequestBuilder(RequestBuilder.POST, "http://localhost/upload");
rb.setRequestData(selected.getBody()); // getBody() is plain-text
rb.setHeader("Content-Type", "application/x-www-form-urlencodeddata");
rb.setCallback(new RequestCallback() {
#Override
public void onResponseReceived(Request request, Response response) {
w.setUrl("http://localhost/magic.html?hide=status&open=" + filename);
w.show();
w.maximize();
}
#Override
public void onError(Request request, Throwable exception) {
exception.printStackTrace();
}
});
// Checked Exceptions sucks *sigh*
try {
rb.send();
}
catch (RequestException e) {
e.printStackTrace();
}
I hope someone can give me some pointers towards solving this issue, thanks!
I think it's not possible to upload files to the server without user interaction using JavaScript only. I think it's blocked by the browser, because it would mean anybody could upload any file from your system when you visit a site, which would be a major security problem. I don't know why you would want to do this, but I guess you need to look at another approach to what you are trying to do.
It seems that you can upload files with gears, so in the worst case you could implement something like this with javascript: link text

Categories

Resources