Exception Jargon

  • Thread starter getsanjay.sharma
  • Start date
G

getsanjay.sharma

Hello to all programmers out there. I have done a bit of fiddling with
exceptions I have come to some conclusions, which I would like to get
evaluated.

public class Test
{
public static void main(String[] args)
{
try
{
System.out.println(1/0);
}
catch(Exception e)
{
try
{
System.out.println("In catch");
throw new NullPointerException();
}
catch(Exception ee)
{
System.out.println("I have really caught the
exception");
}
}
finally
{
System.out.println("This is finally");
}
System.out.println("After finally");
}
}

``Now my understanding is this. The first line causes an Arithmetic
Exception(divide by zero). This exception is pushed on to the current
stack frame of the executing method. The C runtime of the JVM now
searches for the corresponding catch block and finds one. Hence the
exception just pushed is popped off the frame and "IN catch" is
printed. The next line again throws an exception which is again
pushed. The same procedure is repeated and "I have really caught the
exception" is printed. Then in the end, the finally block is executed
which prints "This is finally" and since there are no exceptions
pending in the stack frame, the control continues with the method and
"After finally is printed".``

Now consider this snippet:

public class Test
{
public static void main(String[] args)
{
try
{
System.out.println(1/0);
}
catch(Exception e)
{
System.out.println("In catch");
throw new NullPointerException();
}
finally
{
System.out.println("This is finally");
}
System.out.println("After finally");
}
}

``Here the same thing is repeated except for the fact that the stack
frame still has an exception pending and so after printing "This is
finally" the control returns to the calling method with the exception
still in store.

Its kind of funny why the "After finally" is not printed. Maybe
because the exception still remains on the stack frame and it is
seeking for someone to handle or for the exception to get propagated
to the main method and let the program die.``

Please be picky in evaluating my excerpt by pointing to the smallest
error. Any links to related articles would be helpful.

Thanks and regards,
S T S
 
Z

znôrt

wrote:
Hello to all programmers out there.
hi

Its kind of funny why the "After finally" is not printed.
Maybe because the exception still remains on the stack

Why funny? It just makes sense. The last throw isn't in a catched scope,
because it is not in a try block, so it throws back up to the caller. That is
exactly what makes exception mechanism useful, and by the way it's the
way to deal with errors encountered in ... error handling code.

I believe you should look at it more abstract. It isn't really that complicated.
What's funny is saying "the C runtime of the JVM" and I think it illustrates
well this obfuscation. It is in fact C code (methinks!) but that should be of no
concern. It's just the JVM. Forget about stack frames, those are the trees
that won't let you see the forrest. Focus on the concept of exceptions
instead, it's pretty straightforward.

What you might find a bit weird is that "This is finally" gets printed. Well,
code in "finally" is guaranteed to be executed if the catch block is evaluated.
Remember it is part of the exception handling, not "top level" function body
code. Thus the ever polite "C runtime JVM" manages to execute it just prior
to the exceptional function exit. Granted, it looks a bit like a stunt :D
However, how it does it (and with how many stackframes) shouldn't bother
you as a Java coder. Of course, it can be an issue for general discussion.
Sorry but my knowledge about JVM internals is too limited for that. If this is
your question, I'm pretty sure someone here can explain.
 
P

Patricia Shanahan

Hello to all programmers out there. I have done a bit of fiddling with
exceptions I have come to some conclusions, which I would like to get
evaluated.

public class Test
{
public static void main(String[] args)
{
try
{
System.out.println(1/0);
}
catch(Exception e)
{
try
{
System.out.println("In catch");
throw new NullPointerException();
}
catch(Exception ee)
{
System.out.println("I have really caught the
exception");
}
}
finally
{
System.out.println("This is finally");
}
System.out.println("After finally");
}
}

``Now my understanding is this. The first line causes an Arithmetic
Exception(divide by zero). This exception is pushed on to the current
stack frame of the executing method. The C runtime of the JVM now
searches for the corresponding catch block and finds one. Hence the
exception just pushed is popped off the frame and "IN catch" is
printed. The next line again throws an exception which is again
pushed. The same procedure is repeated and "I have really caught the
exception" is printed. Then in the end, the finally block is executed
which prints "This is finally" and since there are no exceptions
pending in the stack frame, the control continues with the method and
"After finally is printed".``

This paragraph embodies models of the JVM implementation that may, or
may not, be true. For example, although as far as I know all existing
JVMs are written in C, there is nothing in the specifications that
requires that. Maybe exceptions are pushed on some stack, but again they
could be in some other form of thread-local memory.

I think you would do better to focus on a model of Java language
behavior. Unless you know a better one, I strongly recommend using the
model in the JLS,
http://java.sun.com/docs/books/jls/third_edition/html/expressions.html

In those terms, evaluation of 1/0 completes abruptly due to an
ArithmeticException. That causes abrupt completion of the println call
and the try block. Abrupt completion of the try block due to an
exception for which there is a catch block causes execution of the catch
block.

The outer catch block contains a try-catch statement whose try block
completes abruptly due to throw of a NullPointerException. There is a
catch block for it, so the inner catch block executes and completes
normally, causing normal completion of the try-catch and the outer catch
block.

http://java.sun.com/docs/books/jls/third_edition/html/statements.html#14.20.2
gives the rules for this situation. The try block of the
try-catch-finally completed abruptly due to an exception, but the catch
block completed normally. The finally block completes normally, so the
try-catch-finally also completes normally, resulting in execution of the
following statement.
Now consider this snippet:

public class Test
{
public static void main(String[] args)
{
try
{
System.out.println(1/0);
}
catch(Exception e)
{
System.out.println("In catch");
throw new NullPointerException();
}
finally
{
System.out.println("This is finally");
}
System.out.println("After finally");
}
}

``Here the same thing is repeated except for the fact that the stack
frame still has an exception pending and so after printing "This is
finally" the control returns to the calling method with the exception
still in store.

Its kind of funny why the "After finally" is not printed. Maybe
because the exception still remains on the stack frame and it is
seeking for someone to handle or for the exception to get propagated
to the main method and let the program die.``

There is nothing strange about it if you use the JLS model. The try
block completes abruptly as before. The catch block also completes
abruptly, but the finally block completes normally. In that case, the
try statement completes abruptly for the same reason as the catch block,
the NullPointerException. Abrupt completion of a statement that is not
in a try statement cases abrupt completion of the method body without
executing any more statements.

This behavior allows a catch block to substitute a new exception without
interfering with the finally clause. The finally clause can force abrupt
completion due to a return or throw, or leave the completion reason
alone by itself completing normally.

Patricia
 
J

Joshua Cranmer

What you might find a bit weird is that "This is finally" gets printed.
Well, code in "finally" is guaranteed to be executed if the catch block
is evaluated. Remember it is part of the exception handling, not "top
level" function body code. Thus the ever polite "C runtime JVM" manages
to execute it just prior to the exceptional function exit. Granted, it
looks a bit like a stunt :D However, how it does it (and with how many
stackframes) shouldn't bother you as a Java coder. Of course, it can be
an issue for general discussion. Sorry but my knowledge about JVM
internals is too limited for that. If this is your question, I'm pretty
sure someone here can explain.

Before Java 1.5, finally is encoded by using a jump-to-subroutine/return-
from-subroutine call (equivalent to assembly's call/ret instructions)
from every possible exit point. From Java 1.5 and onwards, it is encoded
by literally inlining the finally code at every exit point. The reason is
that the jsr/ret instructions cannot be properly verified in the stricter
bytecode validation introduced in Java 6's machine code (why it started
from 1.5, I don't know...)
 
G

getsanjay.sharma

Forget about stack frames, those are the trees
that won't let you see the forrest. Focus on the concept of exceptions
instead, it's pretty straightforward.
Thanks for your concern but I do know a bit about Exceptions and
wanted to know the nitty gritty details about it, and what kind of
effect it has on the program execution and the low level aspects.
Still thanks for you help. :)

This paragraph embodies models of the JVM implementation that may, or
may not, be true. For example, although as far as I know all existing
JVMs are written in C, there is nothing in the specifications that
requires that. Maybe exceptions are pushed on some stack, but again they
could be in some other form of thread-local memory.

I think you would do better to focus on a model of Java language
behavior. Unless you know a better one, I strongly recommend using the
model in the JLS,http://java.sun.com/docs/books/jls/third_edition/html/expressions.html

In those terms, evaluation of 1/0 completes abruptly due to an
ArithmeticException. That causes abrupt completion of the println call
and the try block. Abrupt completion of the try block due to an
exception for which there is a catch block causes execution of the catch
block.

The outer catch block contains a try-catch statement whose try block
completes abruptly due to throw of a NullPointerException. There is a
catch block for it, so the inner catch block executes and completes
normally, causing normal completion of the try-catch and the outer catch
block.

http://java.sun.com/docs/books/jls/third_edition/html/statements.html...
gives the rules for this situation. The try block of the
try-catch-finally completed abruptly due to an exception, but the catch
block completed normally. The finally block completes normally, so the
try-catch-finally also completes normally, resulting in execution of the
following statement.

There is nothing strange about it if you use the JLS model. The try
block completes abruptly as before. The catch block also completes
abruptly, but the finally block completes normally. In that case, the
try statement completes abruptly for the same reason as the catch block,
the NullPointerException. Abrupt completion of a statement that is not
in a try statement cases abrupt completion of the method body without
executing any more statements.

This behavior allows a catch block to substitute a new exception without
interfering with the finally clause. The finally clause can force abrupt
completion due to a return or throw, or leave the completion reason
alone by itself completing normally.
Thanks for the wonderful explanation Patricia. I do understand that
its based on the JLS on how the language behavior is handled by the
JVM, but I was looking for an explanation in low level terms (stack
frames etc.) or the way the OS handles exceptions. I know maybe I am
asking too much or being foolish here, but I think I need some good
tutorials on how things work under the hood rather than
specifications.

One question though..

public class Bitwise
{
public static void so()
{
try
{
double a = 123;
double b = 123;
if(a == 123.0)
System.out.println("Same");

System.out.println(1/0);
}
catch(Exception e)
{
System.out.println("In catch");
throw new NullPointerException();

}
finally
{
System.out.println("This is finally");
return;
}

}
public static void main(String[] args)
{
so();
}
}

In the above snippet, no exception is raised. Is this because the
return statement in the finally block makes all the exceptions in the
current scope of the method disappear? Or does it mean that the
exception is ignored when the finally block contains the return
statement.

Thanks and regards,
S T S
 
P

Patricia Shanahan

Thanks for the wonderful explanation Patricia. I do understand that
its based on the JLS on how the language behavior is handled by the
JVM, but I was looking for an explanation in low level terms (stack
frames etc.) or the way the OS handles exceptions. I know maybe I am
asking too much or being foolish here, but I think I need some good
tutorials on how things work under the hood rather than
specifications.

I don't think there is one lower level implementation that is
necessarily used in the JVM. If you want to know how a particular JVM
does it, you need source code access to that JVM.

You can go down one level by studying the Java Virtual Machine
Specification, http://java.sun.com/docs/books/jvms/
One question though..

public class Bitwise
{
public static void so()
{
try
{
double a = 123;
double b = 123;
if(a == 123.0)
System.out.println("Same");

System.out.println(1/0);
}
catch(Exception e)
{
System.out.println("In catch");
throw new NullPointerException();

}
finally
{
System.out.println("This is finally");
return;
}

}
public static void main(String[] args)
{
so();
}
}

In the above snippet, no exception is raised. Is this because the
return statement in the finally block makes all the exceptions in the
current scope of the method disappear? Or does it mean that the
exception is ignored when the finally block contains the return
statement.

The return causes the finally block to complete abruptly, so the
try-catch-finally completes abruptly for the same reason. I know you say
you don't need specifications, but the spec section I pointed out would
have told you exactly what to expect.

Patricia
 
G

getsanjay.sharma

(e-mail address removed) wrote:

...
Thanks for the wonderful explanation Patricia. I do understand that
its based on the JLS on how the language behavior is handled by the
JVM, but I was looking for an explanation in low level terms (stack
frames etc.) or the way the OS handles exceptions. I know maybe I am
asking too much or being foolish here, but I think I need some good
tutorials on how things work under the hood rather than
specifications.

I don't think there is one lower level implementation that is
necessarily used in the JVM. If you want to know how a particular JVM
does it, you need source code access to that JVM.

You can go down one level by studying the Java Virtual Machine
Specification,http://java.sun.com/docs/books/jvms/




One question though..
public class Bitwise
{
public static void so()
{
try
{
double a = 123;
double b = 123;
if(a == 123.0)
System.out.println("Same");
System.out.println(1/0);
}
catch(Exception e)
{
System.out.println("In catch");
throw new NullPointerException();
}
finally
{
System.out.println("This is finally");
return;
}
}
public static void main(String[] args)
{
so();
}
}
In the above snippet, no exception is raised. Is this because the
return statement in the finally block makes all the exceptions in the
current scope of the method disappear? Or does it mean that the
exception is ignored when the finally block contains the return
statement.

The return causes the finally block to complete abruptly, so the
try-catch-finally completes abruptly for the same reason. I know you say
you don't need specifications, but the spec section I pointed out would
have told you exactly what to expect.

Patricia

Thanks a lot Patricia for the links and the explanations. I would get
back to this thread in case of any exception queries.

Thanks and regards,
S T S
 
Z

znôrt

Joshua said:
Before Java 1.5, finally is encoded by using a
jump-to-subroutine/return- from-subroutine call (equivalent
to assembly's call/ret instructions) from every possible
exit point. From Java 1.5 and onwards, it is encoded by
literally inlining the finally code at every exit point.
The reason is that the jsr/ret instructions cannot be
properly verified in the stricter bytecode validation
introduced in Java 6's machine code (why it started from
1.5, I don't know...)

Thank you for this information, interesting. Now I'll have to go learn about
bytecode validation! See what you have done? I was so happy in my abstract
conceptual world ... :O)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,225
Members
46,815
Latest member
treekmostly22

Latest Threads

Top