Link Details

Link 56034 thumbnail
User 131196 avatar

By jj83777
via tutorials.jenkov.com
Published: Dec 07 2007 / 05:07

This new article in the Java Exception Handling trail explains how exception handling code can be encapsulated inside a template, which can be reused again and again throughout your application. This means less to worry about, less bugs, and less code to write afterwards. Frameworks like Spring use Templates all the time. Learn to use them effectively yourself.
  • 19
  • 3
  • 3074
  • 1122

Comments

Add your comment
User 241464 avatar

Dmitriy Setrakyan replied ago:

-1 votes Vote down Vote up Reply

In the "correct" exception handling that author describes, he throws exceptions out of finally block and states that no exceptions are lost. This is absolutely wrong, as if code within finally block throws an exception, then any exception that occurred within try block (for example NullPointerException) will be lost without a trail.

User 261423 avatar

jjenkov replied ago:

2 votes Vote down Vote up Reply

Whether the exception handling code in the examples is 100% correct or not, is irrelevant. The point of the article is to show that exception handling code can be encapsulated in exception handling templates, which can be reused throughout your applications. As long as YOUR exception handling templates are implemented correctly, this article has merit. The article shows you how to implement templates, not how to "correctly handle IOExceptions". Those are just examples.

User 261423 avatar

jjenkov replied ago:

1 votes Vote down Vote up Reply

You need to re-read the code, Dmitriy. No Exceptions are lost.

Notice that IF an exception was thrown within the try-block, that exception is *nested* inside the exception thrown from the finally block. As such, it is not lost. The exception thrown inside the try-block can be retrieved from the exception thrown inside the finally block. Both exceptions are preserved.

Look at this code taken from the finally block of the code examples:

if(processException != null){
throw new MyException(processException, e,
"Error processing and closing InputStream for file " +
fileName);
} else {
throw new MyException(e,
"Error closing InputStream for file " +
fileName;
}

Notice the processingException, which is the exception thrown inside the try-block, if any is thrown. This exception is preserved in the catch-block, and nested along with the close exception, inside the MyException, if a close-exception occurs. If not, the processingException is just nested inside a MyException by itself.

,

User 202757 avatar

vvs replied ago:

0 votes Vote down Vote up Reply

Useful stuff indeed.

User 236137 avatar

dzonelurker replied ago:

0 votes Vote down Vote up Reply

Altogether a useful article. Some aspects could be improved:
1. "no exceptions are lost" mans "no IOException is lost".
2. The pattern used obviously is 'Command' rather than 'Template Method'.
3. The code is unnecessarily verbose, e.g. MyException is throws 3 times in each solution.
4. should be: InputStreamProcessingTemplate.process(new InputStreamProcessor("someFile.txt"));

User 261423 avatar

jjenkov replied ago:

0 votes Vote down Vote up Reply

Answers:

1) The article says loud and clear, that only IOException are not lost, and that the example template does not even catch RuntimeException's. However, it should not require much imagination to change the templates to fit your particular situation, be it exception handling for streams, ResultSet's, thread locks etc.

2) It is actually Rod Johnson and Spring that calls this mechanism a "template". They use it for their JDBC templates that lets you plugin
a record processing implementation into their result set iterating template.

The template method pattern is used to provide a user with "hooks" into an algorithm through which that algorithm can be customized. This is what the exception handling templates in the example does. Especially the first examples that use inheritance from an abstract base class.

The fact that the examples change into a static method that takes the "hook" as some implementation of an interface, doesn't make the pattern any less a template method. You may argue that the implementation plugged in is a command, but then the pattern used is a template method with a command as hook. But once you start down the "determine-correct-design-pattern"-lane, you might as well argue that the implementation plugged into the template is a Strategy instead of a Command. However, what is interesting in the given examples is not what is plugged into the template (Command / Strategy), but rather what is wrapped around it - the template mechanism itself.

Interestingly Kent Beck and Erich Gamma wrote in their original cookbook, that when the concentration of design patterns in, or around, a component rise, that is ususally a good sign. A sign of flexible design. Therefore, the fact that you can label the input processing implementation a Command / Strategy, and the exception handling implementation a template method, could be seen as a sign of a healthy mechanism alltogether.

3) You might be able to shorten the exception handling code. But not by much. The reason the MyException is thrown 3 times in each solution is, that different information is encapsulated in it for each throw. One encapsulates a processingException, one encapsulates a closeException, and one encapsulates both.

Yes, using setter methods on MyException might have shortened the code.
But, whether the exception handling code is 10 or 20 lines isn't really that important. What matters is, that you only need to implement the template once or twice in minor variations.

4) No, it should NOT be InputStreamProcessingTemplate.process(new InputStreamProcessor("someFile.txt"));
The template opens the file input stream, and therefore the template needs to know the file name. Not the InputStreamProcessor, which only knows about input streams. In that regard, the code in the article is correct.
If any changes should be made, it should be to pass an InputStream into the .process(...) method instead of a file name.

Add your comment


Html tags not supported. Reply is editable for 5 minutes. Use [code lang="java|ruby|sql|css|xml"][/code] to post code snippets.