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.
Related
A project source code has a Java method for SQL handling. The method does work, but it uses a questionable workaround: try-catch block at the very end of the method for normal execution. What is the correct way to implement it?
public void run() {
if (running) {
return;
}
running = true;
while(null == Common.server || null == Common.database || !ConnectionsPool.isInitialized()) {
// Wait until the database is set before continuing...
try {
Thread.sleep(1000);
}
catch(Exception ex) {}
}
while(running) {
final Connections cs = ConnectionsPool.getConnections();
Connection c = null;
while(!entries.isEmpty()) {
if (null == c) {
c = cs.getConnection();
}
SQLLogEntry entry = entries.remove();
if (null != entry) {
try {
write(entry, c); //find usages
}
catch (SQLException ex) {
writeLogFile("Could not write entry to SQL", ex);
}
}
}
if (null != c) {
try {
c.commit();
}
catch (SQLException ex) {
writeLogFile("Could commit to SQL", ex);
try {
c.rollback();
}
catch (SQLException ex1) {
}
// log
final StringWriter err = new StringWriter();
ex.printStackTrace(new PrintWriter(err));
EditorTransactionUtil.writeLogFile(err.toString());
// for user
final String msg = "Exception: " + EditorUtil.getErrorMessage(ex.getMessage());
try {
SwingUtilities.invokeAndWait(() -> {
JOptionPane.showMessageDialog(null, msg);
});
}
catch (Throwable ex1) {
}
}
finally {
cs.returnConnection(c);
}
c = null;
}
synchronized(entries) {
try {
entries.wait(1000);
}
catch (InterruptedException ex) {
// This is a workaround to process this loop...
}
}
}
writeLogFile("SQLMsgLogger run loop stopping...");
}
Problems with this code start here.
If(running) return;
running=true;
This is clearly an attempt to make sure that only one thread executes. This is a wrong way to check concurrency. Second tread might kick in right when if check ended, but assignment didn't start yet. You need to use syncronizible interface.
As for the disposed try catch block - as Konrad pointed out it will not be executed without Thread.interrupt() call. It might be dead code left from previous versions.
How I can check if user who sent rest request aborted it using Ctrl-C?
I need to check it on server side because it takes several minutes. If user aborted it then I should stop it.
I tried to write to ServletOutputStream but it doesn't work (I never catch exception):
#Path("test")
public void test(#Context MessageContext mc) {
try {
ServletOutputStream out = mc.getHttpServletResponse().getOutputStream();
out.println("test");
out.flush();
} catch (IOException e) {
System.out.println("Connection is broken");
return;
}
}
Found solution:
private boolean isConnected() {
try {
servletResponse.getOutputStream().println("data");
servletResponse.flushBuffer();
return true;
} catch (IOException e) {
return false;
}
}
private boolean isConnected() {
try {
servletResponse.getOutputStream().println("data");
servletResponse.flushBuffer();
return true;
} catch (IOException e) {
return false;
}
}
I want to check if server application is available. After server is started I want to stop checking until the server changes status. How to do that with my code:
private static final String SERVER_ADDRESS = "192.144.10.10";
private static final int TCP_SERVER_PORT = 8890;
private static boolean connected = false;
static Socket s;
public static void main(String[] args) {
Timer timer = new Timer();
timer.schedule(task, 01, 5001); }
static TimerTask task = new TimerTask() {
#Override
public void run() {
// TODO Auto-generated method stub
if (connected == false)
{
System.out.println(hostAvailabilityCheck());
}
}
};
public static boolean hostAvailabilityCheck()
{
boolean available = true;
try {
if (connected == false)
{ (s = new Socket(SERVER_ADDRESS, TCP_SERVER_PORT)).close();
}
}
catch (UnknownHostException e)
{ // unknown host
available = false;
s = null;
}
catch (IOException e) { // io exception, service probably not running
available = false;
s = null;
}
catch (NullPointerException e) {
available = false;
s=null;
}
return available;
}
Is there any better way to solve this?
The check method can be rewritten as follows (Java 7 and later):
public static boolean hostAvailabilityCheck() {
try (Socket s = new Socket(SERVER_ADDRESS, TCP_SERVER_PORT)) {
return true;
} catch (IOException ex) {
/* ignore */
}
return false;
}
In addition to simplifying the exception handling, this eliminates a pesky Socket leak. (If you are concerned with the time taken to do this check, then set a connection timeout before attempting to connect: see Setting a timeout for socket operations)
But the problems with this approach are many-fold:
It only tests that something is listening for connections. If your service is behind a proxy ... or is managed by something like the inetd service ... then the accepted connections don't mean your service is actually working.
This is going to cause your service to "see" connections that close down without sending a request. So you'd better code your service to deal with this "gracefully".
Doing this repeatedly adds to network and server load.
If you set a short timeout because you don't want the test to "freeze", then you risk setting it too short and judging the host to be down when it isn't.
After server is started I want to stop checking until the server changes status
That is next to impossible. The reason is that you won't be able to tell whether the server has "changed status" without checking. Or at least, you won't be able to do this without implementing an elaborate status notification service where the server calls the client to tell it is changing status. (And if "change status" includes "die" or "lost network connection", then you won't be able to make that notification reliable ... if at all.)
public static boolean hostAvailabilityCheck() {
try (Socket s = new Socket(SERVER_ADDRESS, TCP_SERVER_PORT)) {
return true;
} catch (IOException ex) {
/* ignore */
}
return false;
}
working, but the problem is that when you turn on the phone throught WI-FI it comes to a "screeching halt" and no action. for thought...=)
next code will be to work through WI-FI ... if you increase the connection time -
public static boolean isOnline() {
boolean b = true;
try{
InetSocketAddress sa = new InetSocketAddress("SERVER_IP_ADDRESS", PORT);
Socket ss = new Socket();
ss.connect(sa, 1); --> change from 1 to 500 (for example)
ss.close();
}catch(Exception e) {
b = false;
}
return b;
}
First check if server is running and the server accepts the connection.
public static boolean hostAvailabilityCheck()
{
s = new Socket(SERVER_ADDRESS, TCP_SERVER_PORT);
boolean available = true;
try {
if (s.isConnected())
{ s.close();
}
}
catch (UnknownHostException e)
{ // unknown host
available = false;
s = null;
}
catch (IOException e) { // io exception, service probably not running
available = false;
s = null;
}
catch (NullPointerException e) {
available = false;
s=null;
}
return available;
}
I used this method for my ServerUtil.
public static boolean isOnline() {
boolean b = true;
try{
InetSocketAddress sa = new InetSocketAddress("SERVER_IP_ADDRESS", PORT);
Socket ss = new Socket();
ss.connect(sa, 1);
ss.close();
}catch(Exception e) {
b = false;
}
return b;
}
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");
}
}
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>");
}
}