So I have some code that's throwing a RuntimeException. I know it's throwing a RuntimeException, I wrote it to do so under certain circumstances. Recently, I was having what I thought was a deadlock, because the method didn't seem to be finishing, but as I logged out the problem I realized that it was in fact that RuntimeException.
Now, here's the issue: This exception is occurring silently. The Android monitor in Android Studio isn't displaying a stack trace for it. This threw me off, because in normal Java applications (which I'm more used to, I'm a professional Java dev but I'm a bit new to Android), RuntimeExceptions send a stack trace directly to the console.
So, my reaction was to do a Thread.UncaughtExceptionHandler to log this. Only... it's not working.
Here's my UncaughtExceptionHandler. I don't actually care about it doing all the things it does, I was just trying to get something to happen to indicate that it was being called.
public static class ContactsUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler{
private static final String TAG = "UncaughtException";
#Override
public void uncaughtException(Thread thread, Throwable throwable) {
System.out.println("UNCAUGHT EXCEPTION"); //TODO delete this
Log.e(TAG, String.format("Uncaught exception in thread %d", thread.getId()), throwable);
throwable.printStackTrace();
System.exit(1);
}
}
This handler is being added in the following ways:
1) I have an executor spawning threads. It uses a ThreadFactory, which assigns this handler to each thread using Thread.setUncaughtExceptionHandler().
2) I call Thread.setDefaultUncaughtExceptionHandler() in the onCreate() method of my Application class.
3) The code where this is occurring is a Runnable.run() method. I put a line in that run() method calling Thread.currentThread().setUncaughtExceptionHandler().
Nothing works. None of those operations there get triggered.
I know with 100% certainty that a RuntimeException is occurring, because if I surround the code with a try-catch block and do printStackTrace() that way, it shows up in the console log. I just can't get the UncaughtExceptionHandler to work.
The code where this is happening is very long and verbose, here's a quick summary of it:
#Override
public void run(){
Thread.currentThread().setUncaughtExceptionHandler(new ContactsThreadFactory.ContactsUncaughtExceptionHandler());
System.out.println("This line outputs to the console");
object.callingMethodThatCausesException();
System.out.println("This line never executes, because exception was thrown");
}
Any ideas on how to fix this? I don't understand why it's not working.
Edit: Just discovered something interesting, not 100% sure what it means yet. I put "throws new RuntimeException()" into the onCreate() method of my Activity class, and that exception showed up in the console like normal. I tried doing the same thing from within that Runnable, and nothing. Not entirely sure what to make of that.
Also, the UncaughtExceptionHandler worked for that new RuntimeException I put in. I just don't understand why it's not working elsewhere?
Related
So quoting from this page, which is titled: Exception-Handling Antipatterns Blog and seems to be written (or at least to be approved) by Oracle..
An unchecked exception probably shouldn't be retried, and the correct response is usually to do nothing, and let it bubble up out of your method and through the execution stack. This is why it doesn't need to be declared in a throws clause. Eventually, at a high level of execution, the exception should probably be logged.
I am not sure if I understand this. How can I log an unchecked exception? If I have something like:
public static void main(String args) {
foo();
// How do I know what to log here? The method I am calling
// is not throwing an Exception.
// Do I just blindly catch(Exception ex)?
}
static void foo() {
bar();
}
static void bar() {
baz();
}
static void baz() {
// I will do nothing as Oracle suggests and let this exception bubble up.. I wonder who is going to catch it and how this is going to be logged though!
throw new NullPointerException();
}
Can you help me understand what Oracle is suggesting here? I do not see any direct (or clear) way to catch runtime exceptions (I do not understand why it is not just called unchecked exceptions..) in higher levels and I am not sure how this suggested practice is useful. To me it would make more sense if it were talking about checked exceptions. Something like..
If a checked exception is thrown in a method that is not reasonable to be re-tried, the correct response is to let it bubble up and log..
You can also register a global ExceptionHandler that will handle the Exceptions that were not caught by your code:
Thread.setDefaultUncaughtExceptionHandler
This exception handle could then log whatever occured.
First of all, this is a general advice and it depends on the context. The idea behind it is that when a runtime exception occurs (ex. NullPointerException), the system is usually in an indeterministic state, meaning the rest of the code is not be guaranteed to execute as expected, so it's better to stop everything.
In most cases, your code will run in a separate thread and the exception will only stop the current thread, while the rest of the program keeps running.
This is not the case in your example, because everything is executed in a single thread, so the uncaught exception will effectively stop the whole program. In this scenario you might want to catch the exception and handle it.
public static void main(String args) {
try {
foo();
catch(Throwable t) {
t.printStackTrace(); // log exception
// handle the failure
}
}
You can also catch the exception earlier on, log and rethrow it further.
static void bar() {
try {
baz();
catch (Throwable t) { // catch
t.printStackTrace(); // log
throw t; // rethrow further
}
}
Edit: catch Throwable instead of Exception, will also catch Error
Note: Catching throwable is usually a bad idea, and should only be done with a specific purpose, not in general case. See #RC.'s comment.
As I understand it the documentation is suggesting that you have a generic handler at a high level of your code that logs such 'unexpected' (unrecoverable?) exceptions just as the comments in your main method suggest. So it might look something like this
public static void main(String args) {
try {
foo();
}
catch (ArithmeticException aex) { //if it's arithmetic log differently
log("arith issue! "+aex.getMessage());
}
catch (Exception ex) { //Otherwise do the best we can
log("unknown issue! "+ex.getMessage())
}
}
So there is still no path to recovery but at least before the process ends you get a chance to log the issue. You can also use the methods of Exception (or throwable) to get the stack trace and first causal exceptions in many case - so there is is a lot of extra useful information that might be logged.
There is a very straightforward way to catch unchecked exceptions, since they are all subclasses of RuntimeException or Error:
public static void main(String[] args) {
try {
// your code
} catch (RuntimeException | Error e) {
// handle uncaught exceptions, e.g.
e.printStackTrace();
}
}
How do I know what to log here? The method I am calling is not throwing an Exception.
As Joshua Bloch recommends in the Effective Java
Use the Javadoc #throws tag to document each unchecked exception that
a method can throw, but do not use the throws keyword to include
unchecked exceptions in the method declaration
And if you are using method wrapping in multilayered app i can recommend use exception translation:
Higher layers should catch lower-level exceptions and, in their place, throw exceptions that can be explained in terms of the higher-level abstraction
See Effective Java item 61
So i think for your example actually you should use something like:
try {
bar();
} catch(NullPointerException e) {
throw new HigherLevelException(...);
}
The most important guideline regarding exceptions is that a method that couldn't sucessfully complete its task should throw an exception.
Only if you can guarantee successful completion of your method's task, you should catch an exception inside your method (without re-throwing this or another exception). From my experience that's only true in very specific situations, e.g. if you have an alternative way to try if some first attempt fails, or if you really really understand all possible causes of this specific Exception class that you are about to catch.
Speaking about RuntimeExceptions, there are so many different types of RuntimeException that you can hardly justify an assertion like "When such an exception arises in my code or a method called from inside my code, that won't affect the outcome of my method - I can continue just as if nothing happened." So, you should signal to your caller that you failed to fulfill your task, and the clearest way to do that is to let the exception ripple through, without try/catch block or throws declaration, just relying on Java's default behaviour.
In my opinion, the same reasoning applies to nearly all kinds of exceptions, not only RuntimeExceptions.
The difference with checked exceptions is that you have to declare them in the throws clause of your method. Then you have two choices: list the exception in the throws clause of your method (and all parent methods as well!) or catch the exception, wrap it in a new RuntimeException(ex), and throw that from your method.
With e.g. a typical GUI application, your users will be grateful if a problem in one menu function won't crash the whole application - probably other menu items might still work as expected. So, top-level commands or menu items are typically the places where to catch exceptions, tell the user something like "Oops!", log the exception to some file for later inspection, and allow the user to continue with another action.
In your main/foo/bar/baz application, I don't see a place where continuing after an exception makes sense. So the whole program should be aborted (which happens automatically in your case). If you want some error logging to a file, then establish an uncaught exception handler or wrap the body of main() in a try / catch(Throwable t) block. You'll probably want every exception logged, whatever type it is, so catch them all, and that's why I'm suggesting Throwable.
public static void main(String[] args) {
try {
foo();
}
catch(NullPointerException e){
System.out.println("NullPointerException in main.");
}
}
static void foo() {
bar();
}
static void bar() {
baz();
}
static void baz() {
// I will do nothing as Oracle suggests and let this exception bubble up.. I wonder who is going to catch it and how this is going to be logged though!
throw new NullPointerException();
}
OUTPUT :
NullPointerException in main.
Basically the error is expected at a higher level, so there is no need to catch it on the baz() method level. If I understood correctly.
You can catch them just like any other exception with try-catch block. But the benefit is that you don't have to.
Use cases can vary. To my mind, the most popular is when it doesn't make sense to catch the exception right in that place or the appropriate handling should be implemented several levels (in terms of methods) higher than the method, calling the one throwing the exception (sorry, if that is not clear enough).
For example, the typical web application layout in java is as follows: you have a layer of controllers, a layer of services and a layer of dao. First one is responsible for dispatching requests, the second one is for managing business logic and the last one makes actual calls to db. So here for example it often doesn't make much sense to catch the exception in service layer if something goes wrong on the dao level. Here unchecked exceptions can be used. You log an exception and throw an unchecked exception so it could be handled some levels above for a user to get valuable feedback of work of the application.
If in this case you throw a checked exception you will have to rethrow it every level above just to bubble up it to the place of the actual handling. So here the unchecked exception is better to use in order not to copy and paste all that ugly try-catch block, rethrowing an exception and add the throws clause to the method.
I have a program which uses executorService to which I am passing callables.
Each of which is an object of one class which implements java.util.concurrent.Callable.
Then the executorService is invoked. A java.lang.NoClassDefFoundError is thrown in the middle of one of the callables in the call() method.
However it is not terminating nor getting logged on the console. Therefore there is no way to know if the program has worked correctly or not. Kindly suggest any way by which I can understand the same.
A Callable throws an Exception, which is not the superclass of NoClassDefFoundError. Within your Callable, catch Error (or even Throwable) and wrap it with an Exception:
V call() throws Exception
{
try
{
return this.doSomething();
} catch (Error e) {
e.printStackTrace();
throw new Exception(e);
}
}
In order to print the error to the console, you can create a Thread.UncaughtExceptionHander. Passing it into the Thread#setDefaultUncaughtThreadExceptionHandler will cause the handler to be invoked when the error is thrown.
Some one had already posted answer to this question, but when I came to mark it as answer after verifying, the post was unfortunately deleted. I am just retyping the answer.
The Futures which are returned by the ExecutorService after calling the invoke method contain all the Future objects of the thread. If anything goes wrong in any of the threads, an java.util.concurrent.ExecutionException is thrown. Which can be detected in the parent thread which owns the executorService when we do get() on the Future. Then e.getCause() after catching it will get us the actual object which caused an error/exception.
How can I detect when an Exception has been thrown anywhere in my application?
I'm try to auto-magically send myself an email whenever an exception is thrown anywhere in my Java Desktop Application. I figure this way I can be more proactive.
I know I could just explicitly log and notify myself whenever an exception occurs, but I'd have to do it everywhere and I might(more likely will) miss a couple.
Any suggestions?
You probobly don't want to mail on any exception. There are lots of code in the JDK that actaully depend on exceptions to work normally. What I presume you are more inerested in are uncaught exceptions. If you are catching the exceptions you should handle notifications there.
In a desktop app there are two places to worry about this, in the event-dispatch-thread (EDT) and outside of the EDT. Globaly you can register a class implementing java.util.Thread.UncaughtExceptionHandler and register it via java.util.Thread.setDefaultUncaughtExceptionHandler. This will get called if an exception winds down to the bottom of the stack and the thread hasn't had a handler set on the current thread instance on the thread or the ThreadGroup.
The EDT has a different hook for handling exceptions. A system property 'sun.awt.exception.handler' needs to be registerd with the Fully Qualified Class Name of a class with a zero argument constructor. This class needs an instance method handle(Throwable) that does your work. The return type doesn't matter, and since a new instance is created every time, don't count on keeping state.
So if you don't care what thread the exception occurred in a sample may look like this:
class ExceptionHandler implements Thread.UncaughtExceptionHandler {
public void uncaughtException(Thread t, Throwable e) {
handle(e);
}
public void handle(Throwable throwable) {
try {
// insert your e-mail code here
} catch (Throwable t) {
// don't let the exception get thrown out, will cause infinite looping!
}
}
public static void registerExceptionHandler() {
Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler());
System.setProperty("sun.awt.exception.handler", ExceptionHandler.class.getName());
}
}
Add this class into some random package, and then call the registerExceptionHandler method and you should be ready to go.
The new debugging hooks in Java 1.5 let you do this. It enables e.g. "break on any exception" in debuggers.
Here's the specific Javadoc you need.
Check out Thread.UncaughtExceptionHandler. You can set it per thread or a default one for the entire VM.
This would at least help you catch the ones you miss.
If you're using a web framework such as Spring then you can delegate in your web.xml to a page and then use the controller to send the email. For example:
In web.xml:
<error-page>
<error-code>500</error-code>
<location>/error/500.htm</location>
</error-page>
Then define /error/500.htm as a controller. You can access the exception from the parameter javax.servlet.error.exception:
Exception exception = (Exception) request.getAttribute("javax.servlet.error.exception");
If you're just running a regular Java program, then I would imagine you're stuck with public static void main(String[] args) { try { ... } catch (Exception e) {} }
If you are using java 1.3/1.4, Thread.UncaughtExceptionHandler is not available.
In this case you can use a solution based on AOP to trigger some code when an exception is thrown. Spring and/or aspectJ might be helpful.
In my current project I faced the similar requirement regarding the errors detection. For this purpose I have applied the following approach: I use log4j for logging across my app, and everywhere, where the exception is caught I do the standard thing: log.error("Error's description goes here", e);, where e is the Exception being thrown (see log4j documentation for details regarding the initialization of the "log").
In order to detect the error, I use my own Appender, which extends the log4j AppenderSkeleton class:
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.spi.LoggingEvent;
public class ErrorsDetectingAppender extends AppenderSkeleton {
private static boolean errorsOccured = false;
public static boolean errorsOccured() {
return errorsOccured;
}
public ErrorsDetectingAppender() {
super();
}
#Override
public void close() {
// TODO Auto-generated method stub
}
#Override
public boolean requiresLayout() {
return false;
}
#Override
protected void append(LoggingEvent event) {
if (event.getLevel().toString().toLowerCase().equals("error")) {
System.out.println("-----------------Errors detected");
this.errorsOccured = true;
}
}
}
The log4j configuration file has to just contain a definition of the new appender and its attachement to the selected logger (root in my case):
log4j.rootLogger = OTHER_APPENDERS, ED
log4j.appender.ED=com.your.package.ErrorsDetectingAppender
You can either call the errorsOccured() method of the ErrorsDetectingAppender at some significant point in your programs's execution flow or react immidiately by adding functionality to the if block in the append() method. This approach is consistent with the semantics: things that you consider errors and log them as such, are detected. If you will later consider selected errors not so important, you just change the logging level to log.warn() and report will not be sent.
In this case I think your best bet might be to write a custom classloader to handle all classloading in your application, and whenever an exception class is requested you return a class that wraps the requested exception class. This wrapper calls through to the wrapped exception but also logs the exception event.
I assume you don't mean any Exception but rather any uncaught Exception.
If this is the case this article on the Sun Website has some ideas. You need to wrap your top level method in a try-catch block and also do some extra work to handle other Threads.
Sending an email may not be possible if you are getting a runtime exception like OutOfMemoryError or StackOverflow. Most likely you will have to spawn another process and catch any exceptions thrown by it (with the various techniques mentioned above).
There is simply no good reason to be informed of every thrown exception. I guess you are assuming that a thrown exception indicates a "problem" that your "need" to know about. But this is wrong. If an exception is thrown, caught and handled, all is well. The only thing you need to be worried about is an exception that is thrown but not handled (not caught). But you can do that in a try...catch clause yourself.
In some code I've been reading, I've come across this :
class Someclass
{
public static void main(String[] args) throws IOException
{
//all other code here......
}
}
If main() throws an exception, in this case its an IOException, where is it caught and handled?
EDIT:
Is this considered bad practice? Or is this really common in real world code?
The detailed flowchart of full uncaught exception handling is given here: How uncaught exceptions are handled in Java.
When an uncaught exception occurs, the JVM does the following:
it calls a special private method, dispatchUncaughtException(), on the Thread class in which the exception occurs;
[...which] calls the thread's getUncaughtExceptionHandler() method to find out the appropriate uncaught exception handler to use. Normally, this will actually be the thread's parent ThreadGroup, whose handleException() method by default will print the stack trace.
it then terminates the thread in which the exception occurred.
Therefore you can, if you wish to, create your own custom uncaught exception handler.
It should also be noted that while main is commonly used as a Java application entry point, the method is just like any other methods in that it can also be called from other contexts (e.g. other main methods, or even itself recursively!). In that case, the caller can catch exceptions thrown.
public class SelfCatch {
public static void main(String args[]) throws Exception {
if (args == null) throw new Exception("Hi there!");
try {
main(null);
} catch (Exception e) {
System.out.println("Caught: " + e);
}
System.out.println("Exiting...");
}
}
Output:
Caught: java.lang.Exception: Hi there!
Exiting...
EDIT: Is this considered bad practice?
Or is this really common in real world
code?
It would be in production code, but when rapid prototyping or knocking up test code its often used as its quicker than typing the try {...} catch block. (unless you use a good IDE like Eclipse 3.5 which has an 'Auto wrap in try/catch' feature [auto-detecting any and all exceptions to!] ;-) )
Or your pretty sure it wont be thrown by methods invoked by main().
But even wrapping in a try/catch block will usually result in the same output as if you leave the Exception uncaught, if you simply use e.printStackTrace() ...
At the command line.
EDIT: The entry point is Main. Hence, there is no other method/caller to handle the exception.
I want to design it such that whenever one of my custom exceptions is thrown, it automatically prints the stacktrace to a file. Is there a method I can override to accomplish this? Doing this would help to reduce a noticable amount of code in my project.
You can have your custom exceptions inherit from RuntimeException, then set the UncaughtExceptionHandler on the relevant Threads to look for your exceptions and handle them however you like.
The stacktrace is available as soon as you call the constructor of your exception. You can't react to the event of being thrown, but you can write the stacktrace inside your constructor.
If you have a common exception class that's the base of all your custom exceptions then you could do all this in its constructor.
Is there a method I can override to accomplish this?
Yes, the printStacktrace() method.
You can create a base class for your exceptions and them call to an "internal" print that would be redeirected to your file.
You can use a Logger and have that specific logger pointing to the file you desire ( and change it, disable it , re-enable it, etc when you need to )
Something along the lines:
class MyStackTrace extends Throwable {
public void printStacktrace() {
super.printStracTrace();
internalPrint();
}
private void internalPrint() {
StringWriter sw = new StringWriter();
printStackTrace( sw );
Logger logger = Logger.getLogger("exceptions");
logger.warning( sw.toString() );
}
}
I can'r help you print a stack trace when an exception is thrown. But it's easy enough to do when the exception is constructed - Just include the printStackTrace() in your custom exception's constructor.
In general, this is not a great idea to log on every exception creation. The catcher should really decide what is the best handling of an exception. Also overriding the method in exception and logging to a file breaks the general contract around exception.
On a side note, you may discover some horrible performance problem related to logging at later stage. Given overriding happens in a central place you will have hard time fixing this.
If you still want to log while throwing the exception then the better solution is to use/create a utility class like Throwables. Call the code as Throwables.logAndThrow(new CustomerException(...)), same one line of code but flexible for the long term. logAndThrow could be as simple as, using the logger technique of previous poster:
public static void logAndThrow(Throwable t) {
logger.warning(t);
throw t;
}