Where is this exception caught and handled? - java

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.

Related

Why is main() method allowed to declare exceptions?

"Handle or declare. That's the law." - Head First
But, is it a good law? Let me give an example first:
public static void main(String[] args) throws Exception {
m1();
}
static void m1() throws Exception{
m2();
}
static void m2() throws Exception {
throw new Exception();
}
m2() throws exception and m1() calls m2(), meaning it must either handle or declare it. Hmmm let's declare it. Then main() calls m1() and it has same poll: declare or handle. I again decided to declare it and code compiles just fine.
Okay, it works, but who handled this exception at all? Looks like no one did. I know I am a beginner, but I don't like the sound of that. Yes, some methods can decide whether to declare or handle exceptions, but why main()? Shouldn't main method be one that just handles? In that way, no exception could "slip".
Am I missing something to this? I was honestly surprised that it is okay for main method to just declare exception, knowing that it is the last place we could technically catch something.
who handled this exception at all?
The Java runtime did.
More specifically, the UncaughtExceptionHandler did, as specified in the Java Language Specification (JLS), section 11.3. Run-Time Handling of an Exception:
If no catch clause that can handle an exception can be found, then the current thread (the thread that encountered the exception) is terminated. Before termination, all finally clauses are executed and the uncaught exception is handled according to the following rules:
If the current thread has an uncaught exception handler set, then that handler is executed.
Otherwise, the method uncaughtException is invoked for the ThreadGroup that is the parent of the current thread. If the ThreadGroup and its parent ThreadGroups do not override uncaughtException, then the default handler's uncaughtException method is invoked.
So, by default, when main() throws an exception, unchecked or checked, the built-in default "uncaught exception handler" will simply print the stacktrace to System.err, as-if the following was executed right before main() was called:
Thread.setDefaultUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler());
class DefaultUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
#Override
public void uncaughtException(Thread t, Throwable e) {
e.printStackTrace();
}
}
After the "uncaught exception handler" has been invoked the thread is terminated, same as if you simply return from the main() method, and unless the code has started non-daemon threads that are still running, the program ends.
Application may contain more than one class with main method. In that case application should declare a manifest to know which main is entrypoint (first called method). Main method can be called from another methods or another main method as a static method and can throw any exception. If you don't catch exception at least in entrypoint, then exception returned from your application to java virtual machine, then mashine deside what todo with exception. Usually jvm prints error message and return value other than 0 to operating system.

Add auto-clear notification on Cordova FirebaseX plugin [duplicate]

New Java programmers frequently encounter errors phrased like this:
"error: unreported exception <XXX>; must be caught or declared to be thrown"
where XXX is the name of some exception class.
Please explain:
What the compilation error message is saying,
the Java concepts behind this error, and
how to fix it.
First things first. This a compilation error not a exception. You should see it at compile time.
If you see it in a runtime exception message, that's probably because you are running some code with compilation errors in it. Go back and fix the compilation errors. Then find and set the setting in your IDE that prevents it generating ".class" files for source code with compilation errors. (Save yourself future pain.)
The short answer to the question is:
The error message is saying that the statement with this error is throwing (or propagating) a checked exception, and the exception (the XXX) is not being dealt with properly.
The solution is to deal with the exception by either:
catching and handling it with a try ... catch statement, or
declaring that the enclosing method or constructor throws it1.
1 - There are some edge-cases where you can't do that. Read the rest of the answer!
Checked versus unchecked exceptions
In Java, exceptions are represented by classes that descend from the java.lang.Throwable class. Exceptions are divided into two categories:
Checked exceptions are Throwable, and Exception and its subclasses, apart from RuntimeException and its subclasses.
Unchecked exceptions are all other exceptions; i.e. Error and its subclasses, and RuntimeException and its subclasses.
(In the above, "subclasses" includes by direct and indirect subclasses.)
The distinction between checked and unchecked exceptions is that checked exceptions must be "dealt with" within the enclosing method or constructor that they occur, but unchecked exceptions need not be dealt with.
(Q: How do you know if an exception is checked or not? A: Find the javadoc for the exception's class, and look at its parent classes.)
How do you deal with a (checked) exception
From the Java language perspective, there are two ways to deal with an exception that will "satisfy" the compiler:
You can catch the exception in a try ... catch statement. For example:
public void doThings() {
try {
// do some things
if (someFlag) {
throw new IOException("cannot read something");
}
// do more things
} catch (IOException ex) {
// deal with it <<<=== HERE
}
}
In the above, we put the statement that throws the (checked) IOException in the body of the try. Then we wrote a catch clause to catch the exception. (We could catch a superclass of IOException ... but in this case that would be Exception and catching Exception is a bad idea.)
You can declare that the enclosing method or constructor throws the exception
public void doThings() throws IOException {
// do some things
if (someFlag) {
throw new IOException("cannot read something");
}
// do more things
}
In the above we have declared that doThings() throws IOException. That means that any code that calls the doThings() method has to deal with the exception. In short, we are passing the problem of dealing with the exception to the caller.
Which of these things is the correct thing to do?
It depends on the context. However, a general principle is that you should deal with exceptions at a level in the code where you are able to deal with them appropriately. And that in turn depends on what the exception handling code is going to do (at HERE). Can it recover? Can it abandon the current request? Should it halt the application?
Solving the problem
To recap. The compilation error means that:
your code has thrown a checked exception, or called some method or constructor that throws the checked exception, and
it has not dealt with the exception by catching it or by declaring it as required by the Java language.
Your solution process should be:
Understand what the exception means, and why it could be thrown.
Based on 1, decide on the correct way to deal with it.
Based on 2, make the relevant changes to your code.
Example: throwing and catching in the same method
Consider the following example from this Q&A
public class Main {
static void t() throws IllegalAccessException {
try {
throw new IllegalAccessException("demo");
} catch (IllegalAccessException e){
System.out.println(e);
}
}
public static void main(String[] args){
t();
System.out.println("hello");
}
}
If you have been following what we have said so far, you will realise that the t() will give the "unreported exception" compilation error. In this case, the mistake is that t has been declared as throws IllegalAccessException. In fact the exception does not propagate, because it has been caught within the method that threw it.
The fix in this example will be to remove the throws IllegalAccessException.
The mini-lesson here is that throws IllegalAccessException is the method saying that the caller should expect the exception to propagate. It doesn't actually mean that it will propagate. And the flip-side is that if you don't expect the exception to propagate (e.g. because it wasn't thrown, or because it was caught and not rethrown) then the method's signature shouldn't say it is thrown!
Bad practice with exceptions
There are a couple of things that you should avoid doing:
Don't catch Exception (or Throwable) as a short cut for catching a list of exceptions. If you do that, you are liable catch things that you don't expect (like an unchecked NullPointerException) and then attempt to recover when you shouldn't.
Don't declare a method as throws Exception. That forces the called to deal with (potentially) any checked exception ... which is a nightmare.
Don't squash exceptions. For example
try {
...
} catch (NullPointerException ex) {
// It never happens ... ignoring this
}
If you squash exceptions, you are liable to make the runtime errors that triggered them much harder to diagnose. You are destroying the evidence.
Note: just believing that the exception never happens (per the comment) doesn't necessarily make it a fact.
Edge case: static initializers
There some situations where dealing with checked exceptions is a problem. One particular case is checked exceptions in static initializers. For example:
private static final FileInputStream input = new FileInputStream("foo.txt");
The FileInputStream is declared as throws FileNotFoundException ... which is a checked exception. But since the above is a field declaration, the syntax of the Java language, won't let us put the declaration inside a try ... catch. And there is no appropriate (enclosing) method or constructor ... because this code is run when the class is initialized.
One solution is to use a static block; for example:
private static final FileInputStream input;
static {
FileInputStream temp = null;
try {
temp = new FileInputStream("foo.txt");
} catch (FileNotFoundException ex) {
// log the error rather than squashing it
}
input = temp; // Note that we need a single point of assignment to 'input'
}
(There are better ways to handle the above scenario in practical code, but that's not the point of this example.)
Edge case: static blocks
As noted above, you can catch exceptions in static blocks. But what we didn't mention is that you must catch checked exceptions within the block. There is no enclosing context for a static block where checked exceptions could be caught.
Edge case: lambdas
A lambda expression (typically) should not throw an unchecked exception. This is not a restriction on lambdas per se. Rather it is a consequence of the function interface that is used for the argument where you are supplying the argument. Unless the function declares a checked exception, the lambda cannot throw one. For example:
List<Path> paths = ...
try {
paths.forEach(p -> Files.delete(p));
} catch (IOException ex) {
// log it ...
}
Even though we appear to have caught IOException, the compiler will complain that:
there is an uncaught exception in the lambda, AND
the catch is catching an exception that is never thrown!
In fact, the exception needs to be caught in the lambda itself:
List<Path> paths = ...
paths.forEach(p -> {
try {
Files.delete(p);
} catch (IOException ex) {
// log it ...
}
}
);
(The astute reader will notice that the two versions behave differently in the case that a delete throws an exception ...)
More Information
The Oracle Java Tutorial:
The catch or specify requirement
... also covers checked vs unchecked exceptions.
Catching and handling exceptions
Specifying the exceptions thrown by a method

How am I supposed to let an Unchecked Exception bubble up and log?

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.

Adding 'throws' on an extended class?

I'm making a simple application with the Socket API, but have run into a small issue that I haven't found the answer for.
The application is supposed to be multi-threaded, so that the main method starts both the server and client threads.
public class UDPClientServer1 extends Thread
However, since the the Socket classes need to throw some specific exceptions, I must also do this:
public void runClient() throws SocketException, UnknownHostException, IOException
and similarly for the runServer() method.
Not that there's anything wrong with that, but is there a more elegant solution? Something along the lines of :
public class UDPClientServer1 extends Thread, throws Exception
Ideally you may want to wrap the exception that your throw, either converting it to a RuntimeException if the error is unrecoverable, or at least a more appropriate / encapsulated exception.
E.g.
public void runClient throws ClientException
{
try
{
// do something
} catch (Exception e)
{
log.error("Exception encountered in client",e);
throw new ClientException("Unrecoverable client exception encountered",e);
// or: throw new RuntimeException("Unrecoverable client exception",e);
}
}
ClientException in the above is your own exception that you would need to create. Its purpose is to encapsulate the implementation details of corresponding exceptions from any calling code.
Using a RuntimeException, however, may be more appropriate if there is no reasonable way for the calling code to respond to the exception. When throwing a RuntimeException you do not have to declare it in the method signature and calling code does not need to explicitly handle it (although it should be handled at some point).

Handle exception or throw exception in Java

Like such Java code snippet:
public void func() throws XXXException { // throw exception to outer body ------ (2)
try {
......
} catch(XXXException ex) {
// handle exception ------ (1)
}
}
In this condition, how you decide to choose (1) or (2)? Is there any principles in Java exception handling?
If the code that calls the method that throws the exception can properly deal with the exception then it should catch it. If it cannot deal with the exception then it should throw it up.
For instance, if "func" is low-level networking code it should probably throws the exception rather than catch it. The code that ultimatly catches it should display an error message to the user (or whatever else makes sense). If instead "func" is part of the GUI layer it probably would catch the exception and display an error message to the user (or whatever else makes sense).
If you can handle it you handle it. For example, if you are loading a properties file and you get a FileNotFoundException perhaps you can use some default properties. In this case you handle the exception.
If you can't handle it but you think someone else might be able to down the road then you should throw the exception. For example, perhaps you are writing a general utility for reading in property files. In this case you might rethrow the exception so that whoever is using your general utility can then go ahead and load defaults.
If you can't handle it and you don't want to introduce the complexity of throwing the exception then you should send the exception to an exception handling service that you can configure at runtime. This way when unit testing the exception handling service can take that exception and rethrow it as a runtime exception which will crash the test immediately. However, in production code the exception handling service might just log the exception and try and restart the program somehow.
You choose (1) if you want to do something about the exception (e.g. log it, extract info from it). It's also common to throw the exception in the catch block after you are done with it (i.e. throw ex;)
You choose (2) if you want the users of your method to handle it (e.g. Java's String.matches method)
In a nut shell, choose to throw exception to outer body, unless you have a specific reason to catch the exception.
There's an excellent article at the O'Reilly java site about this topic. It goes into some detail about when you should catch versus throw, as well as other stuff, like checked versus unchecked exceptions.
Exceptions represent error conditions. When an error condition occurs, some method in the call chain knows how to handle that error in the context of the application i.e. what to do - ignore, retry, abort, etc. If this is that method that knows how to handle this exception, then you handle it here. If not, you throw it so that the method one level up the call chain receives it and acts on it.
Sometimes, you may want to do both (1) and (2). You may handle the exception, do some intermediate processing and then rethrow it.
public void func() throws XXXException {
try {
......
} catch(XXXException ex) {
logger.log(ex);
throw ex;
}
}
Or you may catch one exception and throw another, for example when you want to wrap a third party exception into an application exception.
public void func() throws YYYException {
try {
......
} catch(XXXException ex) {
throw new YYYException(ex);
}
}
In both cases, this is not the method that fully handles the exception and only does some processing along the way as the exception percolates to the top.

Categories

Resources