Welcome!

Java Authors: Walter H. Pinson, III, Maureen O'Gara, Yakov Werde, Tony Bishop, Kevin Jackson

Related Topics: Java

Java: Article

A Strategy for Aspect-Oriented Error Handling

Bringing new challenges to development

The configuration and instantiation of problem handler chains is where Prob-lo-Matic adds value. Prob-lo-Matic basically provides a factory for creating chains-of-command based on Problem classes. It exposes a static method void handleProblem(Problem aProblem) that constructs a chain based on the XML configuration file. This method then passes the specified Problem to the first link in the chain for processing. To modify the behavior of the exception handling in your application, you need only modify the Prob-lo-Matic configuration file and the changes will be reflected in your application.

To use Prob-lo-Matic you could refer to the Prob-lo-Matic classes in your application. While this is a fine solution for new or simple applications, we might want to be able to apply this framework to preexisting code and to do so in a way that doesn't disturb the integrity of the existing application. This would have been a difficult or impossible task in the past, but AOP gives us some interesting options for a clean integration of this framework.

Two AOP Approaches: Spring AOP and Bytecode Instrumentation
If you're new to AOP it may take a while to wrap your head around the concepts, especially when you see that the AOP designers have developed a whole new lexicon of AOP terms to describe the new concepts. This article doesn't purport to explain even a fraction of AOP, but we will glance over a few AOP concepts and discuss the Spring framework's implementation of a subset of AOP. Spring's implementation can be used to "weave" our error handling code into our application. We are interested in intercepting thrown exceptions, wrapping them in our Problem object, and passing them off to handlers. To this end, we can implement what's called a throws advice in Spring. This is implemented using Prob-lo-Matic as in the following example:

public class ExceptionInterceptor implements ThrowsAdvice {
  public void afterThrowing(Method m, Object[] args, Object target, Exception ex) {
   Problem problem = new RawProblem(ex);
   problem.setAttribute("method.name",m.getName());
   // set other attributes here
   Problomatic.handleProblem(problem);
  }
}

The drawback with this approach is that our target object must be a JavaBean and also configured using the Spring Framework. If this is the case, we can tell Spring to intercept all thrown exceptions and call the afterThrowing method. For more information on integrating throws advice with Spring-enabled beans, see the Spring Framework documentation on www.springframework.org/.

Alternatively, we can weave this code into our application using another technique called bytecode instrumentation. This involves inserting lines of code into Java classes with a tool after the javac compiler has compiled them. Prob-lo-Matic provides such a tool called ProblomaticWeaver and a corresponding Ant task, WeaveTask. The ProblomaticWeaver searches for all try/catch blocks in the specified classes and inserts a call to Prob-lo-Matic before any other code in the catch block (any code already present in the catch block is preserved after this call). For example, the following code fragment is written:

public class MyClass {
public void myMethod() {
Try {
   do();
} catch (Throwable t) {
   System.out.println(t.getMessage());
}
}

After compilation, the Prob-lo-Matic code is woven into MyClass.class. If this class was decompiled, it would look like this:

public class MyClass {
public void myMethod() {
Try {
   do();
} catch (Throwable t) {
  RawProblem problem = new RawProblem(t);
  Problomatic.handleProblem(problem);
   System.out.println(t.getMessage());
}
}
}

Practical Example: Retrying Database Calls
Once Prob-lo-Matic has been integrated into our code, we can use it to perform a number of useful functions when exceptions are thrown. A common requirement for reliable database access is to retry connecting to a database when a connection fails, or to switch to an alternate database if the desired database is down for some reason. Consider a set of implementations of Problem that contain context-specific callback methods on their source, as defined in an interface such as:

public interface Recoverable {
  public int getMaximumRecoveryAttempts();
  public int getRecoveryAttemptsCount();
  public void attemptedRecovery();
  public boolean canRecover();
  public void setConnection(Connection con);
  public void setConnected(boolean yesOrNo);
}

An object that implements Recoverable (see Listing 2) encapsulates the data and logic required to manage multiple attempts of some procedure. If our business objects (or DAOs) implement the Recoverable interface, we can define a DatabaseProblem that has a reference to our Recoverable instance. Our ProblemHandler implementation (see Listing 3) then uses these callback methods to instruct the Recoverable object how to recover from the problem. In addition, the state of the recovery (number of times tried, etc.) is managed by the DatabaseProblemHandler. Our Prob-lo-Matic configuration looks like this:

<problomatic-configuration>
  <define-chain problem="com.mypackage.DatabaseProblem">
  <chain-link handler="com.mypackage.DatabaseRetryHandler"
  <chain-link
  handler="com.stieglitech.problomatic.handlers.EmailNotificationHandler"/>
</define-chain>
</problomatic-configuration>

More Stories By Dan Stieglitz

Dan is an independent software consultant in New York. He specializes in designing and developing distributed applications in Java and J2EE.

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.