Getting the original cause of a JschException - java

I need to do some handling for a JschException. It looks like "JschException" is thrown regardless of what the specific cause of the exception was (ie. SocketTimeoutException, UnknownHostKey, or AuthFail). What's the best way for me to go about determining the original specific cause? Is my only option to parse the e.getMessage() String?
Here is the basic structure.
try {
session = jSch.getSession(getUsername(), host);
session.setUserInfo(user);
session.connect();
} catch (JSchException e) {
e.printStackTrace();
// Here I need to identify the cause and handle accordingly.
}
As an example here is the top trace for a timeout and a authentication failure respectively.
com.jcraft.jsch.JSchException: Session.connect: java.net.SocketTimeoutException: Read timed out
com.jcraft.jsch.JSchException: Auth fail
If it matters, I want to initiate a retry of the try block for authentication errors, and fail out for timeouts errors.

Indeed, JSch throws exceptions is a way that makes it impossible to find the root cause (except for parsing the exception message).
JSch is full of code like this:
catch(Exception e) {
...
throw new JSchException("Session.connect: "+e);
}

Related

Continue function after error / try - catch

I have a function in a server that sometimes throws an error and seems to crash the server.
Do try-catch blocks prevent servers/program from completly crashing and continue to process? This code handles network requests and I need to make sure the server does not crash and prevent the processing of other network requests to the same function because of an error that occurred and crashed the server.
A common error is a java null pointer exception
EDIT added example pseudo code:
public class myClass{
public static string networkHandler(string s) { //static method
try {
string ss = s;
}
catch(string s) {
//handle error
}
}
}
I am wondering if it is because I need to write another catch block to handle the specific type of error that is crashing the server.
Edit: As answered by #denis, I was wondering if there was a wy to have a catch block of type NullPointerException
A try catch allows you to catch an error (that will stop your program from completely crashing) and you can then handle the error. However something like a NullPointerException typically indicates an error in your code.
There's some more info on exception handling here: https://docs.oracle.com/javase/tutorial/essential/exceptions/handling.html
Depending on your server environment and frameworks you should have a global exception handling strategy. Local try-catches can only prevent crashes to that specific exceptions on that specific location.
Furthermore, null pointed exceptions are signs of code and algorithms issues so better seek the root cause and fix it
If the NullPointerException is your culprit then catch an exception like this
try {
// code that throws null pointer excpetion that crashes the server
}
catch(NullPointerExcpetion npe) {
//handle error
}
It should prevent server from crashing from this specific exception.
So, you want to use try-catch and you are using it wrong in your pseudocode.
try {
string ss = s;
}catch(string s) {
//handle error
}
you are passing an string to catch which is wrong. you should pass an exception that you want to be catched. in this case NullPointerException, so you can rewrite it like :
try {
string ss = s;
}catch(NullPointerException ex) {
//handle error
}
you can read this link for more information about try-catch-finally structure in java.

Getting exception while connecting a server through SSH

I am trying to connect to an external server from my Solaris server using SSH in my Java application. Some how we are getting exception while authenticating the user but after 60min. How can we decrease the timing to get the exception to 5min or so.
There was a problem while connecting to IP:PORT
java.io.IOException: There was a problem while connecting to IP:PORT
The time difference between time2 and time3 are around 60min. I want to decrease this time.
Please find below the code snippet that we are using.
try
{
timeout = 1;
if (connection == null)
{
//time1
connection = new ch.ethz.ssh2.Connection(getIpAddress(), Integer.parseInt(getPort()));
if (connection == null)
{
System.out.println("connection is null");
}
else
{
//time2
connection.connect(null, timeout, 0);
}
}
}
catch (Exception t)
{
//time3
System.out.println(t.getLocalizedMessage());
System.out.println(t.toString());
}
Edit1: After checking SSH related configuration files I found KeyRegenerationInterval having a value of 3600s. Is this useful to resolve this issue. What might be the outcome if I decrease its value to some 30min or 5min.
Let me summarize your problem, please correct me if something wrong.
You can not connect to SSH server.
An exception raised after 60 mins.
According to below Throws section of method connect(ServerHostKeyVerifier, int, int), I guess you might be facing issue due to a buggy proxy which doesn't return proper HTTP response. Using direct internet connection to see whether the issue is gone.
Throws:
java.io.IOException - If any problem occurs, e.g., the server's host key is not accepted by the verifier or there is problem during
the initial crypto setup (e.g., the signature sent by the server is
wrong).
In case of a timeout (either connectTimeout or kexTimeout) a SocketTimeoutException is thrown.
An exception may also be thrown if the connection was already successfully connected (no matter if the connection broke in the mean
time) and you invoke connect() again without having called close()
first.
If a HTTP proxy is being used and the proxy refuses the connection, then a HTTPProxyException may be thrown, which contains
the details returned by the proxy. If the proxy is buggy and does not
return a proper HTTP response, then a normal IOException is thrown
instead.
Try setting the "kexTimeout" (Timeout for complete connection establishment (non-negative, in milliseconds). Zero means no timeout.) to non-zero
connection.connect(null, timeout, timeout);
Also, in your catch print the full stacktrace to verify where the timeout occurs
catch (Exception t) {
//time3
t.printStackTrace();
}

Recover from ProtocolException in HttpClient

I sometimes get such stacktraces when downloading from HttpClient:
java.net.SocketTimeoutException: Read timed out, at java.net.SocketInputStream.socketRead0(Native Method),
...
at org.apache.commons.httpclient.ContentLengthInputStream.read(ContentLengthInputStream.java:170),
[wrapped]
org.apache.commons.httpclient.ProtocolException: The server example.com failed to respond with a valid HTTP response,
I've tried to recover from these errors by using a custom HttpMethodRetryHandler, but it seems I don't even enter the retryMethod(). It may be due to the fact the wrapped exception in SocketTimeoutException is a ProtocolException, which inherits from HttpException, and thus is not eligible to recovery, if I correctly understand the code of HttpMethodDirector class.
while (true) {
execCount++;
try {
...
} catch (HttpException e) {
// filter out protocol exceptions which cannot be recovered from
throw e;
} catch (IOException e) {
// test if this method should be retried
http://hc.apache.org/httpclient-3.x/exception-handling.html says
ProtocolException signals a violation of the HTTP specification. It is
important to note that HTTP proxies and HTTP servers can have
different level of HTTP specification compliance. It may be possible
to recover from some HTTP protocol exceptions by configuring
HttpClient to be more lenient about non-fatal protocol violations.
How can i achieve that? Is there an API allowing this or should I implement the mecanism to retry requests failing with HttpException?
There are a number of http.protocol.* configuration parameters that are defined here. You need to carefully look at each one of them and figure out what is the optimum leniency you need.

Exceptions in Java (Recoverable vs Fatal)

I have a java program that tries to collect a certain rss feed from a list of servers. If there are any failures, (authentication, connection, etc) I want to throw an exception that basically takes me back to the main loop where I can catch it, display some info in the logs, and then move on the trying the next server in the loop. Most exceptions seem to be fatal though... even when they don't really need to be. I beleive I have seen exceptions that are not fatal... but don't remember for sure. I have tried to search around but I am probably using the wrong terminology.
Can someone help me get pointed in the right direction here? Are there particular types of exceptions I can throw that will be recoverable vs stopping the entire program in its tracks?
No Exception needs to be fatal. (Errors however, are meant to be fatal. Don't catch them.) All you have to do is catch the Exception somewhere, and it's not fatal.
try
{
riskyMethod();
}
catch (ReallyScaryApparentlyFatalException e)
{
log(e);
// It's not fatal!
}
There are no "unrecoverable exceptions" per se. In Java, if it registers as an "exception" you can catch it:
try {
// Attempt to open a server port
} catch (SecurityException ex) {
// You must not be able to open the port
} catch (Exception ex) {
// Something else terrible happened.
} catch (Throwable th) {
// Something *really* terrible happened.
}
What you may want, if you are creating a server connecting application, something like this:
for(Server server : servers) {
try {
// server.connectToTheServer();
// Do stuff with the connection
} catch (Throwable th) {
//Log the error and move along.
}
}
Error:
An Error "indicates serious problems that a reasonable application
should not try to catch."
Exception:
An Exception "indicates conditions that a reasonable application might
want to catch."
Exceptions are always meant to be recoverable, no matter checked or unchecked though it is possible always not to handle them, but it should be. while On the
other hand, error must be fatal. However, even error can be handled, but it would rather be just fancy way to say "it's a crash"
probably you would wanna have a look at Exception vs Error
Whatever the type of the exception you throw, it will go up the call stack until it's caught. So you just need to catch it:
for (Server server : servers) {
try {
contactServer(server);
}
catch (MyCustomException e) {
System.out.println("problem in contacting this server. Let's continue with the other ones");
}
}
Read the Java tutorial about exceptions.

java rmi server side exception handling

Do you see any possibility to log server side exceptions?Consider such code on the server side:
catch (Exception ex) {
throw new IllegalStateException (ex);
}
The exception is caused by the client-side call. Of course, exception will be noticed on the client-side. Is there any way to somehow handle it on the server side, without catch runtime exceptions? Some kind of handler that would allow me for example to log the stacktrace of the exception?
Any ideas?
you can wrap your server instance in a java.lang.reflect.Proxy and implement your server-side logging in the proxy. just make sure the proxy is exported, not the server implementation.
Commonly, the top level server method will have throws Exception.
If you wrap your "do it" code in this method with a try-catch Exception, and you can log it there as still throw it.
public Response myServerTopLevelMethod() throws Exception {
try {
myImplCode();
catch (Exception e) {
Log.error(e);
throw e;
}
}
Now you have some options about what to do. The basic options are:
You can just re-throw the Exception (as above)
You can play nice and return a "something bad happened" response - like many web servers do
Here's an example of option 2:
public Response myServerTopLevelMethod() throws Exception {
try {
myImplCode();
catch (Exception e) {
Log.error(e);
return new Response("Yikes! Something exploded... we'll look into it.");
}
}
Incidentally, the "Log + throw" of option 1 is one of the few times that you ever want to do this; at the top level method. At other times you should generally either log or throw, not both.
There are RMI system properties that will automatically log server-side exceptions for you. See the links on the RMI Home Page.

Categories