I am trying to make a monitoring application for a FTP server using FTP4J(referred to as client in the code example).
It connects to a FTP, logs in, creates a file locally, uploads file, downloads file, validates the files are the same, cleans up files on ftp and locally and disconnects.
All this is already made but my question is how do I best log what has happened and break when an error is detected?
The simple solution I could think of was to make a Boolean that shows if previous steps where successful and only do next step if they where.
StringBuilder sb = new StringBuilder();
boolean noError = true;
// Connect to FTP
try {
client.connect(hostname, port);
} catch (Exception e) {
noError = false;
sb.append("failed to connect<br>");
}
//Logging in to FTP
if(noError) {
try {
client.login(username, password);
} catch (Exception e) {
noError = false;
sb.append("failed to login<br>");
}
}
...
// Close connection
if(client.isConnected()) {
try {
client.disconnect(true);
} catch (Exception e) {
sb.append("failed to disconnect<br>");
}
}
another solution I could think of was nested try/catch but that looked even worse, is there a better way of doing this?
The solution is simple: don't catch the exception. As soon as an exception is thrown and is not caught, the whole process will stop. Or catch it but transform it into your own exception with the appropriate error message, and throw this exception.
Side note: you should use a boolean and not a Boolean to store a non-nullable boolean value.
StringBuilder sb = new StringBuilder();
Boolean noError = true;
// Connect to FTP
try {
client.connect(hostname, port);
client.login(username, password);
} catch (ConnectException ce) {
sb.append("Couldn't connect: ");
sb.append(ce.getMessage);
} catch (LoginException le) {
sb.append("Couldn't login: ");
sb.append(le.getMessage);
} finally {
if(client.isConnected()) {
try {
client.disconnect(true);
} catch (Exception e) {
sb.append("failed to disconnect<br>");
}
}
Related
i have created mqtt connection suscribeData() as follows to receive data 24/7 from multiple devices
#RequestMapping("/suscribe")
#ResponseBody
public String suscribeData(){
connOpt= new MqttConnectOptions();
connOptPublish= new MqttConnectOptions();
boolean result=false;
int retry=0;
while(!result){
try{
result=initializeMqTTParameters(retry);
retry++;
if(!result){
Thread.sleep(1000);
}
}catch(Exception ex){
}
if(retry>10){
return "mqtterror";
}
}
suscribeReceivedData("DATA/#",2);
Calendar cal=TimeZoneJu.getCalenderInstance();
ModemOnlineStatus status=new ModemOnlineStatus();
status.setActiondate(cal.getTime());
status.setActiontime(cal.getTime());
status.setModemid("mqttreceive");
status.setRemark("online");
status.setStatus(true);
try{
service.checkAndInsertModemStatus(true, status);
}catch(Exception ex1){
}
return "ok";
}
checkAndInsertModemStatus() function is used to save the online offline state of connection i check the connection from another url with cronjobs.
and following is my initializeMqTTParameters
public boolean initializeMqTTParameters(int retry){
String clientID = M2MIO_THING;
connOpt = new MqttConnectOptions();
connOpt.setCleanSession(false);
connOpt.setUserName(M2MIO_USERNAME);
connOpt.setPassword(M2MIO_PASSWORD_MD5.toCharArray());
connOpt.setWill("WILL/mqttreceive", "mqttreceive:disconnected".getBytes(), 2, true);
try {
if(retry%2==0){
MQTTReceive.myClient = new MqttClient(BROKER_URL, "mqtt_virtual_received_sus_1");
}else{
MQTTReceive.myClient = new MqttClient(BROKER_URL, "mqtt_virtual_received_sus_2");
}
MQTTReceive.myClient.setCallback(this);
MQTTReceive.myClient.connect(connOpt);
} catch (MqttException e) {
System.out.println(e.getMessage());
return false;
}
return true;
}
on connectionLost i am trying update status in database and try reconnect
#Override
public void connectionLost(Throwable ex) {
System.out.println("Mqtt Received Connection Lost"+ex.getMessage());
Calendar cal=TimeZoneJu.getCalenderInstance();
ModemOnlineStatus status=new ModemOnlineStatus();
status.setActiondate(cal.getTime());
status.setActiontime(cal.getTime());
status.setModemid("mqttreceive");
status.setRemark("offline");
status.setStatus(false);
try{
service.updateModemStatus(false, status);
}catch(Exception ex1){
}
suscribeData();
}
and from the above code i got my connections were online but i stopped receving data on subscribed topics so another method i tried that i am checking connection status from another function from database like i set the connection online when i connect and offline on connectionLost and i can call to connect(suscribeData()) but it leaves me with too many open files in tomcat within few days how can i make sure previous open files should close
like System.exit(1) on connectionLost() so that current process will close and i will reconnect after checking the status
or please suggest me if there is any other logic i can use to maintain my connections
Your catch block does nothing in method connectionLost.. it should do something like this:
catch (Exception e)
{
e.printStackTrace();
System.exit(1);
}
You should also disconnect your MQTT client whenever not required..i.e processing over:
myClient.disconnect();
I have read a half dozen threads regarding this and I'm no where closer to a solution. No matter what I change I get ftp return code 500 "The command was not accepted and the requested action did not take place." and I'm not sure how to debug that.
This is my site and I can connect with CoreFTP and read and write, so it does not seem to be a permissions issue. I've tried two different accounts, with this code and CoreFTP. One writes to the root and another is pointed to an "image_in" folder.
imageData is a byte array with a length of 166578 and stream has the same length after the InputStream call. storeFile() always returns false with a return code of 500.
One thread implied enterLocalPassiveMode() and enterRemotePassiveMode() were the culprits, but I have tried this code both with and without those lines and still I get a 500 return code.
Any idea what I'm missing?
Greg
class ImageUploadTask extends AsyncTask <Void, Void, String>{
#Override
protected String doInBackground(Void... unsued) {
try {
boolean status = false;
try {
FTPClient mFtpClient = new FTPClient();
String ip = "my domain dot com";
String userName = "ftp79815757-0";
String pass = "my password";
mFtpClient.connect(InetAddress.getByName(ip));
mFtpClient.login(userName, pass);
int reply = mFtpClient.getReplyCode();
if (FTPReply.isPositiveCompletion(reply)) {
//one thread said this would do the trick
mFtpClient.enterLocalPassiveMode();
mFtpClient.enterRemotePassiveMode();
InputStream stream = new ByteArrayInputStream(imageData);
mFtpClient.changeWorkingDirectory("/images_in");
String currdir = mFtpClient.printWorkingDirectory();
if (!mFtpClient.storeFile("remoteName.jpg", stream)) {
Log.e("FTPUpload", String.valueOf(mFtpClient.getReplyCode()));
}
stream.close();
mFtpClient.disconnect();
}
else {
Log.e("FTPConnected", String.valueOf(reply));
}
} catch (SocketException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
} catch (Exception e) {
if (dialog.isShowing())
dialog.dismiss();
Toast.makeText(getApplicationContext(),
"Error",
Toast.LENGTH_LONG).show();
Log.e(e.getClass().getName(), e.getMessage(), e);
return null;
}
}
You forgot to set file type
mFtpClient.setFileType(org.apache.commons.net.ftp.FTP.BINARY_FILE_TYPE);
If it still doesn't work then you have following options:
If you insist on using Apache FTP Client then follow this example
Or you could try this example
The second example worked in my case.
You need to use: enterLocalPassiveMode
mFtpClient.enterLocalPassiveMode();
If you then do other operations, you might have to go back active with enterLocalActiveMode.
I am executing the below code to pull the .gz file from a URL to a local directory.For small files it goes through fine but for large files it downloads only part of it but does not fail. I get to know the error only when I try to UNZIP it. Can someone throw any light on this on what could be the reason.
public boolean downloadFilemethod(String filePath, String url, String
decompressFilePath) {
if (StringUtils.isNotBlank(filePath) && StringUtils.isNotBlank(url)) {
try {
FileUtils.copyURLToFile(new URL(url), new File(SRC_BASE_DIR + filePath),
TIMEOUT_IN_MILLIS, TIMEOUT_IN_MILLIS);
ingestmethod(filePath,decompressFilePath);
downloadSuccess = true;
}
catch (MalformedURLException e)
{ LOG.warn("some message"); }
catch (IOException e)
{ LOG.warn("some message);
}
}
return downloadSuccess
}
What is the correct procedure to follow when an exception is thrown on an FTP Client in Java i.e. does the FTP session stay active or does it automatically 'quit' when an exception is thrown?
So I have this:
public boolean testHost(Host host, String path) {
boolean success = false;
try {
FTPClient ftp = new FTPClient();
ftp.setRemoteHost(host.getIpaddress());
ftp.connect();
ftp.login(host.getUsername(), host.getPassword());
success = ftp.connected();
if (success && path != null){
ftp.chdir(path);
}
ftp.quit();
} catch (UnknownHostException e) {
LOG.info("Host IPAddress cannot be reached on " + host.getIpaddress());
success = false;
} catch (IOException e) {
e.printStackTrace();
success = false;
} catch (FTPException e) {
success = false;
}
return success;
}
The quit command doesnt get hit when any of the exceptions get called - is this a problem? Could there potentially be 100's of active connections open to the FTP Client if this method keeps getting hit? Or am I worrying about nothing?
Move your ftp.quit() statement so it is just above the return statement
Like this:
public boolean testHost(Host host, String path) {
boolean success = false;
try {
FTPClient ftp = new FTPClient();
ftp.setRemoteHost(host.getIpaddress());
ftp.connect();
ftp.login(host.getUsername(), host.getPassword());
success = ftp.connected();
if (success && path != null){
ftp.chdir(path);
}
} catch (UnknownHostException e) {
LOG.info("Host IPAddress cannot be reached on " + host.getIpaddress());
success = false;
} catch (IOException e) {
e.printStackTrace();
success = false;
} catch (FTPException e) {
success = false;
}
ftp.quit();
return success;
}
Since none of your catches terminate the method, execution will continue to the ftp.quit() statement and finally return with the success result.
Optionally, you can use the finally clause at the end of the try and put the ftp.quit() statement in that.
AFAIK the choice is preferential.
I'm trying to make a call that might throw an exception due to server being down.
this is what i want to accomplish:
Server server = serverQueue.poll();
try {
if (server==null){return null}
server.makeConnection();
} catch (Exception e) {
// try another server
server = serverQueue.poll();
// now return to try block?
}
So i have 5 servers and maybe in later stage i'll add some more. So i want to connect to
anyone of them in this manner. How can i return to the try block? is there anything such as a statement like this below in java?:
Server server = serverQueue.poll();
outerBlock:
try {
if (server==null){return null}
server.makeConnection();
} catch (Exception e) {
// try another server
server = serverQueue.poll();
continue outerBlock;
}
Basically a loop:
Server server = serverQueue.poll();
boolean connected = false;
while (!connected) {
if (server == null) {
return null;
}
try {
server.makeConnection();
connected = true;
} catch (Exception e) {
// Presumably log something here, for management info
// try another server
server = serverQueue.poll();
}
}
Or to avoid the duplication:
Server server;
boolean connected = false;
while (!connected) {
server = serverQueue.poll();
if (server == null) {
return null;
}
try {
server.makeConnection();
connected = true;
} catch (Exception e) {
// Presumably log something here, for management info
}
}
You might consider isolating the "find a server" part of that into its own function.
You need to put your try block inside a simple loop, either while or for.
ou can use a for loop
Server server;
for(int i=0;i<=numberOFServers-1;i++){
server = serverQueue.poll();
try {
if (server==null){return null}
server.makeConnection();
} catch (Exception e) {
System.out.println("Server : " +i+ " could not establish connection");
}
}