Seeking for a good “error handling in java” habit I found interesting readings. I already downloaded and read many bytes of text about checked/unchecked exceptions and fault barriers. But I wanted to know how is exception handling implemented in JVMs, time to go back to basics :)
The Sun VM specification is a good reference, here is the overview section about exceptions :
In the Java programming language, throwing an exception results in an immediate nonlocal transfer of control from the point where the exception was thrown. This transfer of control may abruptly complete, one by one, multiple statements, constructor invocations, static and field initializer evaluations, and method invocations. The process continues until a catch clause is found that handles the thrown value. If no such clause can be found, the current thread exits.
In cases where a finally clause is used, the finally clause is executed during the propagation of an exception thrown from the associated try block and any associated catch block, even if no catch clause that handles the thrown exception may be found.
As implemented by the Java virtual machine, each catch or finally clause of a method is represented by an exception handler. An exception handler specifies the range of offsets into the Java virtual machine code implementing the method for which the exception handler is active, describes the type of exception that the exception handler is able to handle, and specifies the location of the code that is to handle that exception. An exception matches an exception handler if the offset of the instruction that caused the exception is in the range of offsets of the exception handler and the exception type is the same class as or a subclass of the class of exception that the exception handler handles. When an exception is thrown, the Java virtual machine searches for a matching exception handler in the current method. If a matching exception handler is found, the system branches to the exception handling code specified by the matched handler.
If no such exception handler is found in the current method, the current method invocation completes abruptly. On abrupt completion, the operand stack and local variables of the current method invocation are discarded, and its frame is popped, reinstating the frame of the invoking method. The exception is then rethrown in the context of the invoker’s frame and so on, continuing up the method invocation chain. If no suitable exception handler is found before the top of the method invocation chain is reached, the execution of the thread in which the exception was thrown is terminated.
The order in which the exception handlers of a method are searched for a match is important. Within a class file the exception handlers for each method are stored in a table. At run time, when an exception is thrown, the Java virtual machine searches the exception handlers of the current method in the order that they appear in the corresponding exception handler table in the class file, starting from the beginning of that table. Because try statements are structured, a compiler for the Java programming language can always order the entries of the exception handler table such that, for any thrown exception and any program counter value in that method, the first exception handler that matches the thrown exception corresponds to the innermost matching catch or finally clause.
Note that the Java virtual machine does not enforce nesting of or any ordering of the exception table entries of a method. The exception handling semantics of the Java programming language are implemented only through cooperation with the compiler. When class files are generated by some other means, the defined search procedure ensures that all Java virtual machines will behave consistently.
Original version contains links to more detailled material.
We already understand that exception handling is not a trivial task for the JVMs.
Reading different writers on the same subject is mostly always insightful. Here is a short excerpt from the Struts book from ObjectSource that gives a more (my?)brain-friendly description of the handler search procedure in a section titled “The cost of exception handling”:
Exceptions are expensive and should be used exceptionally. In order top understand some of the issues involved; let us look at the mechanism used by the Java Virtual Machine (JVM) to handle the exceptions.
The JVM maintains a method invocation stack containing all the methods that have been invoked by the current thread in the reverse order of invocation. In other words, the first method invoked by the thread is at the bottom of the stack and the current method is at the top. Actually it is not the actual method that is present in the stack. Instead a stack frame representing the method is added to the stack. The stack frame contains the method’s parameters, return value, local variables and JVM specific information. When the exception is thrown in a method at the top of the stack, code execution stops and the JVM takes over.
The JVM searches the current method for a catch clause for the exception thrown or one of the parent classes of the thrown exception. If one is not found, then the JVM pops the current stack frame and inspects the calling method (the next method in the stack), for the catch clause for the exception or its parents. The process continues until the bottom of the stack is reached. In summary, it requires a lot of time and effort on the part of JVM.
It’s allways good to know how a given code gets executed and how managed code is … well … managed.
I hope that this condensed read will be of any kind of help.