• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Tim Cooke
  • Campbell Ritchie
  • paul wheaton
  • Jeanne Boyarsky
  • Ron McLeod
Sheriffs:
  • Paul Clapham
  • Devaka Cooray
Saloon Keepers:
  • Tim Holloway
  • Carey Brown
  • Piet Souris
Bartenders:

suppressed exceptions

 
Ranch Hand
Posts: 145
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I can not understand what is the order of the statements to get the output.
In particular I have doubts about these two pieces of code and the respective output.




Try
suppressed:java.io.IOException: Closing






Closing - 2
suppressed:java.io.IOException: Closing - 1





I doubt that it is precisely on the output. Ok, in the second example there are two resources to be closed and is closed before b2 and then b1 but because you get that ouput?
Can you explain the operation?




EDIT: for clarity I also add two exercises of self-tests of Chapter 7 (#10 and #11) with its correct answer in order to talk about it later and clarify any doubts.

#10


Which exceptions will the code throw?
- RuntimeException c with no suppressed exception




#11


Whic exceptions will the code throw?
- IOException with suppressed RuntimeException a

 
John Lerry
Ranch Hand
Posts: 145
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I try to answer and let's see if I understand.



Try
suppressed:java.io.IOException: Closing




During the closing of the resources is throws (line 2) an exception and because does not have a catch block, and that of the main is already in some way associated with the exception throws in the main, the exception throws in the close method is added to array of exceptions suppressed.
The execution returns to the line 1, the exception is thrown and caught by the catch block, is printed Try and later prints, flowing in the array, the details of the exception suppressed to the line 2.




Closing - 2
suppressed:java.io.IOException: Closing - 1



In this case the closing of the first resource (b2) is handled normally then will be printed with the text of the exception (Closing - 2) because the exception will be caught by the catch block of the main.
I do not understand, however, how does running back in the catch block of the main after closing b1 and print the contents of the array which, rightly, will contain the exception suppressed.
 
Ranch Hand
Posts: 39
5
Spring Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

in the second example there are two resources to be closed and is closed before b2 and then b1 but because you get that ouput?
Can you explain the operation?



The close() method gets called on the resources in the reverse order in which resources are declared, to allow for the fact that resources might depend on each other.

Imagine you had:


Because BufferedReader depends on the FileReader object, it makes sense to close the BufferedReader object first, and then the FileReader object.
 
John Lerry
Ranch Hand
Posts: 145
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
ok, I understand the concept, however I do not understand the operation of those two pieces of code.
 
James Pittendreigh
Ranch Hand
Posts: 39
5
Spring Java Linux
  • Likes 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

I think it may help to state the flow of execution that is happening here with a try-with-resources block...

1. Try block executes
2. Specified resources are closed implicitly, in reverse order
3. [Optional] catch blocks are executed
4. [Optional] finally block is executed

The exception that is encountered during steps 1 and 2 become the main exception to which the suppressed exceptions are appended to. This is very important as it explains the first two examples you posted:

In the first example, the Try block executes, throws the first exception, and the "Try" Exception becomes the main exception (the one which is caught by the catch block). However the close() method of the "One" class also throws an exception which is appended to the "Try" exception as a suppressed exception. When we get to the catch block it prints the main "Try" exception and then iterates around the one suppressed exception, printing it out.

In the second example the resources are just closed in the opposite order to the order they were declared in, as such this is the order they were output.

 
John Lerry
Ranch Hand
Posts: 145
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Then an exception is said suppressed at the time when it can not be handled by a catch block. Is it correct?
The first example is clear to me and also the second it is, in particular, the exception throw by the closing of b2 is not suppressed because it is managed by the catch block of the main.

Waiting to see if the consideration just made is correct I wanted to analyze the exercises #10 and #11 inserted at the beginning.

#10
The exception in run() method is handled by the catch block and, according to my reasoning, the exception thrown in close() should be deleted.
That said I would have given an answer so that the exception that will be thrown is the RuntimeException c (because thrown by the catch block) and also would be RuntimeException a as an suppressed exception.
But the answer is not this.

#11
The exception of the try block is handled by the catch block and is rethrow while that of the close() method is suppressed. In fact, the result seems to correspond to this reasoning.
 
James Pittendreigh
Ranch Hand
Posts: 39
5
Spring Java Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

John Lerry wrote:Then an exception is said suppressed at the time when it can not be handled by a catch block. Is it correct?


No. The first exception that occurs during the execution of a try block or during the implicit invocation of the close() method on the declared resources becomes the main exception that will be thrown (and optionally caught by a catch block). Any subsequent exceptions are added to the main exception as suppressed exceptions.

John Lerry wrote:The first example is clear to me and also the second it is, in particular, the exception throw by the closing of b2 is not suppressed because it is managed by the catch block of the main.


The exception thrown by closing b2 becomes the main exception (and is therefore not the suppressed exception).
The exception thrown by closing b1 is added to the main exception as a suppressed exception.
 
James Pittendreigh
Ranch Hand
Posts: 39
5
Spring Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Let's run through #10: Which exceptions will the code throw?


1. Animals.main() executes and invokes Animals.run();

2. In run(), the try block throws a IOException - this becomes the main exception.

3. Lamb.close() is invoked. This throws a Runtime Exception. As we already have a main exception, the RuntimeException becomes the suppressed exception.

4. Now the Try block has been executed and the resources are closed, if we have a main exception (we do!) it is thrown (It's the IOException remember!)

5. The catch block catches the IOException.

6. THE IMPORTANT BIT: NOTHING IS DONE WITH THE IOEXCEPTION!

7. A new Exception is thrown.


As such - only the RuntimeException exception is thrown by the run() method.

This is one of many trick questions. Get used to it. There are two clues here that this is a trap:
1) If you follow it through as I have above - you will see which exceptions are being thrown/caught when/where.

2) run() does not declare that it throws any checked Exceptions. If it threw an Exception or an IOException then it would have to have declare it, otherwise it would not compile.


I kinda think that the question is a little ambiguous, maybe it should be: "Which exceptions will the Animals.run() method throw?"
 
John Lerry
Ranch Hand
Posts: 145
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

James Pittendreigh wrote:
I kinda think that the question is a little ambiguous, maybe it should be: "Which exceptions will the Animals.run() method throw?"



Then should I not consider the exception throws in the close() method (exception suppressed)?
I ask this because it seems that that exception in the exercise #11 is considered and it is present in the result as an exception suppressed.
 
James Pittendreigh
Ranch Hand
Posts: 39
5
Spring Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

John Lerry wrote:

James Pittendreigh wrote:
I kinda think that the question is a little ambiguous, maybe it should be: "Which exceptions will the Animals.run() method throw?"



Then should I not consider the exception throws in the close() method (exception suppressed)?



Correct. You could think of the question as: "If you compiled and ran that section of code, which exception(s) would be thrown", and only the RuntimeException C would be thrown. As I say, I think it is a little ambiguous, but I also found questions on my real 6 exam ambiguous.

John Lerry wrote:I ask this because it seems that that exception in the exercise #11 is considered and it is present in the result as an exception suppressed.



I'm sorry I don't understand what you mean here.

In #11, it tests two bits of knowledge: try-with-resources, and rethrowing Exceptions with more inclusive type checking.

The Try block throws the IOException and becomes the main exception (as it is the first), then when the resources are closed implicitly - the RuntimeException is added as a Suppressed exception to the main (IOException) Exception. This is caught in the Exception block and then thrown again.

One thing again to note is that this time run() throws an IOException (a good clue that if you have followed as above you're on the right track). But the Exception thrown in the catch block is of type Exception when it is thrown - which of course is fine in Java 7+ because it can be inferred that the Exception thrown is the one caught from the code invoked from the try block, and thus can be rethrown (this would be a compile fail in Java 6).
 
John Lerry
Ranch Hand
Posts: 145
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

James Pittendreigh wrote:
Correct. You could think of the question as: "If you compiled and ran that section of code, which exception(s) would be thrown", and only the RuntimeException C would be thrown. As I say, I think it is a little ambiguous, but I also found questions on my real 6 exam ambiguous.



ok, but then the exercise # 11

John Lerry wrote:
#11


Which exceptions will the code throw?
- IOException with suppressed RuntimeException a




should give as ouput "IOException with no suppressed exception" but that is not what the correct ouput for the book.
 
James Pittendreigh
Ranch Hand
Posts: 39
5
Spring Java Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

John Lerry wrote:
ok, but then the exercise # 11

...
should give as ouput "IOException with no suppressed exception" but that is not what the correct ouput for the book.



No, I'm afraid not, as I explained earlier (in reference to #11)...

James Pittendreigh wrote: The Try block throws the IOException and becomes the main exception (as it is the first), then when the resources are closed implicitly - the RuntimeException is added as a Suppressed exception to the main (IOException) Exception. This is caught in the Exception block and then thrown again.



#10 is different because it catches the exception and does nothing with it, and then throws a newly instantiated exception. As such only the new exception is thrown by run.

#11 Catches the IOException, and then throws it again. It has a suppressed RuntimeException attached to it.

Without sounding rude, I think you could probably do with going over chapter 7 again. Also the Java tutorials on this subject are very good: https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html.
 
John Lerry
Ranch Hand
Posts: 145
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think I understand the operation of exceptions suppressed, but I would doubt on an quiz on the book cd (K&B7).
Given this code:


The result, according to the solution, is:


- catch
- An ArrayIndexOutOfBoundsException is thrown



but I would have said:


- finally
- An ArrayIndexOutOfBoundsException is thrown



I say this because the exception "try" is considered top level exception, then the resource is closed and the exception "catch" is thrown and it is marked as suppressed.
Returning to the try block of method() the finally block is runned and therefore no longer be considered the previous exceptions but the exception "finally" is thrown.
Where my reasoning is wrong?
 
James Pittendreigh
Ranch Hand
Posts: 39
5
Spring Java Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi John, the answer looks wrong for that one. I don't have the CD/Book with me to verify, but the output from that code will be:

- finally
- An ArrayIndexOutOfBoundsException is thrown


The only way it would be:
- catch
- An ArrayIndexOutOfBoundsException is thrown


is if there was no Exception("try") thrown in the try block, and there was no finally.

You should add this to the Errata thread, referenceing the question in hand.
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
reply
    Bookmark Topic Watch Topic
  • New Topic