exception handling using aspects

14
Exception handling in Java holds a very special place; a cleverly done effort not only makes the application stable and robust but also provides valuable pointers for problem areas in case things go wrong. For any application exceptions can belong to one of the following categories: Business Scenarios: There can be certain valid scenarios in an application that are correct from the programming perspective but may be an invalid business scenario. Such cases may be handled in the code through exceptions that are specific to business logic of the application. An example of one exception is a user trying to access a section in the application but does not have adequate permissions. Application Paths: These are the scenarios in the application flow that require special handling. Again these may be correct from the programming perspective but can be flow that is invalid in the application functionality. One such case may be when a website tries to contact a third party secure payment gateway and for some reason outside the application the communication is void. There may not be anything wrong with the application flow but this a scenario that may be treated as an exception. Programming Exceptions: These are the standard checked and unchecked exceptions that the applications are embellished with. Volumes have been written on what Java exceptions are and how these should look like and so on and so forth. I may not want to rephrase all that is already available in abundance. Okay, now we know the types and the categories of exceptions w.r.t. to a given application logic. A few “Best Practices” one may follow before starting with an exception handling framework: Catch an exception only if it can be handled where it is caught, do not catch the exception to log and swallow it or to re-throw it. Always present meaningful error messages to the end users and these message should be customizable Log unhandled error situations once and only once and not at all the layers Exceptions may have a unique id and each invocation may have a unique tracking-id so that the debugging is high precision. Have a powerful, extensible, yet simple strategy for exception handling at all tiers. One such implementation may be to route the exceptions as XML or any such format and then have the handlers at each tier/layer handle these accordingly.

Upload: v4vix

Post on 08-Apr-2015

90 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: Exception Handling Using Aspects

Exception handling in Java holds a very special place; a cleverly done effort not only makes the application stable and robust but also provides valuable pointers for problem areas in case things go wrong. For any application exceptions can belong to one of the following categories:

Business Scenarios: There can be certain valid scenarios in an application that are correct from the programming perspective but may be an invalid business scenario. Such cases may be handled in the code through exceptions that are specific to business logic of the application. An example of one exception is a user trying to access a section in the application but does not have adequate permissions.

Application Paths: These are the scenarios in the application flow that require special handling. Again these may be correct from the programming perspective but can be flow that is invalid in the application functionality. One such case may be when a website tries to contact a third party secure payment gateway and for some reason outside the application the communication is void. There may not be anything wrong with the application flow but this a scenario that may be treated as an exception.

Programming Exceptions: These are the standard checked and unchecked exceptions that the applications are embellished with. Volumes have been written on what Java exceptions are and how these should look like and so on and so forth. I may not want to rephrase all that is already available in abundance.

Okay, now we know the types and the categories of exceptions w.r.t. to a given application logic. A few “Best Practices” one may follow before starting with an exception handling framework:

Catch an exception only if it can be handled where it is caught, do not catch the exception to log and swallow it or to re-throw it.

Always present meaningful error messages to the end users and these message should be customizable

Log unhandled error situations once and only once and not at all the layers Exceptions may have a unique id and each invocation may have a unique tracking-id so

that the debugging is high precision. Have a powerful, extensible, yet simple strategy for exception handling at all tiers. One

such implementation may be to route the exceptions as XML or any such format and then have the handlers at each tier/layer handle these accordingly.

There are a lot of exceptions handling frameworks available, open source and proprietary and this makes the life for the applications very easy. I would cover one such implementation of an exception handling framework using Spring AOP. Before proceeding, a few ground rules that would be observed throughout the implementation

No Swollen logs: Every catch block should not contain a log statement thereby avoiding bloated and redundant log entries.

No Redundant implementations: Avoiding that scenario where same type of error has different representations, which complicates how it is handled.

No Broken encapsulation: Avoiding exceptions from other components that are declared as part of the method signature and breaks the clear division between interface and its implementation.

No Noncommittal exception declaration: Avoiding the method signature to be generalized to throw java.lang.Exception. Thereby confusing the method's error semantics.

Page 2: Exception Handling Using Aspects

No Needless Exceptions: Avoid using exceptions to indicate conditions that can reasonably be expected as part of the normal functioning of the method.

There are 3 ways in which we can implement these. Firstly, we can have an XML mapper that maps various handlers to the exception types and incorporates this mapping at the runtime. Secondly, allow a user to define specific actions for specific exception types through the configuration itself when using a default handler. Thirdly, allow a user to define specific handlers/advisors for each method of the same class. The framework also works with error codes and then allows a resource bundle based approach to fetch specific messages for various error codes. All the three approaches as above can be clubbed and combined for best effect.

Rules for the Exception Hierarchy

A Handler is introduced on the top of each layer for handling exceptions, this handler can do one of the three things , capture an exception and perform appropriate actions and pass an error code to upper layers, wrap the exception into some other higher level exception and re-throw or log and handle the exception then and there. Besides, the system does allow for enhancing the approach through defining own handlers for specific exception types.

Implemented Handlers

The idea was to have just 2 types of handlers default handler for just 2 types of exceptions; Runtime Exceptions and exceptions specific to the business/application. Keeping these in mind there can be a few flows for exception handlers, mostly a common exception handler with different flows around the exception types.

Extended Handlers

All the 3 approaches are flexible enough to accommodate customized specific handlers which can probe for exceptions at the method, class, package and application layer level. The specific configuration may be needed to be incorporated and we can customize the handling for specific scenarios.

A very simple flow for the framework is as under:

Page 3: Exception Handling Using Aspects

Framework Organization

The exception structure is as under

An AOP configuration defines pointcuts on specific classes

An AOP Aspect configuration defines the methods of the ExceptionHandler that would be invoked/ Defines the AfterThrows Advisor/Interceptor that

would be invoked

The Handler has the implemetation for tier/product/business/layer/type specific exceptions objects and sets an error code , a configurable message and the base class. The Handler can

be configured for messages and this way we can have multiple handlers per class

These Exceptions are then handled as per their nature and type

Page 4: Exception Handling Using Aspects

The Exception Hierarchy

The structure for handlers for the approaches discussed in the description is:

a) Where pointcuts are specifically defined in the configuration files and the exception types are mapped to methods of the handler. The snippet of the configuration file is as under :

Spring Configuration

Page 5: Exception Handling Using Aspects

b) In this approach the Handlers implement the interface ThrowsAdvice and define their own afterThrowing method. Here multiple things can be configured to have a fine grained handling, configure the interceptors for a bean through wildcards to handle specific methods of a bean and/or implement afterThrowing method of each exception type for the tier and have one generic handling or have a single afterThrowing method and have handling for each exception inside this method.Another way this configuration is managed is through an aroundAdvice , here the message is monitored for any exceptions through the method invoke and any exceptions can then be captured in this advice handler and nothing gets thrown.

Spring Configuration

Page 6: Exception Handling Using Aspects

The Advice Handler Hierarchy

c) This approach has a configuration file configmapper.xml has the mapping of exception types to their handlers and a default handler for all other exceptions. These mappings are loaded as a list. All Exception types implement an interface SimpleBaseException and through IOC the correct implementation is returned and utilized. As mentioned earlier in the introduction too, all the three approaches as above can be clubbed and combined for best effect.

configMapper.xml

Page 7: Exception Handling Using Aspects

The XML configuration based Exception Handling Framework

Page 8: Exception Handling Using Aspects

Spring Configuration

The interface and the implementations used as application classes

All the implementations are written to take String parameters and throw an exception corresponding that. If nothing matches a NullPointerException is thrown.

Code Samples

Page 9: Exception Handling Using Aspects

A simple java program using the recommended framework is as shown below. The console output shows how the various exceptions thrown by the example service are handled. One such example is as below where an exception (Custom DBException) that is intended to be handled at this layer/tier of the application is handled. Here the setup gives out an error code, a custom message and a stack trace.

Page 10: Exception Handling Using Aspects

Another example is when an exception meant for a higher tier/layer is thrown at this layer. The framework here captures the error code and a message and then wraps the type SevereException with BasicExcetion and throws for the upper layers to handle these.

Yet another example is when an unchecked exception (in this case NullPointer Exception) is encountered. The framework here wraps the type NullPointerException with BaseException and throws for the upper layers to handle these. However, the handler at this layer can also be configured to handle this scenario without re-throwing this too.

Page 11: Exception Handling Using Aspects

Merits of the Spring AOP based Framework

This is very simple to use and configure Runtime weaving through proxy using concept of dynamic proxy, therefore

we can handle each scenario differently. Is easily integrated with AspectJ implementations too, if needed the prowess

of aspect can be used too. Using this approach we can implement a pluggable exception handling

framework where the tiers may not be needed to be changes at all and all the association may be setup through configuration files only.

Demerits of the Spring AOP based Framework

Page 12: Exception Handling Using Aspects

This is proxy-based AOP. So we can only use method-execution point-cuts. Run time weaving may be a performance overhead(need to investigate

further on this)