Does throwing any exception cause the GAE instance to restart - java

In my code i have a lot of code like the following. I am wondering if it's a bad thing for my server and if it will cause the instance to restart.
if (opLoginId == loginId) {
datastore.delete(key);
return 0;
} else {
throw new WebApplicationException(Response.Status.UNAUTHORIZED);
}

Unless these are being caught at some higher level (say, to turn them into the right HTTP response), then yes, you're killing your instance.

Related

HttpSession creates session for one Java servlet but doesn't share it in another servlet using getSession()

I have a Java servlet passing attributes to the session using HttpSession. The getSession() method, as far as I know, is allowing me to pass objects to the session using setAttribute(String name, Object value) . I say as far as I know because this servlet is the only one currently able to get the session. The other servlet I want to get the attributes using getAttribute(String name) . However, when I initialize an HttpSession variable, it doesn't work.
Here is the relevant section of code in the doPost() method of the first servlet NewTextLog :
HttpSession session = request.getSession();
System.out.println("NewTextLog: " + session.getId() );
session.setAttribute("textlog", textlog);
session.setAttribute("param", param);
Don't worry about the objects. I can confirm there are objects to provide to the attributes but if the session can't be shared it doesn't matter anyway. I can confirm that the session does initialize successfully when I run my application because the sysout does print what I expected it to. A sample output from one time I ran it would be NewTextLog: 4657DAFB8F5580397CB228AEF618D6DB . Now, here are the relevant lines in the doGet() method of my second servlet, LogData :
HttpSession session = request.getSession(false);
System.out.println(session);
System.out.println("LogData: " + session.getId() );
TextLog textlog = (TextLog) session.getAttribute("textlog");
String param = (String) session.getAttribute("param");
I think the problem must be somewhere on this side of things because neither of those sysouts print anything at all. If session were null, that should have at least been printed. Nothing. It's bizarre too because I was able to get it working for a short while. I did make some minor tweaks to the code but I think I commented all the changes out and even if I didn't, I really don't think I changed anything relevant to the functioning of these lines. It's as though the thing just decided to quit on me.
I'm wondering if there's anything required to target the second servlet to make sure it can get a hold of the session. However, I though the point of using the session was so that any servlet could access it regardless of targeting. Sorry if this is a beginner's question. In any case, if anyone is wondering, I used annotations instead of web.xml for servlet mapping. Maybe this makes a difference. For NewTextLog my annotation is #WebServlet("/logs") and for LogData, it's #WebServlet("/logdata") .
There's a lot of stuff about HttpSession on here, and I did try other methods but they don't seem to work. The long and short of it is that it once worked, and now it doesn't. Can anyone please tell me if they have experience with similar problems or if the issue is readily apparent?
Update:
Using the Eclipse debugger, I started stepping through the code, with Step Return so it wouldn't take me forever to step through all the classes invoked with the doGet() call. There's a class in Tomcat that I can't step through called ThreadPoolExecutor . Absolute path is C:\Users\tylab\.m2\repository\org\apache\tomcat\tomcat-util-9.0.68-sources.jar\org\apache\tomcat\util\threads\ThreadPoolExecutor . I literally have grey buttons where my Step Into, Step Over and Step Return buttons are, which cannot be pressed. I will put the method it's stuck at here and comment on exactly what line it stops at:
#SuppressWarnings("null") // task cannot be null
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock(); // allow interrupts
boolean completedAbruptly = true;
try {
while (task != null || (task = getTask()) != null) {
w.lock();
// If pool is stopping, ensure thread is interrupted;
// if not, ensure thread is not interrupted. This
// requires a recheck in second case to deal with
// shutdownNow race while clearing interrupt
if ((runStateAtLeast(ctl.get(), STOP) ||
(Thread.interrupted() &&
runStateAtLeast(ctl.get(), STOP))) &&
!wt.isInterrupted()) {
wt.interrupt();
}
try {
beforeExecute(wt, task);
try {
task.run();
afterExecute(task, null); //Line 1192: this is where it stops
} catch (Throwable ex) {
afterExecute(task, ex);
throw ex;
}
} finally {
task = null;
w.completedTasks++;
w.unlock();
}
}
completedAbruptly = false;
} finally {
processWorkerExit(w, completedAbruptly);
}
}
I have absolutely no experience digging into the ditches of all these extremely large classes that run the Tomcat server, so I really have no idea what this all means. I'm hoping someone else might be able to figure out what is going on. Is the execution of my doGet() stopping at this point when I run my program normally? I feel like that would explain a lot.

Why retryOnConnectionFailure(true) is a solution to OkHttp Error : java.io.IOException: unexpected end of stream

I had this error for quite a while now when i found this.
After using the solution provided by swankjesse the error disappeared.
I just cant seem to understand why this is a solution. I cant find anything online that
explains the reason why this method solves the error.
OkHttp Docs say:
retryOnConnectionFailure
Configure this client to retry or not when a connectivity problem is
encountered. By default, this client silently recovers from the
following problems:
Unreachable IP addresses. If the URL’s host has multiple IP
addresses, failure to reach any individual IP address doesn’t fail the
overall request. This can increase availability of multi-homed
services.
Stale pooled connections. The ConnectionPool reuses sockets to
decrease request latency, but these connections will occasionally time
out.
Unreachable proxy servers. A ProxySelector can be used to attempt multiple proxy servers in sequence, eventually falling back to a
direct connection.
The above is understandable but it does not justify why this is a solution to that error.
Thanks in advance.
This flag allows OkHttpClient to retry a request multiple times when certain conditions are true that mean it is known to be safe. Without this flag the client will return the error immediately for the client to presumably dcide if and when to retry.
private fun isRecoverable(e: IOException, requestSendStarted: Boolean): Boolean {
// If there was a protocol problem, don't recover.
if (e is ProtocolException) {
return false
}
// If there was an interruption don't recover, but if there was a timeout connecting to a route
// we should try the next route (if there is one).
if (e is InterruptedIOException) {
return e is SocketTimeoutException && !requestSendStarted
}
// Look for known client-side or negotiation errors that are unlikely to be fixed by trying
// again with a different route.
if (e is SSLHandshakeException) {
// If the problem was a CertificateException from the X509TrustManager,
// do not retry.
if (e.cause is CertificateException) {
return false
}
}
if (e is SSLPeerUnverifiedException) {
// e.g. a certificate pinning error.
return false
}
// An example of one we might want to retry with a different route is a problem connecting to a
// proxy and would manifest as a standard IOException. Unless it is one we know we should not
// retry, we return true and try a new route.
return true
}
In the most simple case, if we hadn't started sending a request then we know retrying must be safe. Likewise certain response codes like 408 indicate that the server hasn't started any work so we can try again.

Java - Can I use an empty catch statement?

I am working on a basic Java command line email client application. The connector I was provided with will send me emails, however if I "send" an email it will not be located on the connector as I created this email myself. Now when I want to delete an email I can find the folder I am in and delete it by its ID. I also want to delete it from the connector if its located inside the connector so that I will not receive this email again when I refresh emails.
public boolean delete(int messageId) throws IndexOutOfBoundsException
{
if (folders.get(getActiveFolderName()).delete(messageId))
{
if (connector.retrMessage(messageId) != null)
{
connector.markMessageForDeleting(messageId);
//throws exception if not found on connector
}
return true;
}
return false;
}
I tried this, is this a really bad way of going about handling exceptions?:
public boolean delete(int messageId)
{
if (folders.get(getActiveFolderName()).delete(messageId))
{
try{
connector.markMessageForDeleting(messageId);
} catch (IndexOutOfBoundsException e)
{
//this successfully soaks up the exception if its not located in connector
}
return true;
}
return false;
}
Thanks
Though they are considered as bad, as long as you are aware of what's going on and took necessary steps to recover from abnormal behaviour of the program, it will be fine.
I'm just suggesting to you to put at least a log statement.
I would personally not think so. You are using the exception as an indicator of a particular result. You're not trying to hide some error in the code by not doing anything when you catch it. However, I'm not sure if you have the ability to change anything about this connector, but if so, you should adjust it so it isn't throwing errors like that in the first place.
What you're doing is called exception swallowing. It's generally considered bad practice. The risk is to swallow exceptions that might happen when your emails are located in the connector. You don't want that.
You already know a reason to have an IndexOutOfBoundsException, so why not test first if your email is located in the connector?
It is always good practice to log any exception & then can be ignored in the cases like yours.
P.S.: No need to flood the log with stack trace in your case. It can be a simple error message indicating that the exception can be ignored safely.

Retrying an http connection

I'm making an http request. I'm on a platform (android) where network operations often fail because the network connection might not be immediately available. Therefore I'd like to try the same connection N times before completely failing. Was thinking of something like this:
DefaultHttpClient mHttp = ...;
public HttpResponse runHttpRequest(HttpRequestBase httpRequest)
throws IOException
{
IOException last = null;
for (int attempt = 0; attempt < 3; attempt++) {
try {
HttpResponse response = mHttpClient.execute(httpRequest);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == 200) {
return response;
}
} catch (IOException e) {
httpRequest.abort();
last = e;
}
}
throw last;
}
I'm mostly worried about the connection being in some state which is invalid on subsequent retries. In other words, do I need to completely recreate 'httpRequest', should I avoid calling httpRequest.abort() in the catch block, and only call it in the final failure?
Thanks
The documentation does not mention that such a thing will occur, although you'd have to try it. More importantly, though, there are some things that you should consider with your code...
You should probably expose the number of retries, allowing the caller to specify this value.
You should only retry if an exception was thrown; you currently retry unless you get a 200. However if, for example, you get a 404... this doesn't mean your request failed in the sense that the network did not fail... rather, you made a successful round-trip to the server, but the server simply doesn't have the requested resource... so it really doesn't make sense to retry in such a case.
As-is, you might suppress all sorts of different types of exceptions. It might make sense to record all the exceptions that occurred in a List and return some sort of result object which contains the response (possibly null if all attempts failed) in addition to a list of all exceptions. Otherwise, you throw some arbitrary exception from the set of exceptions that occurred, possibly obscuring failure.
Right now you just hammer away with the same request, over and over again... if there is congestion, you are just adding to it. And if your IP address was banned for too much activity, you are probably going to be adding to that... any sort of retry logic should have a back-off behavior where there is some amount of waiting between retries and that interval increases with each failure.
A HttpRequestRetryHandler seems like it might be helpful here.
I'd recommend to use AOP and Java annotations from jcabi-aspects (I'm a developer):
#RetryOnFailure(attempts = 3, delay = 5)
public String load(URL url) {
return url.openConnection().getContent();
}

How can I avoid the general Exception thrown by the Server-class in Jetty?

Jetty can be used as a library to embed a servlet-server into your application. To do that, you create an instance of the class Server and call start at some point. This method throws Exception. Catching or throwing a pure Exception (not a specialized subclass) is bad style. Does anyone know, how I can avoid this and get a Jetty-server in my application running without handling this general Exception?
Catching Exception is bad practice unless only Exception is thrown. There is no workaround for it. Catching distinct subclasses of Exception has the disadvantage of possibly missing out on some of them.
What is the meaning of Jetty failing to start in your application? You can have multiple approaches:
Decide at the component level that you should proceeed
try {
server.start();
reportingAvailable = true;
} catch ( Exception e ) {
log("Jetty failed to start. Reporting will we unavailable", e);
}
Treat it as a fatal exception
try {
server.start();
} catch ( Exception e ) {
throw new RuntimeException("Jetty failed to start", e);
}
Treat it as a recoverable exception
try {
server.start();
} catch ( Exception e ) {
throw new JettyFailedToStartException(e); // JettyFailedToStartException !instanceof RuntimeException
}
I would strongly advise you to handle it somehow.
If Jetty can't start (e.g. bind to its nominated port) then you're going to want to manage that somehow. At the very least log this so you know you don't have a web server running. Perhaps retry after a while ?
The point is that Jetty is unable to start and you should care about that.

Categories

Resources