How to log the error message when OutOfMemoryError occurs - java

I have an OOM error(Perm Gen is full), problem is when I am logging the error message into the log file, error occurs while the classloader is loading the exception handling class.

You shouldn't handle errors as your application is in abnormal state:
https://docs.oracle.com/javase/7/docs/api/java/lang/Error.html
Differences between Exception and Error
This answer explains scenario where you might want to do it though:
Catching java.lang.OutOfMemoryError?

You can either throw this error to handle where you're using it or you can put a try catch block around your logic(code) and you can log the error inside the catch or finally block.

Related

What is a IOException, and how do I fix it?

What are IO Exceptions (java.io.IOException) and what causes them?
What methods/tools can be used to determine the cause so that you stop the exception from causing premature termination? What does this mean, and what can I do to fix this exception?
Java IOExceptions are Input/Output exceptions (I/O), and they occur whenever an input or output operation is failed or interpreted. For example, if you are trying to read in a file that does not exist, Java would throw an I/O exception.
When writing code that might throw an I/O exception, try writing the code in a try-catch block. You can read more about them here: https://docs.oracle.com/javase/tutorial/essential/exceptions/catch.html
Your catch block should look something like this:
try {
//do something
}catch(FileNotFoundException ex){
System.err.print("ERROR: File containing _______ information not found:\n");
ex.printStackTrace();
System.exit(1);
}
Here you go https://docs.oracle.com/javase/7/docs/api/java/io/IOException.html
IOException is thrown when an error occurred during an input-output operation. That can be reading/writing to a file, a stream (of any type), a network connection, connection with a queue, a database etc, pretty much anything that has to do with data transfer from your software to an external medium.
In order to fix it, you would want to see the stack trace of your exception or at least the message, to see exactly where the exception is thrown and why.
try {
methodThrowingIOException();
} catch (IOException e) {
System.out.println(e.getMessage()); //if you're using a logger, you can use that instead to print.
//e.printStackTrace(); //or print the full stack.
}
The error message that will be printed will likely show you what the issue is. If you add the error message here, I'll be able to give you more info on how to fix that specific IOException. Without that, no one can really give you a complete answer.
It is a very generic exception that a lot IO operation can cause. A best way is to read the Stack Trace. To continue the execution you can use the try-catch block to bypass the exception, but as you mention you should investigate into the cause.
To print the stack trace:
try {
// IO operation that could cause an exception
} catch (Exception ex) {
ex.printStackTrace();
}
IOException is usually a case in which the user inputs improper data into the program. This could be data types that the program can't handle or the name of a file that doesn't exist. When this happens, an exception (IOException) occurs telling the compiler that invalid input or invalid output has occurred.
Like others have said, you can use a try-catch statement to stop a premature termination.
try {
// Body of code
} catch (IOException e) {
e.printStackTrace();
}

Should we log the stacktrace for managed exception?

I made many research on this subject without found a real answer.
Try to imagine a program which execute a multi thread calling a Callable.
For that, we launch an ExecutorService with a specific timeout which invoke all process.
So we have a try...catch block with multiple exception :
CancellationException for a timeout
ExecutionException if an exception is raised in the thread
InterruptedException for an abrupt stop...
Is the philosophy to log an message only, or to log the message and the throwable (so the stacktrace) ?
To sum up, should we do this :
} catch (CancellationException ce) {
logger.error("Timeout. Process cancelled", ce);
}
or just log the message error ?
Is stacktrace considered to appear only for bugs ?
Thank you.
For coding you should stick with the following pattern:
} catch (CancellationException ce) {
logger.error("Timeout. Process cancelled", ce);
}
The reason is that the Throwable captures the complete context of an error. If you omit parts of that context from the logger you'll never be able to access it later on if you need it. Even the Throwable class included with Java has been modified over time to include things like chained and suppressed exceptions. So even if you only want the message from this throwable you still might want to see the full stack traces for suppressed exceptions and exceptions causes.
On the output side, I think you can make that case that for some exceptions the stack trace is not important. In some cases the target audience must not or does not want to see exception stack traces. For these cases should leverage the features of the framework to change the published output to please the target audience. If the needs change over time you can tweak logging configuration without having to fix the application code.

Eclipse breaks on processWorkerExit

After serving a few requests my eclipse has started breaking on processWorkerExit() method.
As per this link I know how to suppress the breaking of eclipse but is there any reason why the code is breaking on this line. Can there be a memory leak in such a case?
Tomcat 7.0.27
Eclipse 3.7.2
JDK 7.0.02
Answer is here: OpenJDK breaks on processWorkerExit with no breakpoint
In debug mode in eclipse by default, break on uncaught exceptions is
checked. Since you don't have a catch method here, it's likely that an
uncaught exception is being thrown and the debugger is breaking for
you immediately before the exception is thrown. You can turn it off in
preferences under Java->Debug.
The reason the debugger is stopping on that line is because there is an exception being thrown by the code within the try{} block, and that particular line of code is the next executable line of code after the exception is thrown. You can almost certainly see the stack trace of that exception in the console window, because by default an uncaught exception that bubbles up to Thread.run() will be sent to stderr.
As for your question about whether there can be a memory leak (or more likely, this being Java, a resource leak): the answer is yes, there could be. But there is nothing in that code to indicate that there is. If there were such a leak, it would almost certainly be because there is incorrect exception handling inside the task implementation.
I had this same problem. It breaks in your try/catch clause if you have one if you don't log the exception. Try inserting a breakpoint or output to LogCat like this :
try
{
//HERE I'VE PUT ALL THE FUNCTIONS THAT WORK FOR ME
Log.e("tag", "Sth passed!");
}
catch (Exception e)
{
//The task failed
Log.e("tag", e.getMessage());
}
If you don't have try/catch block put it like in above code. In LogCat you can see the last line of code that was run before exception it will help you to locate the error in your code just like this :
08-28 05:49:52.321: E/SQLiteDatabase(834): at java.lang.Thread.run(Thread.java:841)

unable to catch org.hibernate.StaleObjectStateException while deleting record that doesn't exists in database

My application has a delete user option. Now in order to check concurrency condition I tried the following use case
opened application in chrome and firefox browser.
deleted user in firefox
now trying to delete the same user in chrome browser I get exception org.hibernate.StaleObjectStateException .. which is right .. since I am trying to delete an object which doesn't exists. But I am not able to catch this exception
try{
getHibernateTemplate().delete(userObj);
} catch (StaleObjectStateException e) {
e.printStackTrace();
}
How do i catch this exception ??
You won't be able to catch it there, because it's not the delete call that throws the exception, but the flush of the session, which happens later (before the execution of a query, or before the transaction commit).
You should not catch this exception anyway, because when Hibernate throws an exception, you can't continue using the session anymore: it's in an unstable state. The only part of the application where such an exception can be caught is outside of the transaction, in order to display an error message to the user (or retry, but this won't be possible in this particular case).
You are catching StaleObjectStateException instead of StaleStateException :-)
UPDATE:
have a look at the stacktrace; assuming you're working in a transaction the exception might only be thrown when the transaction is committed.
The code in your question looks right on the face of it.
If that delete call actually throws that exception when executed, then your code will catch it. If it doesn't then the exception is actually being thrown in a different place ... or the exception that is being thrown is a different one.
I'd temporarily replace the catch with a catch of java.lang.Throwable to see if some other exception is propagating at that point. And add a trace print to see if the code is executing at all.
If you already have a stack trace, that will tell you where the exception is being thrown unless something really tricky is going on. You just need to catch it further up the stack.

Unable to catch IOException

An IOException is thrown and, for some reason, it's impossible to catch. Have a look at the code below. The stack trace says an IOException is thrown when calling the "apply"-method. The exception doesn't, however, get caught by the catch clause. When I try to catch an IOException instead, Eclipse complains saying: "Unreachable catch block for IOException. This exception is never thrown from the try statement body"
Why is this happening?
Code:
try {
action.apply();
}
catch (Exception e) {
System.out.println("Fail");
}
Here's the stacktrace:
java.io.IOException: Unable to download JavaScript from 'somesite' (status 404).
at com.gargoylesoftware.htmlunit.html.HtmlPage.loadJavaScriptFromUrl(HtmlPage.java:1023)
at com.gargoylesoftware.htmlunit.html.HtmlPage.loadExternalJavaScriptFile(HtmlPage.java:967)
at com.gargoylesoftware.htmlunit.html.HtmlScript.executeScriptIfNeeded(HtmlScript.java:353)
at com.gargoylesoftware.htmlunit.html.HtmlScript$1.execute(HtmlScript.java:225)
at com.gargoylesoftware.htmlunit.html.HtmlScript.onAllChildrenAddedToPage(HtmlScript.java:235)
at com.gargoylesoftware.htmlunit.html.HTMLParser$HtmlUnitDOMBuilder.endElement(HTMLParser.java:718)
at org.apache.xerces.parsers.AbstractSAXParser.endElement(Unknown Source)
at com.gargoylesoftware.htmlunit.html.HTMLParser$HtmlUnitDOMBuilder.endElement(HTMLParser.java:676)
at org.cyberneko.html.HTMLTagBalancer.callEndElement(HTMLTagBalancer.java:1136)
at org.cyberneko.html.HTMLTagBalancer.endElement(HTMLTagBalancer.java:1038)
at org.cyberneko.html.filters.DefaultFilter.endElement(DefaultFilter.java:206)
at org.cyberneko.html.filters.NamespaceBinder.endElement(NamespaceBinder.java:329)
at org.cyberneko.html.HTMLScanner$ContentScanner.scanEndElement(HTMLScanner.java:2999)
at org.cyberneko.html.HTMLScanner$ContentScanner.scan(HTMLScanner.java:1991)
at org.cyberneko.html.HTMLScanner.scanDocument(HTMLScanner.java:895)
at org.cyberneko.html.HTMLConfiguration.parse(HTMLConfiguration.java:499)
at org.cyberneko.html.HTMLConfiguration.parse(HTMLConfiguration.java:452)
at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
at com.gargoylesoftware.htmlunit.html.HTMLParser$HtmlUnitDOMBuilder.parse(HTMLParser.java:896)
at com.gargoylesoftware.htmlunit.html.HTMLParser.parse(HTMLParser.java:350)
at com.gargoylesoftware.htmlunit.html.HTMLParser.parseHtml(HTMLParser.java:304)
at com.gargoylesoftware.htmlunit.DefaultPageCreator.createHtmlPage(DefaultPageCreator.java:134)
at com.gargoylesoftware.htmlunit.DefaultPageCreator.createPage(DefaultPageCreator.java:101)
at com.gargoylesoftware.htmlunit.WebClient.loadWebResponseInto(WebClient.java:420)
at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:303)
at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:360)
at org.openqa.selenium.htmlunit.HtmlUnitDriver.get(HtmlUnitDriver.java:228)
at org.openqa.selenium.htmlunit.HtmlUnitDriver.get(HtmlUnitDriver.java:216)
at org.openqa.selenium.internal.seleniumemulation.Open.handleSeleneseCommand(Open.java:36)
at org.openqa.selenium.internal.seleniumemulation.Open.handleSeleneseCommand(Open.java:22)
at org.openqa.selenium.internal.seleniumemulation.SeleneseCommand.apply(SeleneseCommand.java:33)
at Action.runSeleniumAction(Action.java:235)
at SessionDriver.runSession(SessionDriver.java:192)
at SessionDriver.run(SessionDriver.java:123)
the apply() method fully handles the exception and does not rethrow it. If it did it would be marked as "public void apply() throws IOException".
The compiler warns you about this, since it would result in inaccurate error handling if it didn't.
Right, the apply() method itself isn't throwing that exception. Something else inside that apply method() is, and that something prints the complete stack trace instead of the "fail" message that you've decided is somehow better.
As you can see in the stacktrace, your code is missing, therefore you can't catch the exception. My guess is that SessionDriver.run() is called from a different thread.
Have you tried Selenium-RC? It should be able to catch these errors and pass them on to the test case.
You're using eclipse - so easiest way to get to the source of the exception is to run your application in debug mode and set a breakpoint on java.io.IOException. So whenever this exception is thrown somewhere in the running VM, eclipse will stop the application and show you thread, class and line of code (if available).

Categories

Resources